别再死记硬背公式了!用Python手写一个感知机,从鸢尾花分类理解AI的‘第一课’
用Python手写感知机从鸢尾花分类看AI如何学会决策当你第一次听说机器学习时脑海中浮现的是不是一堆复杂的数学公式那些Σ、∇符号和矩阵运算确实容易让人望而生畏。但今天我们要打破这个魔咒——用不到100行Python代码亲手实现一个能自动学习分类规则的感知机模型。你会发现AI的第一课其实就像教小朋友区分苹果和橘子一样直观。1. 感知机半个世纪前的AI基石1960年代Frank Rosenblatt发明的感知机Perceptron开启了模式识别的新纪元。这个看似简单的模型蕴含着机器学习最核心的思想通过错误来学习。想象一下教孩子认猫孩子指着狗说猫错误分类你纠正说这是狗调整参数孩子下次更可能正确识别模型收敛感知机的工作方式与此惊人相似。它由三个关键部分组成class Perceptron: def __init__(self): self.weights None # 决策边界的倾斜程度 self.bias 0 # 决策边界的左右偏移 self.lr 0.1 # 学习率犯错后的调整幅度**权重(weights)**就像我们对不同特征的重视程度。在鸢尾花分类中花瓣长度可能比萼片宽度更重要**偏置(bias)**则相当于判断时的宽松程度——好比老师批改试卷时60分及格和70分及格的区别。2. 数据准备鸢尾花的简化世界我们使用经典的鸢尾花数据集但做两个简化处理只保留setosa和versicolor两个品种二分类问题仅使用萼片长度和宽度两个特征方便可视化from sklearn.datasets import load_iris import numpy as np iris load_iris() X iris.data[:100, :2] # 前100个样本取前两个特征 y np.where(iris.target[:100] 0, 1, -1) # 转换为1/-1标签来看看数据的分布情况特征组合Setosa (标签1)Versicolor (标签-1)萼片长度4.3-5.8 cm4.9-7.0 cm萼片宽度2.3-4.4 cm2.0-3.4 cm提示实际项目中应该对特征进行标准化处理但为了教学直观性我们保留原始尺度3. 核心算法错误驱动的学习过程感知机的训练过程就像蒙眼走迷宫每次碰到墙分类错误就调整前进方向。具体实现如下def fit(self, X, y, epochs100): n_samples, n_features X.shape self.weights np.zeros(n_features) for _ in range(epochs): for idx, x_i in enumerate(X): condition y[idx] * (np.dot(x_i, self.weights) self.bias) if condition 0: # 分类错误 update self.lr * y[idx] self.weights update * x_i self.bias update这段代码中藏着两个精妙之处错误判断条件y * (w·x b) ≤ 0正确分类时w·x b与y同号乘积为正错误分类时两者异号乘积为负参数更新规则w w η * y * xη是学习率b b η * y用几何解释错误样本点在决策边界的错误一侧更新规则将其拉向正确方向。例如正样本被误判为负w η * x使得w·x增大负样本被误判为正w - η * x使得w·x减小4. 可视化看决策边界如何进化让我们用matplotlib观察训练过程中决策边界的变化def plot_decision_boundary(model, X, y, epoch): x1_min, x1_max X[:,0].min()-0.5, X[:,0].max()0.5 x2_min, x2_max X[:,1].min()-0.5, X[:,1].max()0.5 xx1, xx2 np.meshgrid(np.linspace(x1_min,x1_max,100), np.linspace(x2_min,x2_max,100)) Z model.predict(np.c_[xx1.ravel(), xx2.ravel()]) Z Z.reshape(xx1.shape) plt.contourf(xx1, xx2, Z, alpha0.3) plt.scatter(X[:,0], X[:,1], cy, edgecolorsk) plt.title(fEpoch {epoch}) plt.xlabel(Sepal length) plt.ylabel(Sepal width)训练过程中的关键阶段初始状态随机权重决策边界混乱准确率约50%中期调整部分样本正确分类边界开始分离两类样本仍有一些顽固的错误点最终收敛所有训练样本正确分类边界处于两类之间的中庸位置注意如果数据不是线性可分的感知机会在两者间反复震荡无法收敛5. 超越基础现代视角下的感知机虽然原始感知机很简单但它启发了现代深度学习的许多概念激活函数感知机的sign函数是阶跃函数现代神经网络使用sigmoid、ReLU等平滑函数损失函数感知机最小化误分类点到超平面的距离现代方法常用交叉熵、MSE等优化算法感知机使用原始梯度下降现代优化器如Adam、RMSprop更高效用PyTorch实现感知机会发现惊人相似import torch class TorchPerceptron(torch.nn.Module): def __init__(self, input_dim): super().__init__() self.linear torch.nn.Linear(input_dim, 1) def forward(self, x): return torch.sign(self.linear(x)).squeeze()关键区别在于自动计算梯度autograd可以使用GPU加速轻松扩展为多层网络6. 实战建议从玩具到真实项目当你在真实数据上应用感知机时记住这些经验特征工程比算法更重要对非线性数据尝试多项式特征from sklearn.preprocessing import PolynomialFeatures poly PolynomialFeatures(degree2) X_poly poly.fit_transform(X)超参数调优学习率太大导致震荡太小收敛慢用网格搜索找最佳组合from sklearn.model_selection import GridSearchCV param_grid {lr: [0.001, 0.01, 0.1, 1]}评估指标选择准确率对平衡数据集有效不平衡数据用F1-score或AUC-ROC扩展到多分类一对多One-vs-Rest策略多类感知机变种在Kaggle的Titanic数据集上即使简单如感知机经过恰当的特征工程也能达到75%的准确率——这已经比随机猜测的50%好很多了。