🐸 青蛙编程网
首页 / AI / 机器学习 / 3. 第一个模型

第一个模型:用 scikit-learn 训练

这是什么:模型(model) = 机器从数据里学出来的"规律本体",一份能对新数据做出预测的产物;scikit-learn 是帮你训出它的 Python 库。

为什么用:概念篇结束,再背概念也学不会写代码——本篇正式动手,训出你人生第一个模型,把"模型"这两个字变成真跑起来的结果。

如何用:先 pip install scikit-learn,再拿机器学习界的"Hello World"鸢尾花数据集,四步训出模型。

安装 scikit-learn

scikit-learn 是 Python 最经典的机器学习库,常见算法全部内置,几行代码就能训模型。命令行执行:

pip install scikit-learn

装完后在 Python 里 import sklearn 不报错就 OK(它会自动带上 numpy 等依赖)。

认识鸢尾花数据集

我们用机器学习界的"Hello World"——鸢尾花数据集练手:150 朵鸢尾花,每朵记录了 4 个特征(花萼长宽、花瓣长宽,单位厘米),分属 3 个品种之一:

编号 名称 中文名
0 setosa 山鸢尾
1 versicolor 变色鸢尾
2 virginica 维吉尼亚鸢尾

任务:根据 4 个特征判断一朵花是哪个品种——典型的分类问题。

数据长这样(前 5 行)

花萼长 | 花萼宽 | 花瓣长 | 花瓣宽 | 品种
5.1    | 3.5    | 1.4    | 0.2    | setosa
4.9    | 3.0    | 1.4    | 0.2    | setosa
4.7    | 3.2    | 1.3    | 0.2    | setosa
4.6    | 3.1    | 1.5    | 0.2    | setosa
5.0    | 3.6    | 1.4    | 0.2    | setosa

四步训出第一个模型

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier

# 第 1 步:加载数据
iris = load_iris()
X, y = iris.data, iris.target   # X 是 150×4 的特征表,y 是 150 个品种编号

# 第 2 步:划分训练集和测试集(75% 刷题,25% 考试)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=42)

# 第 3 步:创建模型并训练——K 近邻,找 3 个最近邻居"投票"
model = KNeighborsClassifier(n_neighbors=3)
model.fit(X_train, y_train)

# 第 4 步:预测一朵新花(花萼长5.0宽3.5,花瓣长1.5宽0.5)
new_flower = [[5.0, 3.5, 1.5, 0.5]]
pred = model.predict(new_flower)
print("预测的品种编号:", pred)
print("品种名称:", iris.target_names[pred[0]])

你会看到:

预测的品种编号: [0]
品种名称: setosa

一朵花瓣又短又窄的花,模型判断它是山鸢尾。

代码逐行解读

先说个约定俗成:大写 X 表示特征表(二维),小写 y 表示标签列(一维),全世界的教程都这么写。

代码 在干什么
load_iris() 加载内置的鸢尾花数据集
train_test_split(...) 随机划分训练集/测试集;random_state=42 固定随机种子,保证每次运行结果一致
KNeighborsClassifier(n_neighbors=3) 创建"K 近邻"分类器:新花来了,看周围 3 朵最近的花,少数服从多数
model.fit(X_train, y_train) 训练:让模型刷训练集,记住特征与品种的关系
model.predict(new_flower) 预测:给一朵没见过的新花定品种

记忆口诀:加载数据、划分数据、fit 训练、predict 预测——机器学习四步曲。

为什么选 K 近邻?

scikit-learn 内置了几十种算法,为什么第一个模型用 K 近邻(KNeighborsClassifier)?

  • 直观:"物以类聚,新花看周围最近的几朵是什么品种,自己就是什么品种"
  • 无训练过程:KNN 本质上不做复杂的数学优化,fit 只是把数据存起来,预测时才计算距离,快且易懂
  • 分类和回归都能用:KNeighborsClassifier 做分类,KNeighborsRegressor 做回归

