一、感知机模型理论详解

感知机(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$ 的左下方。
  • 黑线:感知机学习到的决策边界。随着迭代进行,这条线会不断旋转和平移,直到将红蓝点完全分开 。

关键步骤说明

  1. 初始化:权重 $w$ 初始为 0,偏置 $b$ 初始为 0 。
  2. 误判驱动:只有当 $y_i(w \cdot x_i + b) \leq 0$ 时才更新参数,正确分类的点不参与更新 。
  3. 几何意义:每次更新都是将超平面向误分类点靠近,使其下次能被正确分类。

五、课后习题与思考

  1. 基础题:修改代码中的 np.random.seed(0) 为其他数字,观察决策边界的变化,理解解的不唯一性 。
  2. 进阶题:尝试构造一组线性不可分的数据(如异或分布),运行代码,观察模型是否收敛,并记录迭代次数 。
  3. 思考题:学习率 eta 的大小对收敛速度有什么影响?如果 eta 过大或过小会发生什么现象?
  4. 推导题:手动计算一个简单的二维数据集(如参考代码中的 trainint_set),模拟一次权重更新过程,验证 $w \leftarrow w + \eta y_i x_i$ 公式 。

参考来源

 

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