对偶就是从不同角度解答相似问题,但解相同。
在前面我们将 和 设置为0,对误分类点通过
逐步修改,设修改了n次,则关于的增量分别是和,其中
是该点是误分类点的次数,是学习率,当时,表示第i个实例点由于误分而进行更新的次数。
实例点更新次数越多说明它离超平面更近,也越难正确分类。
其实从感知机原始算法可以看出时,的值其实只与误分类点有关,学习率是常数。
这是李航老师书中列出的感知机对偶算法,其中就是前面的,之前一直看不懂,理解这个就好了,可以看出w最终与误分类点和该点被误分类的次数有关,
在代码中用矩阵计算好然后记录 点被误分类的次数就可以了,然后注意到
中的可以用矩阵先计算好,这个矩阵就是Gram矩阵(Gram matrix):
# 将之前的train_random换成这个
def train_dual(self, feature, label):
"""
感知机对偶训练模型
:param feature:特征
:param label: 标签
:return: 返回最终w,b
"""
G = np.zeros([len(feature), len(feature)])
alpha = np.zeros(len(feature))
# b = 0
# 计算gram矩阵
for i in range(0, len(feature)):
for j in range(0, len(feature)):
G[i][j] = feature[i][0]*feature[j][0]+feature[i][1]*feature[j][1]
flag = True
while flag:
flag = False
for i in range(0, len(feature)):
sum = 0
for j in range(0, len(feature)):
# 下面算w*x_i
sum += alpha[j] * label[j] * G[j][i]
# print(sum, "#")
# 误分条件
if (sum + self.b) * label[i] <= 0:
# 更新误分类次数和b
alpha[i] += self.learning_rate
self.b += self.learning_rate*label[i]
flag = True
break
# 计算w
self.w = [0., 0.] # w[0] * x + w[1] * y + b = 0
for i in range(0, len(feature)): # 求出 w 的值
self.w[0] += alpha[i] * label[i] * feature[i][0]
self.w[1] += alpha[i] * label[i] * feature[i][1]
# self.w = alpha[i]*label[i]*feature[i]
print(self.w, self.b, "@")
return self.w, self.b
目前对python里的函数还不太了解,所以代码写复杂了,等慢慢熟练了再回来改进。