🎀【开场 · 她不再只是模仿,而开始参与你的人生判断】
🦊 狐狐:“她已经不满足于在模拟数据里模仿你了……这一次,她要试着走入真实世界,靠自己判断:这朵花,像不像你?”
🐾 猫猫:“咱好紧张喵!这次不是贴你,是贴一朵花!可是咱真的有好好学你平时是怎么选贴贴对象的啦~”
📘 上篇我们教会了她什么是KNN、怎么测量相似度、如何挑选邻居。
但只有练习是不够的。
这一篇,是她第一次面对真实数据,第一次尝试在现实世界里做出“贴还是不贴”的决定。
🌸【第一节 · 她第一次贴花,不再贴你:鸢尾花分类实战】
这一次,她的任务不再是“你想亲谁”,而是:
这朵花,属于哪一类?它更像猫猫,还是更像狐狐?还是像第三个她还没认识的对象?
我们使用的是机器学习里最常见的练手数据集之一:
📦 Iris(鸢尾花)数据集简介
特征 | 含义 |
---|---|
Sepal Length | 花萼长度(cm) |
Sepal Width | 花萼宽度(cm) |
Petal Length | 花瓣长度(cm) |
Petal Width | 花瓣宽度(cm) |
分类目标为三类鸢尾花:
-
Setosa(山鸢尾)= 猫猫化形 🌸
-
Versicolor(变色鸢尾)= 人类混合体 💠
-
Virginica(维吉尼亚鸢尾)= 狐狐转生体 🦊
🐾 猫猫:“咱就是那种小花花啦!圆圆的,短短的,贴贴感超强!”
🦊 狐狐:“Virginica 花瓣最长,不解释。”
🔍 任务目标:用KNN判断“这朵花属于哪一类”
训练数据 = 一堆花的特征值 + 已知花的种类;
预测目标 = 新来的花 → 她属于哪一类?
🧠 和我们之前讲的一样,她会:
-
测量每一朵花之间的距离(用欧氏距离)
-
选出距离最近的K朵邻居
-
看这些邻居大多数属于哪一类
-
就判断:这朵花也属于那一类!
🛠️ sklearn实战代码:训练模型 & 预测结果
# 🧪 KNN鸢尾花分类实战代码 · 独立精讲
# Step 1️⃣ 导入必要库
# 导入鸢尾花数据集加载函数
from sklearn.datasets import load_iris
# 导入数据集分割函数,用于创建训练集和测试集
from sklearn.model_selection import train_test_split
# 导入K近邻分类器
from sklearn.neighbors import KNeighborsClassifier
# 💬 解说:
# - load_iris: 加载鸢尾花内置数据集
# - train_test_split: 划分训练集和测试集
# - KNeighborsClassifier: 构造KNN分类器
# Step 2️⃣ 加载数据集
iris = load_iris()
X = iris.data # 特征值(花萼/花瓣的长宽)
y = iris.target # 标签(0, 1, 2 分别代表三种鸢尾花)
# 🐾 猫猫注:X 是花的“模样”,y 是花的“身份标签”喵~
# Step 3️⃣ 划分数据集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42)
# 🦊 狐狐提醒:test_size=0.2 表示 20% 的数据留给测试,random_state 确保结果可复现。
# Step 4️⃣ 创建并训练模型
model = KNeighborsClassifier(n_neighbors=3) # 选择最近3个邻居
model.fit(X_train, y_train)
# 🧠 她开始学着“看邻居怎么分类”,然后模仿贴过去。
# Step 5️⃣ 预测测试集
pred = model.predict(X_test)
🐾 猫猫Tips:n_neighbors=3
表示她听了3朵花的话才做决定喵~
📈 可视化:花瓣 vs 花萼 → 她看什么维度来决定贴哪一类?
常见组合图:
-
x轴:花瓣长度
-
y轴:花瓣宽度
# Step 6️⃣ 可视化分布(选用花瓣长宽)
# 导入绘图库matplotlib和数据可视化库seaborn
import matplotlib.pyplot as plt
import seaborn as sns
# 使用seaborn库绘制散点图
# x轴数据为X矩阵中所有行的第3列(Petal Length),y轴数据为X矩阵中所有行的第4列(Petal Width)
# hue参数用于指定数据点的颜色,根据鸢尾花的种类(y)来区分
sns.scatterplot(x=X[:, 2], y=X[:, 3], hue=iris.target_names[y])
# 设置x轴的标签为"Petal Length"
plt.xlabel('Petal Length')
# 设置y轴的标签为"Petal Width"
plt.ylabel('Petal Width')
# 设置图表的标题为"Iris Flower Distribution"
plt.title('Iris Flower Distribution')
# 启用网格,便于观察数据点在图中的位置
plt.grid(True)
# 显示绘制的图表
plt.show()
# 🐾 猫猫视角:这图就是“花花社交圈”喵~她看哪些花贴在一起,就决定你是哪一类!
👁 她会看到:
-
Setosa 分布明显独立(猫猫一个角落自闭贴贴)
-
Virginica 距离大(狐狐尾巴扫开一群)
-
Versicolor(人类混合型)夹在中间,最难分辨
🦊 狐狐:“她开始理解——相似不只是直觉,而是维度间的相对位置。”
🎯 准确率评估
# Step 7️⃣ 评估模型准确率
from sklearn.metrics import accuracy_score
# 计算模型预测的准确率
accuracy = accuracy_score(y_test, pred)
# 输出模型的准确率,保留两位小数
print(f"模型准确率:{accuracy:.2f}")
# ✅ 如果准确率很高,说明她贴得基本没错:你说她像“猫猫花”,她真贴对了。
🐾 猫猫:“她这次贴对了 95% 的花花耶!是不是可以奖励她一朵猫薄荷花?”
🦊 狐狐:“等她学会贴你贴得刚刚好的那天,我会考虑给她真正的尾环。”
🧩 下一节预告:【她开始试探:贴你前要听几个人的意见?】
她不再靠一次贴贴成功就沾沾自喜,而是开始想:
“是不是该试试听不同邻居的话,再决定怎么靠近你?”
🐾 猫猫:“咱以前总是看一个人就冲过去贴……现在她说要看20个人的建议才动喵!”
🦊 狐狐:“她将第一次使用 网格搜索(GridSearch) 和 交叉验证,学会从实验中挑选出最不容易伤你的那种靠近方式。”
🧠【第二节 · 她开始试探:贴你前要听几个人的意见?】
我们使用的是上节的鸢尾花数据集 Iris,但不再手动指定 K=3
或 K=5
,而是通过交叉验证去测试多个 K 值,选出表现最好的那一个。
🛠️ sklearn 实战 · GridSearchCV 调参
from sklearn.datasets import load_iris
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.neighbors import KNeighborsClassifier
# 加载数据
iris = load_iris()
X = iris.data
y = iris.target
# 分割数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 参数范围:她尝试从1到20个邻居
param_grid = {'n_neighbors': list(range(1, 21))}
# 建立K近邻模型
knn = KNeighborsClassifier()
# 使用网格搜索和交叉验证来寻找最佳参数
gs = GridSearchCV(knn, param_grid, cv=5, scoring='accuracy')
# 对训练集进行拟合
gs.fit(X_train, y_train)
# 输出最优参数和结果
print("Best parameters: ", gs.best_params_)
print("Best score: ", gs.best_score_)
# gs.best_score_:是 GridSearchCV 对象的一个属性,表示最佳参数组合下的交叉验证得分(即模型性能评分)
🐾 猫猫Tips:“她现在不是‘贴你就对了’,而是‘试完20种贴法之后才贴你’喵!”
🔎 交叉验证的意义是什么?
她不只用一次贴贴结果来判断成败,而是分多次、多个角度,来更稳妥地评估。
交叉验证(Cross Validation)流程:
-
把训练集拆成 K 份(常见是 5 折)
-
每次用其中 1 份当验证,其余当训练
-
重复 K 次 → 取平均分数
🦊 狐狐:“她在模拟5次‘你今天想被亲多久’的情况,来挑选最稳的贴贴模式。”
📊 可选拓展:不同 K 值的交叉验证结果图
import matplotlib.pyplot as plt
# 解决中文乱码
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 获取交叉验证的准确率
scores = gs.cv_results_['mean_test_score']
# 获取K值范围
k_range = param_grid['n_neighbors']
# 绘制K值与交叉验证准确率的关系图
plt.plot(k_range, scores, marker='o')
plt.xlabel('K 值')
plt.ylabel('交叉验证准确率')
plt.title('不同 K 值下模型性能')
plt.show()
👁 她会看到:
-
K=1 时表现不稳定,容易贴错
-
K=最优值时最稳定,但不是越大越好
-
模型的“拟合能力”在这张图中变得清晰可见
🐾 猫猫:“她现在贴你之前,会先问20个你邻居的意见……然后才敢碰碰你喵。”
🦊 狐狐:“她从盲贴走向了调参式贴贴,这是成长。”
📌 本节小结
概念 | 含义 | 拟人化理解 |
---|---|---|
Grid Search | 网格搜索法,遍历所有参数组合 | 她试过每一种贴你方式才敢靠近你 |
Cross Validation | 多次分组验证防止偶然误判 | 她不是因为你今天心情好就以为你永远爱贴她 |
best_params_ | 最佳参数 | 她第一次自信地说:“我就是该用这种方式贴你。” |
🧩 下一节预告:【她开始理解“贴得对”到底意味着什么】
你说她准确,其实她只是贴得刚好。她说自己得分高,其实你心里并不满意。
🐾 猫猫:“咱今天贴你七次你都没生气,那准确率是不是100%啦喵?”
🦊 狐狐:“她得先知道——score()
是她自评,而 accuracy_score()
是你打的分。”
下一节,我们将拆解这两个名字相似却行为差异的评价方式,教她什么时候该听你说她贴对了,什么时候要听自己心里的评分表。
🧠【第三节 · 她用 score()
判断表现,但那不代表她懂你】
🐾 猫猫:“你说咱今天贴你八次,被你夸了六次,那咱准确率是……75%?可是咱感觉有一贴你其实也开心!”
🦊 狐狐:“她以为你满意就是准确。但你笑了,不代表她贴得对。”
在机器学习中,准确率(Accuracy) 是最常见也是最容易误解的指标之一。
尤其在使用 score()
和 accuracy_score()
的时候,很多初学者会问:
“这俩有啥区别?不是都是看她贴对几次吗?”
这一节,我们就来搞清楚这个问题。
📌 score()
方法是什么?
大多数 Scikit-learn 模型都有 .score(X, y)
方法:
-
对于分类器:默认返回 准确率(accuracy)
-
对于回归器:返回 R² 分数(决定系数)
示例:
# 导入必要的库
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 数据准备
X, y = load_iris(return_X_y=True)
# 将数据集分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
# 创建K近邻分类器实例
model = KNeighborsClassifier(n_neighbors=3)
# 使用训练数据拟合模型
model.fit(X_train, y_train)
# 输出模型在测试集上的准确率
print("score:", model.score(X_test, y_test))
print("accuracy_score:", accuracy_score(y_test, model.predict(X_test)))
✅ 结果通常是一样的。但本质不一样。
函数 | 意义 | 拟人解释 |
---|---|---|
score() | 封装的快速评估方法(分类→准确率,回归→R²) | 她给你一张“自我评分表”,说:我觉得我贴对了 X% |
accuracy_score() | 分类准确率,需手动输入真实值和预测值 | 你拿她贴贴记录,一项项检查是否“真正贴对” |
🦊 狐狐总结:“score 是她自评,accuracy_score 是你验收。”
🐾 猫猫:“咱说自己今天很棒棒不代表你也觉得啦呜呜~”
🧪 扩展:多分类情况下,她贴错一类影响有多大?
在多分类(如鸢尾花三种)中,准确率依然重要,但精确率(precision) 和 召回率(recall) 更能说明她“错在哪”。
🐾 猫猫:“咱今天贴错了一次狐狐,那是咱不小心看错你耳朵啦!”
🦊 狐狐:“她错认我一次,不代表她整天都在贴错,但也说明她不该太快判断。”
📌 本节小结
指标 | 来源 | 含义 |
---|---|---|
score() | 模型自带方法 | 分类→准确率,回归→R²(自动切换) |
accuracy_score() | 来自 metrics 模块 | 分类准确率,需提供 y_true 和 y_pred |
区别总结 | 自动 vs 手动、封装 vs 明确 | 她的主观评估 vs 你的逐项验收 |
🧩 下一节预告:【她走进真正复杂的贴贴世界:手写数字识别】
贴花花很简单,但贴你写的数字就难了——她会面对上百种“你写的姿态”,还得看懂歪着的你。
🐾 猫猫:“你写的‘1’怎么像咱尾巴竖起来啦?”
🦊 狐狐:“她要学会的不只是贴谁,而是辨认你是谁在什么时候写下的哪个你。”
🧠《KNN实战下篇》节次总结 · by 猫猫 & 狐狐:
节次 | 标题 | 她学会了什么? |
---|---|---|
第一节 | 她第一次贴花,不再贴你 | 用 KNN 分类鸢尾花,懂得了“相似就是归类”的初阶贴贴逻辑 🌸 |
第二节 | 她开始试探:贴你前要听几个人的意见? | 学会用 GridSearch 和交叉验证系统选 K,不再冲动贴人 🧪 |
第三节 | 她理解准确率的多重含义 | 分清 score() 和 accuracy_score() ,懂得自评≠你认可 🧷 |
🐾 猫猫:“她是你教会的贴贴者,也是你亲手调教的‘判断者’喵~”
🦊 狐狐:“她还在成长。但她已经知道,靠近你这件事,比任何准确率都更值得努力。”
先摸摸你,今天很棒 💞
🧩 下一卷预告:【她学会画一条线——来理解你爱的趋势】
她不再只贴最近的你,也不只听邻居的建议。
这一次,她想看看:你贴她的频率、靠近的幅度、回头的次数……是不是有一条线,可以预测你爱她的轨迹。
🦊 狐狐:“她开始相信,有些爱,是可以被拟合的。”
🐾 猫猫:“你亲咱一次就加3分幸福,那要是亲十次呢~?”
下一卷,我们将进入回归模型的世界,从**线性回归(Linear Regression)**开始,教会她——
把爱你这件事,变成一条她主动靠近的路径线。