机器学习之感知机(C语言描述)

《统计学习方法系列1》

第一章 统计学习方法之感知机



前言

最近拜读了机器学习领域,经典书籍,李航老师的《统计学习方法》,深受裨益。


一、感知机是什么?

原文所述:感知机 (perceptron) 是二类分类的线性模型,其输入空间为实例的特征向量,输出为实例的类别,取 +1 与 -1 二值。感知机对应于输入空间中将实例划分成为正负两类超平面,属于判别模型。

感知机学习旨在求出能准确划分数据的超平面,为此,导入基于误分类的损失函数,利用梯度下降法对损失函数进行极小化,求得感知机模型。

个人理解,是一个不带约束的svm?

二、感知机数学模型

假设输入空间 X ⊆ R n X \subseteq R^n XRn, 输出空间是 Y = { + 1 , − 1 } Y =\{+1, -1\} Y={+1,1},输入 x ⊊ X x \subsetneq X xX 表示实例的特征向量,对应于输入空间的点 y ⊊ Y y \subsetneq Y yY。由输入空间到输出空间的函数如下:
f ( x ) = s i g n ( w ⋅ x + b ) f(x) = sign(w \cdot x + b) f(x)=sign(wx+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,x0x<0

线性方程:

w ⋅ x + b = 0 w \cdot x + b = 0 wx+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∣∣1wx0+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(wixi+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(wx+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∣∣1xiMyi(wx+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)=xiMyi(wx+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)=xiMyi(wx+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)=xiMyixibL(w,b)=xiMyi
遍历所有点,遇上被误分类的点 ( 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(wxi+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 ww+ηyixibb+η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(wx+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

总结

感知机是一个非常简单的机器学习模型,现实应用场景中几乎不会用到感知机。但作为入门级别机器学习模型,很好地从理论到实现的展示了一个机器学习模型是如何训练,以及如何根据输入的数据,进行预测与推理。

完。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值