感知机的概念、算法请参照书本,这里只给出代码。
'''
##############感知机学习算法原始形式 开始##############
输入:训练数据集T={x1,y1},...,{xn,yn},学习率l
输出:w,b,感知机模型f(x)=sign(w·x+b)
(1)选取初始值w0,b0;
(2)在训练集中选取数据(xi,yi) (i为下标,范围是1-n)
(3)如果yi(w·xi+b)<=0,
w=w+lyixi
b=b+lyi
(4)转至(2),直至训练集中没有误分类点
##############感知机学习算法原始形式 结束##############
##############感知机学习算法对偶形式 开始##############
输入:训练数据集T={x1,y1},...,{xn,yn},学习率l
输出:a,b,感知机模型f(x)=sign((累加ajyjxj(j从1到n))*x+b),其中a=(a1,a2,...,an)^T
(1)选取初始值a0,b0;
(2)在训练集中选取数据(xi,yi) (i为下标,范围是1-n)
(3)如果((累加ajyjxj(j从1到n))*x+b)<=0,
a=a+l
b=b+lyi
(4)转至(2),直至训练集中没有误分类点
Gram matrix: G = [xi·xj]n*n
#######感知机学习算法对偶形式 结束#######
'''
import numpy as np
import matplotlib.pyplot as plt
class train():
# f(x)=sign(wx+b)
def originalTrain(self, x, y, w, b, dimension):
wx = sum(x[j] * w[j] for j in range(dimension))
f = y * (wx + b)
return f
def originalTrain(self, data, learning_rate, max_loop_cnt=10000): # 训练集,学习率,最大迭代次数
data_num = len(data) # 数据集大小
if data_num == 0: # 没有数据,直接返回
return None
dimension = len(data[0][0]) # 特征向量的维度
w = [0 for i in range(dimension)] # 初始化w0,b0
b = 0
for k in range(max_loop_cnt):
loop_end = True
for i in range(data_num): # 计算第(3)步
x, y = data[i][0], data[i][1]
wx = sum(x[j] * w[j] for j in range(dimension))
f = y * (wx + b) # 计算f=yi(w·xi+b)
while f <= 0:
for j in range(dimension):
w[j] = w[j] + learning_rate * y * x[j]
b = b + learning_rate * y
wx = sum(x[j] * w[j] for j in range(dimension))
f = y * (wx + b)
print('i,x,y,w,b,f', i, x, y, w, b, f)
loop_end = False
if loop_end:
print("All data are classified correctly by using originalTrain")
return w, b
return None
def dualTrain(self, data, learning_rate, max_loop_cnt=10000): # 对偶形式
data_num = len(data)
dimension = len(data[0][0])
gram = [ # 先计算gram matrix
[
sum([data[i][0][k] * data[j][0][k]
for k in range(dimension)])
for j in range(data_num)
]
for i in range(data_num)
]
print('gram', gram)
alpha = [0 for i in range(data_num)]
b = 0
print('alpha', alpha)
for k in range(max_loop_cnt): # 与原始形式的做法类似
loop_end = True
for i in range(data_num):
y = data[i][1]
tmp = sum(alpha[j] * data[j][1] * gram[j][i] for j in range(data_num)) + b
f = tmp * y
while f <= 0:
alpha[i] += learning_rate
b += learning_rate * y
tmp = sum(alpha[j] * learning_rate * data[j][1] * gram[j][i] for j in range(data_num)) + b
f = tmp * y
loop_end = False
print('dual change', i, data[i][0], data[i][1], alpha, b, f)
if loop_end:
print("All data are classified correctly by using dualTrain")
return alpha, b
return None
class perceptron(): # 感知机模型
def __init__(self, w, b):
self.w = w
self.b = b
def percept(self, x): # 进行计算
f = sum(self.w[i] * x[i] for i in range(len(x))) + self.b
print(f)
if f > 0:
return 1
elif f < 0:
return -1
def test(data): # 测试感知机模型,并输出w,b
tr = train()
w, b = tr.originalTrain(data, 1)
alpha, b = tr.dualTrain(data, 1)
print('w,b', w, b)
# print('alpha,b',alpha,b)
per = perceptron(w=w, b=b)
print(per.percept((1, 1)))
return w, b
def showPicture(data, w, b): # 画出数据的图像以及分离超平面
data = [data[i][0] for i in range(len(data))]
# print(data)
data = np.array(data)
m, n = data.shape
# 画出所有数据点
for i in range(m):
x, y = data[i][0], data[i][1]
plt.annotate("(%s,%s)" % (x, y), xy=(x, y))
plt.scatter(x, y)
max_num = np.max(data)
# 画出超平面
x = np.linspace(0, max_num + 10)
#w0x+w1y+b=0 1.如果w1=0,x=-1/w0,否则y=(-b-w0·x)/w1
if w[1] == 0:
x = -b / w[0]
else:
y = (-b - w[0] * x) / w[1]
plt.plot(x, y)
plt.show()
if __name__ == '__main__':
data = [((3, 3), 1), ((4, 3), 1), ((1, 1), -1)]
print('data', data)
w, b = test(data)
showPicture(data, w, b)