笔记三:感知器算法原理和步骤。
程序实现:手撕感知机算法
函数1--训练样本数据:
# 创建训练样本数据,第一个1为阈值对应的w0,即b
def createTrainDataSet():
trainData = [[1, 1, 4],
[1, 2, 3],
[1, -2, 3],
[1, -2, 2],
[1, 0, 1],
[1, 1, 2]]
label = [1, 1, -1, -1, -1, -1]
return trainData, label
函数2--测试样本数据:
# 创建测试样本数据
def createTestDataSet():
testData = [[1, 1, 1],
[1, 2, 0],
[1, 1, 4],
[1, 1, 3],
[1, 3, 5],
[1, 7, 2]]
return testData
类3--感知器算法(该类包括初始化、sigmoid函数、PLA、测试分类函数、画图函数):
# 感知机分类算法
class Perceptron_self():
def __init__(self): # 初始化函数
self.traindataIn, self.trainlabelIn = createTrainDataSet()
self.train_data = np.mat(self.traindataIn) # 将特征数据列表转换成矩阵
self.train_label = np.mat(self.trainlabelIn).transpose() # 将标签数据列表转化为矩阵并进行转置
self.testdata = createTestDataSet() # 获取测试集样本数据
self.m, self.n = np.shape(self.train_data) # 获取矩阵的行和列,行m用来更新每一个W值,列n用来形成全1数组
self.w = np.ones((self.n, 1)) # numpy中的ones函数是用于生成一个全1的数组
def sigmoid(self, X): # 定义激活函数--sigmoid()
X = float(X)
if X > 0:
return 1
elif X < 0:
return -1
else:
return 0
def pla(self): # 感知机学习算法--PLA
while True:
iscompleted = True # 作为判断是否更新W的标志
for i in range(self.m):
if (self.sigmoid(np.dot(self.train_data[i], self.w)) == self.train_label[i]): # 正确继续循环
continue
else:
iscompleted = False
# 当WT+b>0,且y=-1:W=W-X;当WT+b<0,且y=+1:W=W+X. 即:[W=W+y*X]进行更新
self.w += (self.train_label[i] * self.train_data[i]).transpose()
if iscompleted:
break # 判读全部样本均符合条件,循环退出
return self.w
def classify(self, inX, w):
result = self.sigmoid(np.dot(np.mat(inX), w))
if result > 0:
return 1
else:
return -1
def classifyall(self, datatest):
predict = []
for data in datatest:
result = self.classify(data, self.w)
predict.append(result)
return predict
def plotBestFit(self, traindata, label):
dataArr = np.array(traindata)
n = np.shape(dataArr)[0]
xcord1 = []
ycord1 = []
xcord2 = []
ycord2 = []
for i in range(n):
if int(label[i]) == 1:
xcord1.append(dataArr[i, 1])
ycord1.append(dataArr[i, 2])
else:
xcord2.append(dataArr[i, 1])
ycord2.append(dataArr[i, 2])
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
ax.scatter(xcord2, ycord2, s=30, c='green')
x = np.arange(-3.0, 3.0, 0.1)
y = (-self.w[0] - self.w[1] * x) / self.w[2]
ax.plot(x, y)
plt.xlabel('X1')
plt.ylabel('X2')
plt.show()
训练结果展示:
测试结果展示:
测试结果为:
完整代码为:
import numpy as np
import matplotlib.pyplot as plt
# 创建训练样本数据,第一个1为阈值对应的w0,即b
def createTrainDataSet():
trainData = [[1, 1, 4],
[1, 2, 3],
[1, -2, 3],
[1, -2, 2],
[1, 0, 1],
[1, 1, 2]]
label = [1, 1, -1, -1, -1, -1]
return trainData, label
# 创建测试样本数据
def createTestDataSet():
testData = [[1, 1, 1],
[1, 2, 0],
[1, 1, 4],
[1, 1, 3],
[1, 3, 5],
[1, 7, 2]]
return testData
# 感知机分类算法
class Perceptron_self():
def __init__(self): # 初始化函数
self.traindataIn, self.trainlabelIn = createTrainDataSet()
self.train_data = np.mat(self.traindataIn) # 将特征数据列表转换成矩阵
self.train_label = np.mat(self.trainlabelIn).transpose() # 将标签数据列表转化为矩阵并进行转置
self.testdata = createTestDataSet() # 获取测试集样本数据
self.m, self.n = np.shape(self.train_data) # 获取矩阵的行和列,行m用来更新每一个W值,列n用来形成全1数组
self.w = np.ones((self.n, 1)) # numpy中的ones函数是用于生成一个全1的数组
def sigmoid(self, X): # 定义激活函数--sigmoid()
X = float(X)
if X > 0:
return 1
elif X < 0:
return -1
else:
return 0
def pla(self): # 感知机学习算法--PLA
while True:
iscompleted = True # 作为判断是否更新W的标志
for i in range(self.m):
if (self.sigmoid(np.dot(self.train_data[i], self.w)) == self.train_label[i]): # 正确继续循环
continue
else:
iscompleted = False
# 当WT+b>0,且y=-1:W=W-X;当WT+b<0,且y=+1:W=W+X. 即:[W=W+y*X]进行更新
self.w += (self.train_label[i] * self.train_data[i]).transpose()
if iscompleted:
break # 判读全部样本均符合条件,循环退出
return self.w
def classify(self, inX, w):
result = self.sigmoid(np.dot(np.mat(inX), w))
if result > 0:
return 1
else:
return -1
def classifyall(self, datatest):
predict = []
for data in datatest:
result = self.classify(data, self.w)
predict.append(result)
return predict
def plotBestFit(self, traindata, label):
dataArr = np.array(traindata)
n = np.shape(dataArr)[0]
xcord1 = []
ycord1 = []
xcord2 = []
ycord2 = []
for i in range(n):
if int(label[i]) == 1:
xcord1.append(dataArr[i, 1])
ycord1.append(dataArr[i, 2])
else:
xcord2.append(dataArr[i, 1])
ycord2.append(dataArr[i, 2])
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
ax.scatter(xcord2, ycord2, s=30, c='green')
x = np.arange(-3.0, 3.0, 0.1)
y = (-self.w[0] - self.w[1] * x) / self.w[2]
ax.plot(x, y)
plt.xlabel('X1')
plt.ylabel('X2')
plt.show()
if __name__ == '__main__':
per = Perceptron_self()
per.pla()
# 训练
traindata, label = createTrainDataSet()
per.plotBestFit(traindata, label)
# 测试
testdata = createTestDataSet()
predict = per.classifyall(testdata)
per.plotBestFit(testdata, predict)
# print(testdata, "\n", predict)
# print("y={}x0+{}x1+{}x2".format(w[0],w[1],w[2]))