感知机和SVM算法的实现(sklearn)

感知机

题目要求如下:

首先我们产生数据(注意,我们的data后面都加上一个1,是为了计算感知机里的偏置也就是常数项):

1
2
3
4
5
6
7
8
import numpy as np
from matplotlib import pyplot as plt


def produce():
data = np.array([[1,2,1],[2,3,1],[3,3,1],[2,1,1],[3,2,1]])
label = np.array([1,1,1,-1,-1])
return data,label

感知机计算函数如下:

1
2
3
def sign(w,x):
res = np.dot(w,x)
return res

然后就是计算感知机系数的过程,如果一轮迭代后权重发生改变,则继续循环,否则说明权重已经收敛,就停止计算,返回权重

1
2
3
4
5
6
7
8
9
10
11
12
def calulate_w(iters):
data,label = produce()
w = np.array([0,0,0])
for i in range(iters):
w_old = w
for j in range(5):
res = sign(w,data[j])
if label[j]*res <= 0:
w = w + label[j]*data[j]
if (w_old == w).all==True:
break
return w

最后就是将我们计算得到的结果画出来,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def main():
data, label = produce()
w = calulate_w(100)
print(w)
X_true = data[:3]
X_false = data[3:]
plt.scatter(X_true[:, 0], X_true[:, 1],c='r',label='+')
plt.scatter(X_false[:, 0], X_false[:, 1], c='b', label='-')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Perpetron')
x1 = np.arange(0,4.0,0.1)
y1 = (-w[2]-w[0]*x1)/w[1]
plt.plot(x1,y1)
plt.legend()
plt.show()


if __name__=="__main__":
main()
[-7  9 -1]

output_10_1.png

结果图和w计算结果如上图所示。

SVM分类(使用sklearn)

题目要求如下:

产生数据同上:

1
2
3
4
5
6
7
8
9
10
11
12
13
from numpy import *
from sklearn import svm
import matplotlib.pyplot as plt

def produce():
data = array([[1,2,1],
[2,3,1],
[3,3,1],
[2,1,-1],
[3,2,-1]])
x=data[:,0:2]
y=data[:,2]
return x,y,data

计算svm的系数,调包即可:

1
2
3
4
def compute_svm(x,y):
clf=svm.SVC(kernel='linear',C=1000)
clf.fit(x,y)
return clf

最后得出结果,画图如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def main():
x,y,data = produce()
clf = compute_svm(x,y)
w = clf.coef_[0]
print('weight for svm:',w)
x0 = data[:3,:]
x1 = data[3:,:]
plt.scatter(x0[:, 0], x0[:, 1], c='r', label='+')
plt.scatter(x1[:, 0], x1[:, 1], c='b', label='-')
a = -w[0] / w[1]
xx = arange(0,4.0,0.1)
yy = a * xx - clf.intercept_[0] / w[1]
plt.plot(xx, yy)
plt.title('svm for linear')
plt.xlabel('density')
plt.ylabel('ratio_sugar')
plt.legend()
plt.show()


if __name__=="__main__":
main()
('weight for svm:', array([-1.,  2.]))

output_20_1.png

可得图和权重结果。

0%