这是我第一次从头开始编写感知器学习算法。我之前使用过现成的机器学习解决方案,但这次我想真正理解它并自己编写。不知为何,我的错误率一直在增加而不是减少。因此,看来我的算法在发散而不是收敛。我设置了一个容忍范围,因为它有时会接近目标,但从未完全达到要求。
我有三个权重;一个用于偏置,另外两个分别用于X和Y。
我通过以下方式找到判别函数:D = (weight0 + weight1 * Xi) + (weight2 * Yi)
如果判别函数与预期输出不匹配,那么我会使用以下方式更新权重:注意:假设c和k是预定义的常数,d = 预期输出w0 = w0 + cdk
, w1 = w1 + cdXi
, w2 = w2 + cdYi
以下是我在Python中的实现:
def weightsUpdate(weights, constantC, constantK, classificationd, x, y):
weights[0] = weights[0] + constantC * classificationd * constantK # w0 = w0 + cdk
weights[1] = weights[1] + constantC * classificationd * x #w1 = w1 + cdx
weights[2] = weights[2] + constantC * classificationd * y #w2 = w2 + cdy
return weights
def trainModel(df, weights, constantC, constantK, maxIter, threshHold):
#grab the values in a list
x = df['X'].values
y = df['Y'].values
d = df['Class'].values
#define some variables to keep track
numTurns = 0
while numTurns < maxIter:
errorRate = 0
falsePosNeg = 0
truePosNeg = 0
'''assign som threshhold values. must accomodate for slight variance.'''
posThreshHoldCeiling = 1 + threshHold
posThreshHoldFloor = 1 - threshHold
negThreshHoldFloor = -1 - threshHold
negThreshHoldCeiling = -1 + threshHold
for i in range(len(x)):
''' calculate the discriminant D = w0 + w1*xi + w2*yi '''
discriminant = weights[0] + (weights[1] * x[i]) + (weights[2] * y[i])
'''if the discriminant is not correct when compared to the correct output'''
if ((discriminant >= posThreshHoldFloor and discriminant <= posThreshHoldCeiling) or
(discriminant >= negThreshHoldFloor and discriminant <= negThreshHoldCeiling)):
truePosNeg += 1
#weights = weightsUpdate(weights, constantC, constantK, d[i], x[i], y[i])
else:
'''update the weights'''
weights = weightsUpdate(weights, constantC, constantK, d[i], x[i], y[i])
falsePosNeg += 1
numTurns += 1 #increase number of turns by 1 iteration
print("Number of False Positive/Negative: " + str(falsePosNeg))
print("Number of True Positive/Negative: " + str(truePosNeg))
errorRate = falsePosNeg / len(x) * 100
print("Error rate: " + str(errorRate) + "%")
'''add stop conditions'''
if (errorRate < 25):
break
else:
continue
感谢所有帮助。
回答:
感知器学习算法(PLA)不应该需要阈值。此外,PLA要求判别函数和预期输出的符号应该匹配,即,sign(Discriminant) == d
,因此不需要实际输出的收敛。以下是trainModel()
的修改版本。
def trainModel(df, weights, constantC, constantK, maxIter):
#grab the values in a list
x = df['X'].values
y = df['Y'].values
d = df['Class'].values
globalErrorRate = 0
#define some variables to keep track
numTurns = 0
while numTurns < maxIter:
localErrorRate = 0
successRate = 0
falsePosNeg = 0
truePosNeg = 0
for i in range(len(x)):
#calculate the discriminant
discriminant = weights[0] + (weights[1] * x[i]) + (weights[2] * y[i])
if(isPos(discriminant) and d[i] == 1):
truePosNeg += 1
elif(isPos(discriminant) == False and d[i] == -1):
truePosNeg += 1
else:
falsePosNeg += 1
weights = weightsUpdate(weights, constantC, constantK, d[i], x[i], y[i])
numTurns += 1 #increase number of turns by 1 iteration
print("Number of False Positive/Negative: " + str(falsePosNeg))
print("Number of True Positive/Negative: " + str(truePosNeg))
localErrorRate = falsePosNeg / len(x) * 100
successRate = truePosNeg / len(x) * 100
print("Error rate: " + str(localErrorRate) + "%")
print("Success rate: " + str(successRate) + "%")
if successRate == 100:
print("Trained Weight Values: " + str(weights))
break
else:
continue