感知机算法原理
感知机学习算法的原始形式:
输入:
T
=
(
x
1
,
y
1
)
,
.
.
.
,
(
x
n
,
y
n
)
T={(x_1,y_1),...,(x_n,y_n)}
T=(x1,y1),...,(xn,yn)其中,
x
i
x_i
xi属于
R
n
R^n
Rn,
y
i
y_i
yi属于{-1,1},i = 1,2,3,…,N;学习率a(0<a<=1)
输出:w,b;
模型为
f
(
x
)
=
s
i
g
n
(
w
∗
x
+
b
)
f(x)=sign(w*x+b)
f(x)=sign(w∗x+b)
(1)设定处置
w
0
,
b
0
w_0,b_0
w0,b0
(2)在训练集中选取数据
(
x
i
,
y
i
)
(x_i,y_i)
(xi,yi)
(3)如果
y
i
(
w
∗
x
i
+
b
)
<
=
0
y_i(w*x_i+b)<=0
yi(w∗xi+b)<=0:
w
i
+
1
=
w
i
+
a
y
i
x
i
w_{i+1}=w_i+ay_ix_i
wi+1=wi+ayixi
b
i
+
1
=
b
i
+
a
y
i
b_{i+1}=b_i+ay_i
bi+1=bi+ayi
(4)转至第(2)步直到训练集中没有误分类点
定义一个感知机的类:
class Model:#定义模型类
def __init__(self,data):#构造函数
self.w = np.zeros(len(data[0])-1,dtype=np.float32)#为w赋初值大小为训练数据集的x的维度
print(self.w)
self.b = 0#设置b的初值
self.learn_rate = 0.1#设置学习率
def sign(self,x,w,b):#定义模型函数f(x)=w*x + b
y = np.dot(w,x.T) + b
return y
def fit(self,x_train,y_train):#定义训练函数
is_wrong = False#设置循环控制变量
while not is_wrong:
wrong_count = 0#分类错误点的计数
for d in range(len(x_train)):#遍历提供的训练集
x = x_train[d]
y = y_train[d]
if (y*self.sign(x,self.w,self.b)) <= 0:#判断更新参数的条件
wrong_count += 1#分类错误点加一
#更新两个参数w,b
self.w = self.w + self.learn_rate*np.dot(y,x)
self.b = self.b + self.learn_rate*y
if wrong_count == 0:#判断是否还有分类错误点。
is_wrong = True
return 'perceptron Model'
具体训练流程:进入循环遍历所有的数据点并对每一个进行判断,如果分类错误,错误的计数加一,然后更新两个参数,直到遍历完所有的数据点。如果错误计数不为0,说明还有错误点存在,利用新的参数再去遍历所有数据点重复同样的操作,直到数据集中没有分类错误的数据。
模型已经编写完毕,下面就要使用特定的数据进行测试:
采用sklearn中的iris的数据集来进行测试,在iris数据集中的特征向量是四维的,不利于显示观看,所以选取特征向量的前两个特征,作为感知机输入的特征向量。并且在iris数据集中的类别为三类,我们只选取前两类。
下面是对数据处理的代码:
#导入所需要的功能包
import numpy as np
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
#载入数据集
iris_data = load_iris()
print(iris_data.feature_names)
#得到数据集的数据部分
iris = iris_data.data
iris_length = iris[:,0]#取得特征向量的第一维
iris_width = iris[:,1]#取得特征向量的第二维
targets = iris_data.target#数据集中的类别集合
iris_length_0 = iris_length[targets==0]#选取类别为0的数据
iris_width_0 = iris_width[targets==0]
iris_length_1 = iris_length[targets==1]#选取类别为1的数据
iris_width_1 = iris_width[targets==1]
T = []
#使用for循环将训练数据改为(x1,x2,y)的形式
for i in range(len(iris_length_0)):
T.append([iris_length_0[i],iris_width_0[i],-1])
for i in range(len(iris_length_1)):
T.append([iris_length_1[i],iris_width_1[i],1])
T = np.array(T)
#绘制两个类别的点
plt.scatter(T[T[:,2]==-1][:,0],T[T[:,2]==-1][:,1],label='0')
plt.scatter(T[T[:,2]==1][:,0],T[T[:,2]==1][:,1],label='0')
plt.legend()
最后就是使用模型和数据进行验证了:
perceptron = Model(T)
perceptron.fit(T[:,0:2],T[:,2])
#将训练后的参数在图像中显示出来
x = np.linspace(4,7,10)
y = -(perceptron.w[0]*x+perceptron.b)/perceptron.w[1]
plt.plot(x,y)
plt.scatter(T[T[:,2]==-1][:,0],T[T[:,2]==-1][:,1],label='0')
plt.scatter(T[T[:,2]==1][:,0],T[T[:,2]==1][:,1],label='0')