感知机用于将一个线性可分的模型将正实例点和负实例点分在一个平面的两侧。
感知机学习算法一共有两种实现形式,一种是原始形式,一种是对偶形式
感知机学习算法是通过梯度下降算法来实现最优化的,这里梯度下降选用的是随机梯度下降法。
1. 原始形式
算法实现步骤:
- 选取初值 w , b w,b w,b
- 在训练集中选取数据 x i , y i x^i,y^i xi,yi
- 如果
y
∗
(
w
x
+
b
)
<
=
0
y*(wx+b)<=0
y∗(wx+b)<=0 ,那么更新
w
,
b
w,b
w,b,
w = w + η y i x i w = w+\eta y^ix^i w=w+ηyixi
b = b + η y i b = b+\eta y^i b=b+ηyi - 转至(2),直到训练集中没有误分类点
这里我为了代码简洁,将
b
b
b当做了
w
0
w^0
w0处理,并将
X
X
X的每一行都添加了一个1。
代码如下:
#!/usr/bin/env python
import numpy as np;
# 实现感知觉学习算法
def perceptron(X,y,w,alpha):
(m,n) = X.shape;
while(1):
num = 0;
for i in range(0,m):
x = X[i].reshape((1,n));
if(x.dot(w)*y[i]<=0):
grad(w,x,y[i],alpha);
print('i='+(i+1).__str__());
else: num+=1;
if(num==m): break;
# 计算出梯度,然后更新w
def grad(w,x,y,alpha):
w+=alpha*x.T*y;
if __name__=='__main__':
X = np.array([[3,3],[4,3],[1,1]]);
(m, n) = X.shape;
X = np.c_[np.ones((m, 1)), X];
y = np.array([[1],[1],[-1]]);
w = np.zeros((n+1,1));
alpha = 1;
perceptron(X,y,w,alpha);
其实随机下降梯度算法需要先将数据集随机排序。
对偶形式
对偶形式其实就是原始形式的
w
w
w和
b
b
b的化简形式
w
=
∑
i
=
1
N
α
i
y
i
x
i
w = \sum_{i=1}^{N}\alpha_iy_ix_i
w=i=1∑Nαiyixi
b
=
∑
α
y
i
b = \sum\alpha y_i
b=∑αyi
a
l
p
h
a
=
n
i
η
alpha=n_i \eta
alpha=niη
x
i
x^i
xi中的i表示第几组数据,
n
i
n_i
ni表示
x
i
x_i
xi纠正次数,初始化全为0。
G
r
a
m
=
[
x
i
∗
x
j
]
N
∗
N
Gram = [x_i*x_j]_{N*N}
Gram=[xi∗xj]N∗N
预先求得的Gram矩阵其实就是
X
∗
X
T
X*X^T
X∗XT。
算法实现步骤:
- α = 0 \alpha=0 α=0 , b = 0 b=0 b=0
- 在训练集中选取数据 x i , y i x^i,y^i xi,yi
- 如果
y
i
(
∑
j
=
1
N
α
j
y
j
x
j
∗
x
i
+
b
)
<
=
0
y^i(\sum_{j=1}^{N}\alpha_jy_jx_j*x_i+b)<=0
yi(∑j=1Nαjyjxj∗xi+b)<=0
α = α + η \alpha=\alpha+\eta α=α+η
b = b + η y i b = b+\eta y^i b=b+ηyi - 转至(2),直到训练集中没有误分类点
代码实现没有用像原始形式那样的技巧。
代码如下:
#!/usr/bin/env python
import numpy as np;
def antperceptron(X,y,alpha,b,learn):
m = X.shape[0];
Gram = X.dot(X.T);
#print(Gram);
while(1):
num=0;
for i in range(0,m):
x = Gram[:,i].reshape(m,1);
sum_x = (alpha*y*x).sum()+b;
#print(sum_x);
if(y[i]*sum_x<=0):
[alpha[i],b]=grad(alpha[i],y[i],b,learn);
print('i='+(i+1).__str__());
else: num+=1;
if(num==m): break;
def grad(alpha_x,y,b,learn):
alpha_x = alpha_x +learn;
b = b+learn*y;
return [alpha_x,b];
if __name__=='__main__':
X = np.array([[3,3],[4,3],[1,1]]);
y = np.array([[1],[1],[-1]]);
alpha = np.zeros((X.shape[0],1));
b = 0; learn = 1;
antperceptron(X,y,alpha,b,learn);
参考资料:
李航----统计学习方法