《统计学习方法系列1》
第一章 统计学习方法之感知机
前言
最近拜读了机器学习领域,经典书籍,李航老师的《统计学习方法》,深受裨益。
一、感知机是什么?
原文所述:感知机 (perceptron) 是二类分类的线性模型,其输入空间为实例的特征向量,输出为实例的类别,取 +1 与 -1 二值。感知机对应于输入空间中将实例划分成为正负两类超平面,属于判别模型。
感知机学习旨在求出能准确划分数据的超平面,为此,导入基于误分类的损失函数,利用梯度下降法对损失函数进行极小化,求得感知机模型。
个人理解,是一个不带约束的svm?
二、感知机数学模型
假设输入空间
X
⊆
R
n
X \subseteq R^n
X⊆Rn, 输出空间是
Y
=
{
+
1
,
−
1
}
Y =\{+1, -1\}
Y={+1,−1},输入
x
⊊
X
x \subsetneq X
x⊊X 表示实例的特征向量,对应于输入空间的点
y
⊊
Y
y \subsetneq Y
y⊊Y。由输入空间到输出空间的函数如下:
f
(
x
)
=
s
i
g
n
(
w
⋅
x
+
b
)
f(x) = sign(w \cdot x + b)
f(x)=sign(w⋅x+b)
这称之为感知机。其中:
s
i
g
n
(
x
)
=
{
+
1
,
x
≥
0
−
1
,
x
<
0
sign(x) = \begin{cases}+ 1, & x \ge 0\\ -1, & x \lt 0 \end{cases}
sign(x)={+1,−1,x≥0x<0
线性方程:
w
⋅
x
+
b
=
0
w \cdot x + b = 0
w⋅x+b=0
对应于特征空间
R
n
R^n
Rn 中的一个超平面
S
S
S,其中
w
w
w 是超平面的法向量,
b
b
b 是超平面的截距,这个超平面将特征空间划分为两部分,位于两部分的点分别被分正负两类。
我们的目标是找到适合的 w w w 与 b b b,使得超平面刚好可以正确划分所有的特征向量。
三、感知机的学习策略
首先输入空间 R n R^n Rn 中任一点 x 0 x_0 x0 到超平面 S S S 的距离:
1 ∣ ∣ w ∣ ∣ ∣ w ⋅ x 0 + b ∣ \frac {1} {||w||} | w \cdot x_0 + b| ∣∣w∣∣1∣w⋅x0+b∣
这里的 ∣ ∣ w ∣ ∣ ||w|| ∣∣w∣∣ 是 w w w 的 L 2 L_2 L2 范数,也就是( w 0 2 + w 1 2 + w 3 2 . . . + w n 2 \sqrt{w_0^2 + w_1^2 + w_3^2 ...+w_n^2} w02+w12+w32...+wn2), 其次,对于误分类点数据 ( x , y ) (x, y) (x,y) 来说,
−
y
i
(
w
i
⋅
x
i
+
b
)
>
0
-y_i(w_i\cdot x_i +b) \gt 0
−yi(wi⋅xi+b)>0
是成立的。因此,误分类点
x
i
x_i
xi 到超平面
S
S
S 的总距离为
−
1
∣
∣
w
∣
∣
y
i
(
w
⋅
x
+
b
)
-\frac{1}{||w||}y_i(w\cdot x +b)
−∣∣w∣∣1yi(w⋅x+b)
那么假设误分类点集合为
M
M
M,那么所有误分类点到超平面的距离和为:
−
1
∣
∣
w
∣
∣
∑
x
i
⊊
M
y
i
(
w
⋅
x
+
b
)
-\frac {1}{||w||} \sum_{x_i\subsetneq M} y_i(w\cdot x + b)
−∣∣w∣∣1xi⊊M∑yi(w⋅x+b)
不用考虑
1
∣
∣
w
∣
∣
\frac{1}{||w||}
∣∣w∣∣1,就得到感知机的损失函数:
L
(
w
,
b
)
=
−
∑
x
i
⊊
M
y
i
(
w
⋅
x
+
b
)
L(w,b) = - \sum_{x_i \subsetneq M}y_i(w\cdot x +b)
L(w,b)=−xi⊊M∑yi(w⋅x+b)
于是我们的目标便是最小化这个函数
min
w
,
b
L
(
w
,
b
)
=
−
∑
x
i
⊊
M
y
i
(
w
⋅
x
+
b
)
\min_{w,b}L(w,b) = -\sum_{x_i \subsetneq M} y_i(w\cdot x + b)
w,bminL(w,b)=−xi⊊M∑yi(w⋅x+b)
四,优化函数
得到了目标函数后,我们目标要使其最小化。最小化函数最常用的便是梯度下降法。对目标函数进行求导,便得到:
∇
w
L
(
w
,
b
)
=
−
∑
x
i
⊊
M
y
i
x
i
∇
b
L
(
w
,
b
)
=
−
∑
x
i
⊊
M
y
i
\nabla _wL(w, b) = - \sum_{x_i\subsetneq M}y_ix_i \\ \nabla _bL(w, b) = - \sum_{x_i\subsetneq M}yi
∇wL(w,b)=−xi⊊M∑yixi∇bL(w,b)=−xi⊊M∑yi
遍历所有点,遇上被误分类的点
(
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
,
b
w, b
w,b 进行更新:
w
←
w
+
η
y
i
x
i
b
←
b
+
η
y
i
w \leftarrow w + \eta y_ix_i \\ b \leftarrow b + \eta y_i
w←w+ηyixib←b+ηyi
其中
η
\eta
η 是梯度下降法中的步进系数。
五、感知机学习算法
综上所述,感知机的算法有以下几步:
1、初始化
w
0
,
b
0
w_0, b_0
w0,b0,一般将他们赋值为 0。
2、找出所有被误分的点,也就是
y
i
(
w
⋅
x
+
b
)
<
0
y_i(w\cdot x +b) \lt 0
yi(w⋅x+b)<0 的点。
3、然后更新
w
0
,
b
0
w_0, b_0
w0,b0。
4、重复步骤 2、3 直到没有误分类的点。
六、上代码
1、感知机的模型训练。
// C式伪代码:
matrix_t* pct_train(matrix_t* data, matrix_t* label, int eta)
{
// W_b 是 [w0, w1, w2,...wn,b] 向量。
// 其中 w 的长度为 data 的列数。
matrix_t* W_b = create_matrix(data->cols + 1);
// 初始化 W_b 为零
matrix_fill(W_b, 0.f);
// 是否有误分类点。
bool has_mistake = true;
while(has_mistake) {
has_mistake = false;
for (i : data->rows) {
int y_i = label[i];
matrix_t* x_i = data[i];
// x_i 往右拉宽一位,放入 1,形成新向量[x0, x1, x2, x3,...xn, 1]。
// 此举方便 x_i 点乘 W_b 向量。
matrix_pad_right(x_i, 1);
if ( y_i X (x_i dot W_b) > 0) {
// 遇上误分类的点
W_b += eta X y_i X W_b;
has_mistake = true;
// break;
}
}
} //直到没有误分类点,退出循环。
return W_b;
}
2、感知机推理代码
int pct_predict(matrix2_t* _X, matrix2_t* W_b)
{
// 将输入的特征向量往右拉宽一位,放入 1
Mat2_pad_right(_X, 1);
// X 向量与 W_b 向量点乘得到结果。
float predict = _X dot W_b;
return predict > 0 ? 1 : -1;
}
源码:https://github.com/zuweie/boring-code/blob/main/src/statistical_learning/perceptron.c
总结
感知机是一个非常简单的机器学习模型,现实应用场景中几乎不会用到感知机。但作为入门级别机器学习模型,很好地从理论到实现的展示了一个机器学习模型是如何训练,以及如何根据输入的数据,进行预测与推理。
完。