数据挖掘感知机模型全面解析,从理论原理到完整代码实战教程(附代码)
·
一、感知机模型理论详解
感知机(Perceptron)是二类分类的线性分类模型,其输入为实例的特征向量,输出为实例的类别,取 +1 和 -1 二值 。
感知机对应于输入空间(特征空间)中将实例划分为正负两类的分离超平面,属于判别模型 。
1. 核心数学模型
感知机由符号函数构成,其数学表达式如下:
$$
f(x) = sign(w \cdot x + b)
$$
其中,$w$ 为权值向量,$b$ 为偏置,$w \cdot x$ 表示 $w$ 和 $x$ 的内积 。符号函数 $sign$ 定义为:
$$
sign(x) = \begin{cases} +1, & x \geq 0 \ -1, & x < 0 \end{cases}
$$
2. 模型组件表
| 组件 | 符号 | 物理意义 | 更新规则 |
|---|---|---|---|
| 输入向量 | $x$ | 特征数据 (如身高、体重) | 固定不变 |
| 权值向量 | $w$ | 特征的重要性权重 | $w \leftarrow w + \eta y_i x_i$ |
| 偏置 | $b$ | 决策边界的截距 | $b \leftarrow b + \eta y_i$ |
| 学习率 | $\eta$ | 每次更新的步长 (0 < $\eta$ ≤ 1) | 人工设定 |
| 真实标签 | $y_i$ | 数据的真实类别 (+1 或 -1) | 固定不变 |
二、学习算法与逻辑推演
感知机学习算法旨在求出将训练数据进行线性划分的分离超平面,为此,导入基于误分类的损失函数,利用梯度下降法对损失函数进行极小化 。
1. 策略与算法
- 损失函数:选择误分类点到超平面总距离作为损失函数。
- 更新条件:当某个点被误分类时,即 $y_i(w \cdot x_i + b) \leq 0$ 时,更新参数 。
- 驱动逻辑:通过不断迭代,减少误分类点的数量,直到所有点都被正确分类或达到最大迭代次数 。
2. 难点解析
- 线性可分性:感知机仅适用于线性可分的数据集。如果数据异或(XOR)分布,单层感知机无法收敛 。
- 解的不唯一性:分离超平面依赖于初始值和迭代顺序,不同运行结果可能不同 。
三、Python 代码实战(含详细注释)
以下代码整合了数据生成、模型类封装、训练逻辑及可视化展示,完整复现了感知机的工作流程 。
import numpy as np
import matplotlib.pyplot as plt
class Perceptron:
def __init__(self):
self.w = None # 初始化权值向量
self.b = 0 # 初始化偏置
def train(self, X, y, eta=0.1, times=100):
"""
训练感知机模型
:param X: 训练数据特征 (n_samples, n_features)
:param y: 训练数据标签 (n_samples,)
:param eta: 学习速率
:param times: 最大迭代次数
"""
n_samples, n_features = X.shape
self.w = np.zeros(n_features) # 权重初始化为 0
for i in range(times):
is_updated = False
# 遍历所有样本进行检查
for idx in range(n_samples):
xi = X[idx]
yi = y[idx]
# 判断是否误分类:yi(w*xi + b) <= 0
if yi * (np.dot(self.w, xi) + self.b) <= 0:
# 核心更新公式:w = w + eta * yi * xi
self.w += eta * yi * xi
self.b += eta * yi
is_updated = True
# 如果一轮下来没有更新,说明已完全分类,提前结束
if not is_updated:
print(f"收敛于第 {i+1} 轮迭代")
break
def predict(self, X):
"""预测函数"""
return np.sign(np.dot(X, self.w) + self.b)
# --- 数据生成与可视化部分 ---
# 生成线性可分的数据,保证结果可复现
np.random.seed(0)
X = np.random.randn(100, 2) # 生成 100 个 2 维特征的数据点
# 标签:x0 + x1 > 0 为 1,否则为 -1,构造线性可分边界
Y = np.array([1 if x[0] + x[1] > 0 else -1 for x in X])
# 实例化并训练模型
model = Perceptron()
model.train(X, Y, eta=0.1, times=50)
# 可视化结果
plt.scatter(X[Y==1][:, 0], X[Y==1][:, 1], color='blue', label='Class 1')
plt.scatter(X[Y==-1][:, 0], X[Y==-1][:, 1], color='red', label='Class -1')
# 绘制决策边界 w0*x + w1*y + b = 0 => y = -(w0*x + b)/w1
x_line = np.linspace(-3, 3, 100)
if model.w[1] != 0:
y_line = -(model.w[0] * x_line + model.b) / model.w[1]
plt.plot(x_line, y_line, label='Decision Boundary', color='black')
plt.title('Perceptron Classification Result')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.legend()
plt.show()
四、实例生动解析
上述代码生成了 100 个随机数据点,标签为 1 或 -1,并通过散点图可视化出来 。
- 蓝色点:代表类别 +1,分布在直线 $x_0 + x_1 = 0$ 的右上方。
- 红色点:代表类别 -1,分布在直线 $x_0 + x_1 = 0$ 的左下方。
- 黑线:感知机学习到的决策边界。随着迭代进行,这条线会不断旋转和平移,直到将红蓝点完全分开 。
关键步骤说明:
- 初始化:权重 $w$ 初始为 0,偏置 $b$ 初始为 0 。
- 误判驱动:只有当 $y_i(w \cdot x_i + b) \leq 0$ 时才更新参数,正确分类的点不参与更新 。
- 几何意义:每次更新都是将超平面向误分类点靠近,使其下次能被正确分类。
五、课后习题与思考
- 基础题:修改代码中的
np.random.seed(0)为其他数字,观察决策边界的变化,理解解的不唯一性 。 - 进阶题:尝试构造一组线性不可分的数据(如异或分布),运行代码,观察模型是否收敛,并记录迭代次数 。
- 思考题:学习率
eta的大小对收敛速度有什么影响?如果eta过大或过小会发生什么现象? - 推导题:手动计算一个简单的二维数据集(如参考代码中的
trainint_set),模拟一次权重更新过程,验证 $w \leftarrow w + \eta y_i x_i$ 公式 。
参考来源
- python 实现感知机_mob64ca12d9e536的技术博客_51CTO博客
- 通俗易懂讲解感知机(二)--学习算法及python代码剖析- 大数跨境
- 感知机理论与实践代码 - FoolishFlyFox - 简书
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)