感知机的python实现
感知机是对线性可分的数据进行分类的一种模型,属于判别模型。通过所给出的数据集,求解出一个超平面,将两种不同类别的数据分离开来。其损失函数是误分点到超平面的距离,优化过程是将该距离变为0,从而实现消灭误分点,实现数据的成功划分的目的。
本文参考《统计学习方法(第二版)》李航著,第二章内容,将感知机的求解分为原始形式和对偶形式,分别通过python求解。
首先是原始形式:
import numpy as np
import matplotlib.pyplot as plt
import random
X = np.array([[0, 0], [5, 4], [4, 5], [9, 0], [0, 9], [10, 10], [10, 1], [1, 10], [6, 6], [5, 6]])
y = np.array([-1, -1, -1, -1, -1, 1, 1, 1, 1, 1])
a1 = X[:5, 0]
b1 = X[:5, 1]
a2 = X[5:, 0]
b2 = X[5:, 1]
plt.scatter(a1, b1)
plt.scatter(a2, b2)
def origin(η):
w = [0, 0]
b = 0
for i in range(10000):
t = random.randint(0, 9)
if y[t]*(w[0]*X[t, 0] + w[1]*X[t, 1] + b) <= 0:
w[0] = w[0] + η*y[t]*X[t, 0]
w[1] = w[1] + η*y[t]*X[t, 1]
b += η*y[t]
i = [-b/w[0], 0]
j = [0, -b/w[1]]
print(w)
print(b)
plt.plot(i, j)
plt.show()
运行结果如下图所示:
接下来展示对偶解法:
def dual(η):
G = np.zeros([10, 10])
α = np.zeros(10)
b = 0
for i in range(10):
for j in range(10):
G[i, j] = X[i][0]*X[j][0] + X[i][1]*X[j][1]
print(G)
for i in range(5000):
t = random.randint(0, 9)
m = 0
for j in range(10):
m += α[j]*y[j]*G[t, j]
n = (m + b)*y[t]
if n <= 0:
α[t] += η
b += η*y[t]
d1 = 0
d2 = 0
for j in range(10):
d1 += α[j] * y[j] * X[j][0]
d2 += α[j] * y[j] * X[j][1]
w = [d1, d2]
i = [-b / w[0], 0]
j = [0, -b / w[1]]
plt.plot(i, j)
plt.show()
运行结果如下图所示:
经过可视化后发现,运算结果与原始形式相同。
参考:《统计学习方法》 李航著