- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在解决加州理工学院机器学习类(class) (http://work.caltech.edu/homework/hw1.pdf) 的家庭作业 1。要解决问题 7-10,我们需要实现 PLA。这是我在 python 中的实现:
import sys,math,random
w=[] # stores the weights
data=[] # stores the vector X(x1,x2,...)
output=[] # stores the output(y)
# returns 1 if dot product is more than 0
def sign_dot_product(x):
global w
dot=sum([w[i]*x[i] for i in xrange(len(w))])
if(dot>0):
return 1
else :
return -1
# checks if a point is misclassified
def is_misclassified(rand_p):
return (True if sign_dot_product(data[rand_p])!=output[rand_p] else False)
# loads data in the following format:
# x1 x2 ... y
# In the present case for d=2
# x1 x2 y
def load_data():
f=open("data.dat","r")
global w
for line in f:
data_tmp=([1]+[float(x) for x in line.split(" ")])
data.append(data_tmp[0:-1])
output.append(data_tmp[-1])
def train():
global w
w=[ random.uniform(-1,1) for i in xrange(len(data[0]))] # initializes w with random weights
iter=1
while True:
rand_p=random.randint(0,len(output)-1) # randomly picks a point
check=[0]*len(output) # check is a list. The ith location is 1 if the ith point is correctly classified
while not is_misclassified(rand_p):
check[rand_p]=1
rand_p=random.randint(0,len(output)-1)
if sum(check)==len(output):
print "All points successfully satisfied in ",iter-1," iterations"
print iter-1,w,data[rand_p]
return iter-1
sign=output[rand_p]
w=[w[i]+sign*data[rand_p][i] for i in xrange(len(w))] # changing weights
if iter>1000000:
print "greater than 1000"
print w
return 10000000
iter+=1
load_data()
def simulate():
#tot_iter=train()
tot_iter=sum([train() for x in xrange(100)])
print float(tot_iter)/100
simulate()
根据问题 7 的答案,当训练集大小时,感知器需要大约 15 次迭代
才能收敛,但我的实现平均需要 50000 次迭代
。训练数据是随机生成的,但我正在为简单的线条生成数据,例如 x=4、y=2、..等。这是我得到错误答案的原因还是有其他问题。我的训练数据样本(可使用 y=2 分离):
1 2.1 1
231 100 1
-232 1.9 -1
23 232 1
12 -23 -1
10000 1.9 -1
-1000 2.4 1
100 -100 -1
45 73 1
-34 1.5 -1
格式为x1 x2 output(y)
最佳答案
很明显,您在学习 Python 和分类算法方面做得很好。
但是,由于您的代码在文体上有些低效,因此很难为您提供帮助,并且有可能部分问题是您与教授之间的沟通不畅。
例如,教授希望您在“在线模式”或“离线模式”下使用 Perceptron?在“在线模式”中,您应该按顺序移动通过数据点,您不应该重新访问任何点。根据作业的猜想,它应该只需要 15 次迭代才能收敛,我很好奇这是否意味着前 15 个数据点按顺序排列会导致分类器线性分离您的数据集。
通过替换随机抽样,您可能会花费更长的时间(尽管根据数据样本的分布和大小,这不太可能发生,因为您大致预计任何 15 个点都可以做大约以及前 15 个)。
另一个问题是,在您检测到一个正确分类的点之后(当 not is_misclassified
评估为 True
的情况)如果您随后看到一个新的随机点 被错误分类,然后您的代码将进入外部 while
循环的较大部分,然后返回顶部,它将覆盖 check
全为 0 的向量。
这意味着您的代码检测到它已正确分类所有点的唯一方法是它评估它们的特定随机序列(在内部 while
循环中)恰好是一个字符串所有 1 的神奇能力除外,在任何特定的 0 上,在通过数组的情况下,它都能正确分类。
我不能完全形式化为什么我认为这会使程序花费更长的时间,但看起来你的代码需要一种更严格的收敛形式,它必须在一个整体上同时学习所有内容在已经更新了一堆之后,在训练阶段后期通过了。
检查我的直觉是否糟糕的一种简单方法是将行 check=[0]*len(output)
移到 while 循环
之外全部放在一起,只初始化一次。
一些使代码更易于管理的一般建议:
不要使用全局变量。相反,让您的函数加载和准备数据返回内容。
有几个地方可以说,比如
返回(如果 sign_dot_product(data[rand_p]) 为真!=output[rand_p] 否则为假)
这种事情可以简化为
返回 sign_dot_product(data[rand_p]) != output[rand_p]
哪个更容易阅读,并以更直接的方式传达您要检查的标准。
我怀疑效率是否起着重要作用,因为这似乎是一种教学练习,但有许多方法可以重构您对列表理解的使用,这可能是有益的。如果可能,只需使用具有原生数组类型的 NumPy
。目睹其中一些操作如何必须用 list
操作来表达是令人遗憾的。即使您的教授不希望您使用 NumPy
来实现,因为她或他正在尝试教您纯粹的基础知识,我也会说忽略它们并去学习 NumPy
。与使用 native 数据类型进行非设计用途(数组计算)相比,它对您在 Python 中进行此类操作的工作、实习和实践技能的帮助要大得多。
关于python - 感知器学习算法需要大量迭代才能收敛?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23942112/
晚安,我正在与一些合作伙伴使用 javaFx 制作一个应用程序;我们的想法是它将在 Windows 和 Linux 中使用。我们进行了一些测试,发现应用程序在两种操作系统中的显示有所不同。 我们正在使
我有一项服务,可通过 CreateProcessAsUser 将可执行文件启动到用户 session 中,并在 STARTUPINFO 参数中指定桌面。它运行良好。 我的可执行文件没有显示出来,也没有
当每个文件写入集群时,HDFS 会创建一个复制管道。假设有两个 Rack 1 和 5。根据 Rack 感知,第一个 block 将被保存到 Rack 1,其他两个复制 block 将被插入 Rack
我正在做一个 Django 项目,我对时区感到困惑。 我有一个事件对象,它有 publish_start 和 publish_end 日期。 控制台输出示例; campaingObject.publi
我在下面有一个函数,它通过将字体 (.ttf) 复制到 Windows 字体文件夹然后触发 WM_FONTCHANGE 消息将其安装到 Windows 中。但是,该字体不会立即在 Windows 资源
是否有类似 grep 的 Unix/Linux 命令行工具可以理解由 log4j 或 logback 打印的日志文件中的 Java 堆栈跟踪?该工具应该理解堆栈跟踪由多行组成。 典型的用例是在查看存储
每次我在我的 SCM 中看到诸如导入或方法签名更改(例如变量的重命名)之类的冲突时,我想知道是否有类似语言感知的 diff/merge 方法可以处理更烦人的小更改发生在共享项目上。有什么东西可以在 U
我使用 astyanax 连接池定义如下: ipSeeds = "LOAD_BALANCER_HOST:9160"; conPool.setSeeds(ipSeeds) .setDiscoveryTy
据我所知,OCaml 中的字符串只是简单的字节序列。他们没有编码的概念。 这对于大多数用途来说都很好。但是,标准库的某些部分对以单字节字符集编码的字符串做出了假设,例如 printf 的对齐功能: #
据我所知,OCaml 中的字符串只是简单的字节序列。他们没有编码的概念。 这对于大多数用途来说都很好。但是,标准库的某些部分对以单字节字符集编码的字符串做出了假设,例如 printf 的对齐功能: #
我正在使用 this enhanced version of WebClient登录网站: public class CookieAwareWebClient : WebClient {
我正在尝试将 Awareness API 集成到一个新项目中,但我遇到了一条错误消息:ACL_ACCESS_DENIED 状态代码:7503。 我也在其他项目中集成了 Awareness API,但上
有什么方法可以定义一个 spring bean,当 session 中的数据发生变化时,它会得到通知? 如果可能的话,我还想知道纯 Java 解决方案。我想要的只是当我在 httpsession 中添
有没有方便有效的方式以 NUMA 感知方式使用 cpp 标准容器 API? 我想在 cpp 环境中执行 OpenMP 并行稀疏矩阵 vector 乘法。要分配和初始化与 NUMA 域有关的 vecto
我正在创建一个程序,它使用 SetWindowPos() 从另一个进程移动/调整窗口大小。我自己的程序是 PROCESS_PER_MONITOR_DPI_AWARE。其他程序可以是 PROCESS_D
我一直在研究许多 JDBC 连接池,但我有一个特定的要求,即池需要是 JTA 感知的,这给我留下了 Apache DBCP 和 OW2 XAPool 的简短列表。我查看的其他池(c3p0、Proxoo
我有一个 php 脚本,可以在服务器上发出一系列请求。第一个请求将是登录请求。 问题是 file_get_contents 似乎每次都创建一个新 session ,那么我怎样才能让它感知 sessio
我有一个整数,表示 unix 纪元之后的微秒数。 (格林威治标准时间) 如何使用 astype 将 1349863207154117 转换为 pandas.Timestamp("2012-10-10T
我有一个 Web 服务,我正在尝试将变量 Autowiring 到其中。这是类(class): package com.xetius.isales.pr7.service; import java.u
再会! 我已经在 WPF 应用程序上工作了一段时间(作为一种学习体验,哦,天哪,这是一种学习体验),它终于可以发布了。发布意味着将其安装在我的 HTPC 上,用于浏览我的电影收藏。 我在运行 1920
我是一名优秀的程序员,十分优秀!