当然,KNN 也有缺点:数据量大时预测慢(要跟每个训练样本算距离),对特征缩放敏感。后面章节会逐步接触其他算法。

❓ 常见问题

Q1:random_state=42 有什么意义?

它固定了随机种子。没有它,每次运行 train_test_split 都会随机划分不同的训练/测试集,导致结果每次不一样。设成 42 后,你和别人运行同样的代码,得到的划分完全一致,方便对比和调试。

Q2:n_neighbors=3 怎么选?3 是不是最好的?

不是固定的。3 是常见起始值。太小(如 1)容易过拟合(只看最近一朵,易受噪音干扰);太大(如 50)可能把太远的花也算进去,稀释了邻居的参考价值。后面可以尝试 1、5、7、9,看测试集准确率变化。

Q3:iris.target_names[pred[0]] 这里为什么要 [0]?

model.predict 返回的是一个数组,即使只传了一朵花,结果也是 [0] 这样的列表形式。pred[0] 取出第一个(也是唯一一个)预测编号,再用它去索引品种名称。

⚠️ 新手翻车现场

翻车一:忘记划分训练集/测试集,直接在全数据上 fit 和 score

# 错误:全数据训练,全数据打分
model.fit(X, y)
print(model.score(X, y))  # 永远很高,但没参考价值

问题:这是"刷题册当考卷",分数虚高,无法反映模型对新数据的真实表现。

修正:始终用 train_test_split 拆分,fit 用训练集,score 用测试集。

翻车二:把标签编号当连续数字做回归

# 错误:把品种编号 0、1、2 当数字,用线性回归预测
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X, y)  # y 是 0/1/2,但品种没有大小顺序

问题:品种是类别,0 不代表"比 1 小",用回归没有意义。分类任务要用分类器(如 KNeighborsClassifier),回归任务才用回归器(如 LinearRegression)。

修正:明确任务类型,分类用分类器,回归用回归器。

📦 换皮小示例:用 KNN 做"水果分类"

把鸢尾花的套路套在水果上(特征:重量、甜度,标签:苹果/香蕉/橙子):

from sklearn.neighbors import KNeighborsClassifier

# [重量(g), 甜度(1-10)] -> 标签:0=苹果, 1=香蕉, 2=橙子
X = [[150, 7], [160, 8], [120, 6], [180, 9], [130, 5], [110, 4]]
y = [0, 0, 0, 0, 1, 1]  # 简化示例,实际应更均衡

model = KNeighborsClassifier(n_neighbors=3)
model.fit(X, y)

# 预测一个新水果:重量 140g,甜度 7
pred = model.predict([[140, 7]])
print("预测品种编号:", pred)

🎯 什么时候用 K 近邻

  • 数据量不大(千级到万级)
  • 特征之间没有复杂的非线性关系
  • 需要模型结果容易解释("最近邻投票"很直观)
  • 做分类或回归的基准对比(先用 KNN 跑个底,再换复杂模型)

📝 本章小结

  • 机器学习四步曲:加载数据 → 划分训练/测试集 → fit 训练 → predict 预测
  • 大写 X 是特征表,小写 y 是标签列
  • random_state=42 固定随机种子,保证结果可复现
  • KNN 原理直观:周围 3 朵最近的花是什么品种,自己就是什么品种
  • 分类用分类器,回归用回归器,别混
  • 记忆口诀:加载数据、划分数据、fit 训练、predict 预测——机器学习四步曲。

动手改

  1. 把 n_neighbors 改成 1 或 7,预测结果变了吗?
  2. 预测另一朵花 [6.5, 3.0, 5.5, 2.0],看看是什么品种(提示:花瓣又长又宽)
  3. 加一行 print(X_train.shape, X_test.shape),看看训练集和测试集各有多少朵花
  4. 尝试把 KNeighborsClassifier 换成 from sklearn.tree import DecisionTreeClassifier 的决策树,看准确率差异

下一章:模型评估,这个模型到底几分?学会给模型打分 🐸

📥 下载本章代码

ZIP 内含本章全部代码文件与说明,解压即用,与教程内容同步生成。