定义和模型
(1)
f
(
x
)
=
s
i
g
n
(
w
⋅
x
+
b
)
f(x) = sign(w \cdot x+b) \tag{1}
f(x)=sign(w⋅x+b)(1)
其中, w和b是模型参数, w向量叫做权重向量; b叫偏置(bias)向量。
公式1就是感知机,是线性分类模型(liner classifier model),属于判别模型。
几何解释
超平面:
(2)
w
⋅
x
+
b
=
0
w\cdot x +b =0 \tag{2}
w⋅x+b=0(2)
也称为分离超平面;其实和二维空间的二维分割线一个作用。在多维空间中,则称为超平面,
w
w
w是法向量,也就是平面上变化最快的方向,可以参考梯度.
学习目标
我们的目标是通过训练实例,学习参数w,b,从而找到分离超平面,得到模型,公式1,从而预测新的实例。大部分的学习都是学习参数,从而确定假设空间,也就是f。
学习策略
极小化误分类点到分离超平面的距离。 也就是说,错误实例点到分离平面的距离之和尽量小。
损失函数
如果存在超平面
w
⋅
x
+
b
=
0
w\cdot x +b =0
w⋅x+b=0
那么正确的分类的实例,
w
⋅
x
i
+
b
>
0
w\cdot x_i +b >0
w⋅xi+b>0的
y
i
y_i
yi值为1; 那么
w
⋅
x
i
+
b
<
0
w\cdot x_i +b<0
w⋅xi+b<0的
y
i
y_i
yi的值则为-1。
任意一个点
(
x
i
,
y
i
)
(x_i,y_i)
(xi,yi)到超平面的距离为:
∣
w
⋅
x
i
+
b
∣
∥
W
∥
\frac{|w\cdot x_i+b|}{\lVert W \lVert}
∥W∥∣w⋅xi+b∣
补充:
点到平面的距离公式
d = ∣ A x 0 + B y 0 + C Z 0 + D ∣ A 2 + B 2 + C 2 d = \frac{|Ax_0+By_0+CZ_0+D|}{\sqrt{A^2+B^2+C^2}} d=A2+B2+C2∣Ax0+By0+CZ0+D∣
公式描述:公式中的平面方程为Ax+By+Cz+D=0,点P的坐标(x0,y0,z0),d为点P到平面的距离。
技巧:由于是误分类点,根据f>0,y=-1; f<0,y=1这个特点,可以得到分类点
x
i
x_i
xi到超平面的距离公式统一为:
−
1
∥
W
∥
y
i
(
w
⋅
x
i
+
b
)
-\frac{1}{\lVert W \lVert}y_i(w\cdot x_i+b)
−∥W∥1yi(w⋅xi+b)
不考虑固定的法向量w的L2范数,那么我们的优化目标即损失函数为:
(3)
L
o
s
s
(
w
,
b
)
=
−
∑
x
i
∈
M
y
i
(
w
⋅
x
i
+
b
)
Loss(w,b) =- \sum_{x_i \in M}^{}y_i(w\cdot x_i+b) \tag{3}
Loss(w,b)=−xi∈M∑yi(w⋅xi+b)(3)
其中M为误分类点集合。总结一句:错误样例驱动的训练模型。
学习算法
采用随机梯度下降法,对w和b分别求偏导得到梯度:
∇
w
L
(
w
,
b
)
=
−
∑
x
i
∈
M
y
i
x
i
\nabla_w L(w,b) = - \sum_{x_i \in M} y_ix_i
∇wL(w,b)=−xi∈M∑yixi
∇
b
L
(
w
,
b
)
=
−
∑
x
i
∈
M
y
i
\nabla_b L(w,b) = - \sum_{x_i \in M} y_i
∇bL(w,b)=−xi∈M∑yi
有了梯度,则参数按照负梯度的方向变化,则目标函数会不断减小。
针对一个误分类点
(
x
i
,
y
i
)
(x_i, y_i)
(xi,yi),从而得到更新公式:
(4)
w
:
=
w
+
η
y
i
x
i
b
:
=
b
+
η
y
i
w:=w+\eta y_ix_i \\ b:=b+\eta y_i \\ \tag{4}
w:=w+ηyixib:=b+ηyi(4)
根据公式4,则找到了参数的迭代公式。
利用一个实例进行更新参数,是随机梯度下降法。
对偶形式
算法
输入:训练数据集
T
=
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
.
.
.
,
(
x
N
,
y
N
)
,
y
∈
{
−
1
,
+
1
}
T={(x_1,y_1),(x_2,y_2),...,(x_N,y_N)}, y \in \{{-1,+1}\}
T=(x1,y1),(x2,y2),...,(xN,yN),y∈{−1,+1}, 学习率
η
(
0
<
η
<
=
1
)
\eta(0<\eta<=1)
η(0<η<=1)
输出:w,b 感知机模型
f
(
x
)
=
s
i
g
n
(
w
⋅
x
+
b
)
f(x) = sign(w\cdot x+b)
f(x)=sign(w⋅x+b)
算法步骤:
- 选择初始值 w 0 , b 0 w_0,b_0 w0,b0
- 在训练集中选择数据 ( x i , y i ) (x_i,y_i) (xi,yi)
- 如果满足
y
i
(
w
⋅
x
i
+
b
)
<
=
0
y_i(w\cdot x_i+b)<=0
yi(w⋅xi+b)<=0则是误分类点,那么更新参数。
w : = w + η y i x i b : = b + η y i w:=w+\eta y_ix_i \\ b:=b+\eta y_i \\ w:=w+ηyixib:=b+ηyi - 转到2直到不存在误分类点。
解释:如果存在误分类点,则通过更新w,b来满足误分类点,直到不存在误分类点。
举例和代码
package algorithm;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 用二维特征演示感知机的计算过程例子。
*
*
*/
public class Perceptron {
//feature, label
// w:=w+alpha * xiyi
// b:= alpha * yi
public static void main(String args[])
{
List<Instance> data = new ArrayList<Instance>();
data.add(new Instance(new int[]{3,3},1));
data.add(new Instance(new int[]{4,3},1));
data.add(new Instance(new int[]{1,1},-1));
Perceptron pt = new Perceptron();
pt.fit(data);
}
public void fit(List<Instance>data){
int iteration = 1;
boolean allfit = true;
while(allfit)
{
allfit = false;
for(Instance it: data)
{
int distanceToPlane = 0;
for(int i=0;i<w.length;i++)
{
distanceToPlane+=(w[i]*it.feature[i]);
}
distanceToPlane+=b;
distanceToPlane*=it.label;
if(distanceToPlane<=0)
{
allfit = true;
for(int i=0;i<w.length;i++)
{
w[i]+=it.label*it.feature[i];
}
b+=it.label;
System.out.println("迭代次数:"+iteration+++",误分类点:"+it.label+","+Arrays.toString(it.feature)+",w:"+Arrays.toString(w)+",b:"+b);
System.out.println();
}
}
}
}
private int w[] = new int[2];
private int b = 0;
}
class Instance
{
//模拟二维的特征向量
int[] feature = new int[2];
int label;
Instance(int[]feature, int label)
{
this.feature = feature;
this.label = label;
}
}
计算的输入实例是:
data.add(new Instance(new int[]{3,3},1));
data.add(new Instance(new int[]{4,3},1));
data.add(new Instance(new int[]{1,1},-1));
三个实例,2个正例,一个反例。
结果是:
迭代次数:1,误分类点:1,[3, 3],w:[3, 3],b:1
迭代次数:2,误分类点:-1,[1, 1],w:[2, 2],b:0
迭代次数:3,误分类点:-1,[1, 1],w:[1, 1],b:-1
迭代次数:4,误分类点:-1,[1, 1],w:[0, 0],b:-2
迭代次数:5,误分类点:1,[3, 3],w:[3, 3],b:-1
迭代次数:6,误分类点:-1,[1, 1],w:[2, 2],b:-2
迭代次数:7,误分类点:-1,[1, 1],w:[1, 1],b:-3
python-sklearn
from sklearn.linear_model import Perceptron
x_data_train = [[3.0,3.0],[4.0,3.0],[1.0,1.0]]
y_data_train = [1,1,-1]
#定义感知机
clf = Perceptron(fit_intercept=True,n_iter=30,shuffle=False)
#使用训练数据进行训练
clf.fit(x_data_train,y_data_train)
#得到训练结果,权重矩阵W
print(clf.coef_)
#输出为:[[ 1. 1.]]
#超平面的截距b,此处输出为:[-3.]
print(clf.intercept_)
输出的结果和java程序的输出是一样的。
总结
- 二分类模型
- 线性分类模型
- 感知机对应到分离超平面,属于判别模型。
- 误分类驱动的损失函数
- 随机梯度下降求解最优
- 分为原始形式和对偶形式
- 是神经网络和支持向量机的基础
- 函数是符号函数,称为感知机。 f ( x ) = s i g n ( w ⋅ x + b ) f(x) = sign(w \cdot x+b) f(x)=sign(w⋅x+b)
参考文献
https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_plane
https://zhuanlan.zhihu.com/p/27152953
统计学习方法 李航