感知机:教你用Python一步步实现
Posted Zccccccc_tz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了感知机:教你用Python一步步实现相关的知识,希望对你有一定的参考价值。
感知机
问题描述
感知机是二类分类的线性分类模型,输入为分类对象的特诊向量,输出为
±
1
\\pm 1
±1,用于判别分类对象的类型。这么说有些抽象,下面举一个例子。
就像上面这幅图,
- 实例对应上图就是每个点
- 实例的特征向量就是指这些点的横纵坐标,我们把他记为 ( x 1 , x 2 ) T (x_1, x_2)^T (x1,x2)T。
- 我们根据每个点的颜色,将点分别标记为 1 1 1和 − 1 -1 −1,也就是我们的输出 y y y 。
利用这些已知坐标的红蓝点,我们需要训练下面这个模型,
这个模型一共有
3
3
3个参数
(
θ
0
,
θ
1
,
θ
2
)
(\\theta_0, \\theta_1, \\theta_2)
(θ0,θ1,θ2),使它能够实现以下功能:
- 当 y = s i g n ( θ 1 x 1 + θ 2 x 2 + θ 0 ) = + 1 y=\\rm sign(\\theta_1 x_1 + \\theta_2 x_2 + \\theta_0)=+1 y=sign(θ1x1+θ2x2+θ0)=+1时,我们知道该点为红。
- 当 y = s i g n ( θ 1 x 1 + θ 2 x 2 + θ 0 ) = − 1 y=\\rm sign(\\theta_1 x_1 + \\theta_2 x_2 + \\theta_0)=-1 y=sign(θ1x1+θ2x2+θ0)=−1时,我们知道该点为蓝。
其中
s
i
g
n
(
x
)
=
+
1
,
x
≥
0
−
1
,
x
<
0
\\beginaligned \\rm sign(x) = \\left\\\\beginaligned +1,&x \\geq 0 \\\\ -1,&x<0 \\endaligned\\right. \\endaligned
sign(x)=+1,−1,x≥0x<0
数据集构建
开始前,我们需要自己整一个数据集用来训练。
先导入一些后面需要的包
import numpy as np
import matplotlib.pyplot as plt
import random
from typing import List, Tuple
然后就是搭建我们的数据集。
# 随机生成一些点,并根据直线将点划分为2个区域
def sample_point(w: float, b: float, num: int) -> Tuple[List[List[float]], List[float]]:
x, y = [], []
for _ in range(num):
p_x1 = np.random.random_sample(1) * 20 - 10
p_x2 = np.random.random_sample(1) * 20 - 10
p_y = 1 if w * p_x1 + b - p_x2 > 0 else -1
x.append([p_x1, p_x2])
y.append(p_y)
return x, y
# 先随机生成一条直线
w_ideal = np.random.random_sample(1) * 10 - 5
b_ideal = np.random.random_sample(1) * 10 - 5
x = np.linspace(-10, 10, 1000)
line_ideal = w_ideal * x + b_ideal
# 搭建数据集
sample_x, sample_y = sample_point(w_ideal, b_ideal, 500)
为了更加直观,我们可以将这些点用 matplotlib
来可视化一下
# 可视化
plt.xlim(xmax=-10, xmin=10)
plt.ylim(ymax=-10, ymin=10)
plt.plot(x, line_ideal, 'g', linewidth=10)
for i, p_x in enumerate(sample_x):
if sample_y[i] == 1:
plt.scatter(p_x[0], p_x[1], c='r', alpha=0.3)
else:
plt.scatter(p_x[0], p_x[1], c='b', alpha=0.3)
plt.show()
我们会得到下面这张图片,
其中绿色的那条线,就是实际情况下可以区分红蓝点的直线。
下面我们要做的,就是假装不知道这条直线的参数,即代码中的w_ideal
和b_ideal
,看看我们能否从数据集中获得我们估计出来的参数,即w_est
和b_ideal
。
(有人可能要问了,我们上面不是说三个参数
(
θ
0
,
θ
1
,
θ
2
)
(\\theta_0, \\theta_1, \\theta_2)
(θ0,θ1,θ2)吗?怎么又变成估计两个参数了?不着急,后面会有介绍)。
模型训练
模型训练的理论支持
回到我们的问题,如何根据点的横纵坐标来实现点颜色的分类?
为了能够实现这个预测功能,我们知道,我们需要训练
3
3
3个参数
(
θ
0
,
θ
1
,
θ
2
)
(\\theta_0, \\theta_1, \\theta_2)
(θ0,θ1,θ2)。
假设我们现在有了这么一组参数
(
θ
0
′
,
θ
1
′
,
θ
2
′
)
(\\theta_0',\\theta_1', \\theta_2')
(θ0′,θ1′,θ2′),如何衡量这一组参数的好坏呢?如果这一组参数还不够好,我们如何去优化这些参数呢?
于是,我们需要定义一个损失函数,用来衡量这个参数的好坏,并利用损失函数的梯度,将损失函数极小化。
损失函数的定义
直观来讲,一组好的参数应该满足不误分一个点,所以将分错点的个数作为损失函数是一个合理的想法。那么误分的点有什么特点呢?
y
i
⋅
(
∑
j
=
1
θ
j
x
i
j
+
θ
0
)
≤
0
y_i \\cdot (\\sum_j=1 \\theta_j x_ij + \\theta_0) \\leq 0
yi⋅(j=1∑θjxij+θ0)≤0
对于第
i
i
i个样本而言,
- 当样本点为蓝色时, y i = − 1 y_i=-1 yi=−1,却被误分为红色,也就是 ∑ j = 1 θ j x i j + θ 0 ≥ 0 \\sum_j=1 \\theta_j x_ij + \\theta_0 \\geq 0 ∑j=1θjxij+θ0≥0。
- 当样本点为红色时, y i = + 1 y_i=+1 yi=+1,却被误分为蓝色,也就是 ∑ j = 1 θ j x i j + θ 0 ≤ 0 \\sum_j=1 \\theta_j x_ij + \\theta_0 \\leq 0 ∑j=1θjxij+θ0≤0。
综上,我们损失函数被定义为 以上是关于感知机:教你用Python一步步实现的主要内容,如果未能解决你的问题,请参考以下文章 神级程序员教你用Python实现简单的导弹自动追踪!此乃装逼神技! #yyds干货盘点# 一步步教你用taro封装一个公司库的下拉组件 一步步教你用Prometheus搭建实时监控系统系列——详细分析拉取和推送两种不同模式
L
(
θ
)
=
−
∑
x
i
∈
M
y
i
⋅
(
∑
j
=
1
θ
j
x
i
j
+
θ
0
)
=
−
∑
x
i