Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 感知器学习算法需要大量迭代才能收敛?_Python_Python 2.7_Machine Learning_Perceptron - Fatal编程技术网

Python 感知器学习算法需要大量迭代才能收敛?

Python 感知器学习算法需要大量迭代才能收敛?,python,python-2.7,machine-learning,perceptron,Python,Python 2.7,Machine Learning,Perceptron,我正在解决加州理工学院机器学习课程()的家庭作业-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_produ

我正在解决加州理工学院机器学习课程()的家庭作业-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可分离):


它的格式是
x1x2输出(y)

很明显,您在学习Python和分类算法方面做得很好

然而,由于您的代码在风格上存在一些低效之处,因此很难为您提供帮助,这就造成了问题的一部分可能是您与教授之间的错误沟通

例如,教授是否希望您在“在线模式”或“离线模式”下使用感知器?在“在线模式”中,您应按顺序移动数据点,并且不应重新访问任何点。根据任务的推测,它应该只需要15次迭代就可以收敛,我很好奇这是否意味着前15个数据点(按顺序)将产生一个线性分隔数据集的分类器

通过随机抽样和替换,您可能会花费更长的时间(尽管,根据数据样本的分布和大小,这是不可能的,因为您大致预计任何15个点都与前15个点差不多)

另一个问题是,在检测到正确分类的点后(当
未被错误分类时
的计算结果为
),如果随后看到一个新的随机点被错误分类,则代码将在循环时踢入外部
的较大部分,然后返回顶部,它将用所有0覆盖
检查
向量

这意味着您的代码将检测到它已正确分类所有点的唯一方法是,如果它计算这些点的特定随机序列(在内部
while
循环中)恰好是所有1的字符串,除了通过数组的任何特定0上的神奇能力,它分类正确

我不能很正式地解释为什么我认为这会使程序花费更长的时间,但似乎您的代码需要更严格的收敛形式,在训练阶段的后期,在经过大量更新后,它必须在一个单一的通道上一次学习所有东西

检查我的直觉是否糟糕的一个简单方法是将行
check=[0]*len(output)
移到
while循环的外部,并且只初始化一次

一些使代码更易于管理的一般建议:

  • 不要使用全局变量。相反,让您的函数来加载和准备数据,并返回一些东西

  • 有几个地方你说,比如

    return(如果在产品上签名(数据[rand\u p]),则返回True)!=output[rand\u p]否则返回False)

    这种事情可以简化为

    return sign\u dot\u product(数据[rand\u p])!=输出[rand\u p]

    它更容易阅读,并以更直接的方式传达您试图检查的标准

  • 我怀疑效率起着重要作用,因为这似乎是一个教学练习,但有许多方法可以重构列表理解的使用,这可能是有益的。如果可能,只需使用具有本机数组类型的
    NumPy
    。目睹这些操作中的一些必须用
    list
    操作来表达是令人遗憾的。即使你的教授不想让你用
    NumPy
    来实现,因为她或他试图教你纯粹的基础知识,我还是建议你忽略它们,去学习
    NumPy
    。它将帮助您完成工作、实习以及Python中此类操作的实际技能,远远超过与本机数据类型进行斗争以完成它们不适合的任务(数组计算)


  • 首先感谢您的反馈。事实上,我并没有参加这门课程,而是在做一些自学。我使用的算法可以在中的幻灯片14中查看。这里给出了用替换选择新点的方法。家庭作业也谈到了同样的PLA算法。因此,根据本文,我的实现或生成问题的数据集是否存在任何问题。如果没有看到所有的数据生成代码,我不能说更多。似乎您不应该使用
    check
    变量,而是应该在生成新的
    rand\p
    后,只要正确分类,就使用
    pass
    continue
    。试着这样做,然后试着按顺序遍历数据(即使您再次环绕并从数据的开头开始)。看看需要多长时间。从代码中我可以看到,除了这个需要很长时间的问题,我没有看到任何算法错误。但是,全局变量的使用使其复杂化。
    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