news 2026/10/19 8:01:52

KNN鸢尾花分类实战:基于Python与Scikit-learn的完整流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
KNN鸢尾花分类实战:基于Python与Scikit-learn的完整流程

看到这个项目名,很多同学应该都会心一笑——基于 Python 3.7 和 Spyder,用 KNN 给鸢尾花数据集做分类。这几乎是我见过出现频率最高的机器学习入门实验,也是很多人第一次从“看教程”变成“跑代码”的一个完整闭环。我前阵子把这个流程从头到尾重跑了一遍,从环境准备、数据加载到模型调参和踩坑都过了一遍,今天整理成这篇分享,给正在准备课程实验、或者想找第一个机器学习项目练手的朋友一个可以直接照着做的参考。

这个项目能解决的问题很实在:让你用最短的路径跑通一个监督学习分类任务。通过它你能理解训练集和测试集为什么要分开,KNN 的 K 值到底怎么选,模型评估除了“准确率”还能看什么,顺便把 Spyder 这个 IDE 的常用操作摸熟。不管你是刚接触机器学习的大二学生,还是想转数据分析的初学者,这套流程都适用。下面我按实际操作的顺序来写,代码都是我实测跑过的版本,环境是 Python 3.7 + Spyder + scikit-learn。

1. 先弄懂 KNN 在干什么,再动键盘

很多教程上来就丢代码,跑通了当然开心,但如果不懂原理,后面标注化和调参就完全靠蒙。我建议先花十分钟把 KNN 的核心逻辑搞清楚,再打开 Spyder。

1.1 KNN 的核心逻辑:物以类聚,少数服从多数

KNN 全称 K-Nearest Neighbors,也就是 K 个最近的邻居。它的思路用一个生活场景就能说清楚:你在一个陌生班级里,想判断新来的同学 A 属于哪个学习小组。做法是看 A 周围最近的几个同学——如果离他最近的 5 个人里,有 4 个来自“数学兴趣小组”,1 个来自“文学社”,那大概率 A 也应归入数学兴趣小组。KNN 干的事就是这个,只是它不掺入人类直觉,全靠距离计算和投票。

这里的“距离”默认是欧氏距离,公式就是初中学过的两点间距离扩展到多维:d = sqrt( (x1 - y1)^2 + (x2 - y2)^2 + ... )。K 值就是“看最近几个邻居”,比如 K=5 就找最近的 5 个样本。邻居们投完票,少数服从多数,票数最高的类别作为预测结果。所以 KNN 一共就三个关键点:距离怎么算、K 取多少、票怎么投。

KNN 还有一个特点在入门时容易忽略——它属于惰性学习算法,或者说“懒学习”。模型的训练阶段几乎不做任何事,只是把训练数据原样保存下来。等到要预测新样本了,才现场算一遍距离,临时去做分类。所以 KNN 的训练时间几乎为零,但预测时如果数据量大、特征多,计算开销会很大。鸢尾花数据集只有 150 条样本 4 个特征,计算负担可以忽略不计,是练习 KNN 的绝佳场地。

1.2 为什么拿鸢尾花数据集来做这个实验

鸢尾花数据集在机器学习界的地位,差不多相当于练习编程时的“Hello World”。它是英国统计学家 R.A. Fisher 在 1936 年整理发布的经典数据,到现在快九十年了,依然是入门分类任务的首选数据集。它包含 150 条样本,均匀分成三个类别:Setosa、Versicolor、Virginica,每个类别 50 条。

每条样本有 4 个特征:花萼长度、花萼宽度、花瓣长度、花瓣宽度,单位都是厘米。这四个特征属于连续型数值,数据非常干净,没有缺失值、没有异常值、类别也完全平衡。这样的数据意味着你在跑模型时基本不用做数据清洗,可以把全部注意力放在算法流程上。

更重要的是,这个数据集存在明显的可分性:Setosa 这一类别在特征空间里和另外两类分得很开,即便只用 KNN 这种简单算法也能拿到很高准确率;Versicolor 和 Virginica 之间有一部分重叠区域,这正好让你有机会观察到误分类现象,从而引出调参、特征选择等更深入的话题。简单说,这个数据集既给了你成就感,也给了你成长空间。

1.3 环境选型的真实理由:Python 3.7 + Spyder + sklearn

项目标题里特意标明了 Python 3.7 和 Spyder,这实际上是很多高校课程里预装好的标准组合。一般同学用的是 Anaconda 发行版,自带 Python、Spyder、Jupyter 和常见的科学计算库,省去了手动配置环境的大量麻烦。

选 Spyder 而不是 Jupyter,我个人的体验是:Spyder 的界面结构很像 MATLAB,左侧代码编辑器、右侧变量查看器、下方 IPython 控制台,写脚本、看变量非常直观。特别是变量查看器,能直接看到 DataFrame 的列名、类型和值,比在终端里输入一堆 print 调试方便得多。Sklearn 是 scikit-learn 的简称,里面封装了 KNN 算法、数据集加载工具、模型评估工具,是 Python 机器学习生态里绕不开的库。

有一点需要提醒:Python 版本本身对 KNN 这个项目影响不大,3.7、3.8、3.9 都能跑。真正影响功能的是 scikit-learn 的版本。早期版本和较新版本在某些函数参数上有调整,比如train_test_split里的stratify参数、KNeighborsClassifier的n_jobs等。本文的代码在 scikit-learn 0.23 到 1.0 之间的版本都测试过,可以放心参考。

2. 环境准备与数据摸底

搞懂了原理,下面进入实操。第一步不是直接写 KNN,而是先确认环境、加载数据、把数据集的结构摸清楚。这个过程花不了五分钟,但对后面的建模非常有帮助。

2.1 环境验证:3 分钟确认你的库都齐了

打开 Spyder,在下方的 IPython 控制台里依次输入下面几行命令,确认依赖库都已安装:

import sys print(sys.version)
import sklearn print(sklearn.__version__)
import pandas as pd import numpy as np import matplotlib.pyplot as plt print("all ok")

如果import sklearn这步报ModuleNotFoundError: No module named 'sklearn',说明 scikit-learn 没有安装。在 Anaconda Prompt 里执行conda install scikit-learn或者pip install scikit-learn就能解决。pandas、numpy、matplotlib 一般 Anaconda 自带,很少缺。

确认完这些库没问题,顺带在 Spyder 里看一眼工作目录。可以用os.getcwd()查看当前路径,把工作目录设置到一个专门存放本次项目的文件夹。养成这个习惯的好处是,你后面如果想把数据导出成 CSV,或者保存模型图片,都方便管理。

2.2 第一次加载数据集:Bunch 对象其实很好懂

scikit-learn 内置了鸢尾花数据集,不需要去网上下载任何文件。加载方式非常简单:

from sklearn.datasets import load_iris iris = load_iris() print(type(iris))

load_iris()返回的是一个 Bunch 对象,你可以把它理解成 Python 里的一个字典,里面装了数据本身和说明信息。它至少包含下面几个属性:

属性名含义对应内容
data特征矩阵150 行 4 列的二维数组
target标签数组150 个整数,0、1、2
target_names标签名字由 setosa 等三个字符串组成的数组
feature_names特征名字四个特征名
DESCR数据集说明一段详细的数据集文档

第一次跑的时候,我强烈建议在 Spyder 的变量查看器里双击iris这个变量,看看里面每一项数据的形状和样子。同时打印一下几个关键属性:

print(iris.feature_names) print(iris.target_names) print(iris.data.shape) print(iris.target[:10])

输出结果里你能看到,数据是 150 行 4 列的浮点数,标签是 0、1、2 三个整数。为什么标签是数字而不是字符串?因为 scikit-learn 里所有算法都要求标签必须是数值型,0、1、2 分别对应 Setosa、Versicolor、Virginica。这是初学者很容易忽略的一点,再强调一下:sklearn 不接受字符串标签直接训练,必须转换成数值。

2.3 用可视化和统计量给数据“拍个照片”

把数据简单整理成 DataFrame,再用统计量和图形对数据建立直觉,这一步虽然不直接产生模型,但非常有价值。我习惯把特征和标签拼起来看:

import pandas as pd df = pd.DataFrame(iris.data, columns=iris.feature_names) df['target'] = iris.target print(df.head()) print(df.describe())

df.describe()可以一次性看到每个特征的均值、标准差、最小值、四分位数等统计量。四列数据的单位都是厘米,量级差别不大,所以暂时不需要做标准化。如果你用的是一个特征单位相差百倍的别的数据集,那分布区间差异会在后续距离计算中造成很大的干扰,这个问题我在第 4 节会详细展开。

接下来画一个散点图矩阵,把所有特征两两组合的分布情况都展示出来。最简单的办法是用 pandas 自带的可视化接口:

from pandas.plotting import scatter_matrix scatter_matrix(df, c=iris.target, figsize=(10, 10), alpha=0.6) plt.show()

运行之后你能直观看到:Setosa(target=0)在绝大多数特征组合下都和其他两类分开;Versicolor(target=1)和 Virginica(target=2)在部分组合下有交叉。看到这个分布,你心里大概就有数了:如果只用花萼宽度这一个特征,区分度很差;如果用花瓣长度和花瓣宽度两个特征,分类效果应该很好。

这一步的最大收获是建立对数据的“预判”。很多同学直接跳过可视化直接建模,遇到准确率不理想时就想换模型,却不知道先看看数据是不是本身存在不可分的问题。数据可视化能帮你区分“模型不行”和“数据本身就这样”。

3. KNN 模型完整实现:从划分到预测

数据和环境都准备好了,开始写模型代码。这一节我会给出完整的流程,每一段代码都配解释,你把它一步步跑通,就已经完成了这个项目的主体工作。

3.1 数据划分的一个关键动作:stratify 分层抽样

训练模型之前,必须先把数据拆成训练集和测试集。原因是:如果拿全部数据既训练又测试,模型相当于“已经看过答案再考试”,成绩虚高,没有参考价值。正确做法是用一部分数据训练,让模型从未见过的另一部分数据上做测试。

scikit-learn 提供了train_test_split方法,一行代码就能完成随机划分:

from sklearn.model_selection import train_test_split X = iris.data y = iris.target X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y )

这里每个参数都值得说清楚。test_size=0.2表示拿 20% 的数据当测试集,也就是 150 条样本中 30 条用于测试、120 条用于训练。

random_state=42是随机种子。不设这个值的话,每次运行都会得到不同的随机划分,实验结果不可复现。设成整数之后,只要代码不变,每次运行训练集测试集都一样。42 这个数字只是约定俗成的习惯值,你用 0、1、2024 都可以。

最关键的是stratify=y这个参数。它表示按 y 的类别比例进行分层抽样。因为原始数据里三个类别各占 1/3,如果不分层,随机划分可能让测试集里某一类很多、另一类很少,导致评估结果不公。分层抽样能保证训练集和测试集中三个类别的比例都接近各占 1/3。这是不少入门教程没讲的细节,但对分类任务非常重要。

划分后可以用打印确认一下:

import numpy as np print(np.bincount(y_train)) print(np.bincount(y_test))

我这次运行时,训练集每个类都是 40 条,测试集每个类都是 10 条,比例完美。

3.2 第一版模型代码,照着写就能跑

划分完数据,KNN 模型的训练和预测代码非常简洁,核心就三步:

from sklearn.neighbors import KNeighborsClassifier knn = KNeighborsClassifier(n_neighbors=5) knn.fit(X_train, y_train) y_pred = knn.predict(X_test)

n_neighbors=5就是 K 值,表示选最近 5 个邻居投票。KNeighborsClassifier 在fit阶段其实没有做什么复杂运算,它只是把训练样本留下来。真正的计算发生在predict的时候,它会逐一计算测试样本和所有训练样本的距离,找到最近的 5 个,统计它们的类别标签,投票决定预测结果。

如果你想知道模型对每个测试样本的“把握程度”,可以调用predict_proba:

print(knn.predict_proba(X_test[:5]))

它返回每个样本归入三个类别的概率。比如某一行输出[0.0, 0.8, 0.2],说明这个样本是 Setosa 的概率为 0,Versicolor 的概率为 0.8,Virginica 的概率为 0.2,最终预测为 Versicolor。这个概率值是“5 个邻居里 4 个是 Versicolor、1 个是 Virginica”的结果,这在模型解释上非常直观。

3.3 第一版模型的评估结果解读

模型预测完了,第一件事就是看准确率:

from sklearn.metrics import accuracy_score acc = accuracy_score(y_test, y_pred) print("准确率:", acc)

我这里跑出来的准确率是 0.9333,也就是 30 条测试样本中 28 条分对了,错了 2 条。这已经是很好的成绩了,因为鸢尾花数据集中后两类存在重叠区域,出现少量误判是合理的。

还可以调用模型自带的score方法,效果和上面完全一样:

print(knn.score(X_test, y_test))

如果你想看哪几条样本被分错了,可以用下面的方式找出来:

import numpy as np misclassified = np.where(y_test != y_pred)[0] print(misclassified)

找到被分错的样本后,对照一下它的真实特征值,你大概率会发现它位于 Iris Versicolor 和 Iris Virginica 的重叠地带。这说明错误并不是模型实现的问题,而是数据本身的类别边界存在重叠。这一点对于理解“准确率不是 100% 不代表代码有问题”非常重要。

第一版模型到这里就跑通了。到此为止,你已经完成了一次完整的机器学习分类项目:数据加载、探索、划分、训练、预测、评估。不过既然是经验分享,我建议你继续看下一节,因为调优部分才是我认为这个项目最有含金量的地方。

4. 调参进阶:寻找最优 K 值和更可靠的评估

第一版模型跑到 93% 准确率,听起来不错,但你不该直接收工。因为 K 值是我随便选的 5,有没有更好的 K 值?单次划分的评估结果是否可靠?每个类别的具体分类表现如何?这些都需要进一步分析。

4.1 交叉验证:让评估结果不再靠运气

刚才我们用 70% 的数据训练、30% 的数据测试,这种做法虽然简单,但结果受划分方案影响很大。如果恰好把某些分界处的样本全部划进测试集,准确率可能掉到 90% 以下;如果恰好避开分界样本,准确率可能高达 97%。单次划分的评估具有随机性,解决办法是交叉验证。

交叉验证的常见做法叫 K-Fold,把数据集分成 K 份,轮流拿其中 1 份当测试集、其余 K-1 份当训练集,一共训练 K 次,最后取 K 次准确率的平均值。这样每个样本都有机会当测试数据,结果更稳定可靠:

from sklearn.model_selection import cross_val_score scores = cross_val_score(knn, X, y, cv=5) print("每次的准确率:", scores) print("平均准确率:", scores.mean()) print("标准差:", scores.std())

注意这里传的是X和y的全量数据,而不是划分好的训练测试集,因为交叉验证自己会负责数据拆分。我实测 5 折交叉验证得到五个准确率,平均在 0.96 左右,标准差 0.04。这个结果比单次划分的 0.9333 更能反映模型的真实水平。

用cv=10就是十折交叉验证,每次 135 条训练、15 条测试,结果更平滑。鸢尾花数据量小,十折计算也很快,我推荐用它。

4.2 找最优 K:从 K 值曲线到网格搜索

K 值是 KNN 最重要的超参数。K 太小,模型容易受单个噪声样本影响,过拟合;K 太大,模型过于“平滑”,可能连类别边界都分不出来了。最科学的办法是画一条 K 值与准确率之间的关系曲线。

我在 1 到 30 的范围内做了十折交叉验证,得到每个 K 值的平均准确率:

k_range = range(1, 31) accs = [] for k in k_range: knn_k = KNeighborsClassifier(n_neighbors=k) score = cross_val_score(knn_k, X, y, cv=10).mean() accs.append(score) import matplotlib.pyplot as plt plt.plot(k_range, accs) plt.xlabel("K value") plt.ylabel("Cross-validation accuracy") plt.show()

从曲线上你能看到一个大致的趋势:K 从 1 开始逐步上升,中间有一段平台期,K 取 6 到 12 左右准确率最高,之后随着 K 继续增大准确率缓慢下滑。这就是典型的“小 K 过拟合、大 K 欠拟合”的体现。

如果你想自动化地把 K 值和距离度量一起调优,可以用GridSearchCV:

from sklearn.model_selection import GridSearchCV from sklearn.neighbors import KNeighborsClassifier param_grid = { 'n_neighbors': range(1, 21), 'weights': ['uniform', 'distance'], 'p': [1, 2] } grid = GridSearchCV(KNeighborsClassifier(), param_grid, cv=10) grid.fit(X, y) print(grid.best_params_) print(grid.best_score_)

weights控制投票方式:uniform表示等权投票,distance表示距离越近权重越高。p控制距离度量方式:p=1 是曼哈顿距离,p=2 是欧氏距离。以我这次运行的结果来看,最优参数大约在n_neighbors=8、weights='uniform'、p=2附近,交叉验证准确率接近 0.98 左右。这说明默认欧氏距离对鸢尾花数据是合适的,等权投票也符合预期。

4.3 混淆矩阵与分类报告:看模型每类都做得怎么样

准确率是一个综合指标,但它掩盖了类别的具体表现。六条 Setosa 全对、而 Virginica 错了两条,和每个类别都错一点,虽然准确率可能相同,但模型质量完全不同。这时候需要用混淆矩阵和分类报告。

from sklearn.metrics import confusion_matrix, classification_report cm = confusion_matrix(y_test, y_pred) print(cm)

混淆矩阵的每一行代表真实类别,每一列代表预测类别。对角线上的数字是分类正确的数量,对角线外的数字是分类错误的数量。我这次测试集里 30 条样本的混淆矩阵大概是这样的:

真实\预测SetosaVersicolorVirginica
Setosa1000
Versicolor091
Virginica019

也就是说 Setosa 全部正确,Versicolor 错了一条,Virginica 也错了一条。这两条错样本恰好把两个类别互相搞混了,说明它们正好位于两个类别的分界区域。

分类报告则提供了更丰富的每个类别指标:

print(classification_report(y_test, y_pred, target_names=iris.target_names))

你会看到三个类别的 precision、recall、f1-score。Precision 是“预测为某类的样本中真正属于该类的比例”,Recall 是“真实属于某类的样本中被预测出来的比例”。多数情况下我们希望这两个指标都高,但它们往往此消彼长,f1-score 是它们的调和平均,用一个数字综合衡量两者。对初学者来说,先学会看 f1-score 就够了:越接近 1 表示该类别的综合表现越好。

4.4 特征标准化:距离算法里的一个必做选择题

前面我说鸢尾花数据集四个特征都是厘米,量级接近,可以不做标准化。但如果换一个特征量级差异很大的数据集,比如一个特征范围是 0 到 1,另一个特征范围是 0 到 10000,KNN 的距离计算就会被取值范围大的特征主导,小范围特征相当于完全失效。解决办法是标准化(StandardScaler),把每个特征变换成均值为 0、标准差为 1 的分布。

from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_scaled = scaler.fit_transform(X)

标准化后,所有特征在距离计算中处于同等的贡献地位。针对鸢尾花数据,标准化前后准确率差别不大,因为原本特征范围就接近,但它是一个你必须知道的坑。以后做任何基于距离的算法(KNN、K-Means、SVM 等),都应该认真考虑特征量级问题。

我建议你在自己的项目里跑通这条流程:先不标准化,记录准确率;再标准化,记录准确率;对比两者差异,把结论写进实验报告。这种“先对比再下结论”的做法,比单纯背结论有价值得多。

5. 实操中的常见报错与排查实录

写代码最怕报错,尤其是一个不认识的报错能卡住你好几个小时。我把常见的高频报错和排查方法整理成了一段实录,希望能帮你快速脱困。

5.1 环境安装类:sklearn 装不上、导入报错的排查

最常见的报错就是第一篇代码里的import sklearn直接失败,提示ModuleNotFoundError。出现这个问题的原因通常有两个:一是根本没有安装 scikit-learn,二是安装了但安装到了另一个 Python 环境。

如果你用的是 Anaconda 默认的 base 环境,执行下面的命令即可:

pip install scikit-learn

或者用 conda:

conda install scikit-learn

第二个原因很隐蔽。有些人电脑上装了多个 Python,比如既有 Anaconda 又有系统自带 Python,还有可能自己配置了虚拟环境。你在 Spyder 里运行的 Python 解释器,可能和命令行里pip指向的解释器不是同一个。排查办法是在 Spyder 的控制台运行下面两行:

import sys print(sys.executable)

它会显示当前解释器的绝对路径。然后在你执行 pip 的终端里也运行一下python -c "import sys; print(sys.executable)",对比两个路径是否一致。不一致的话,要么把 Spyder 的解释器切换到同一个环境,要么在同一个环境里重新安装 sklearn。这一点是新人最常掉进去的坑。

5.2 数据形状类:Expected 2D array 这类高频报错

很多新手在把模型训练好之后,想拿它预测单个样本,于是写了这样的代码:

knn.predict([5.1, 3.5, 1.4, 0.2])

然后报错出来一个ValueError: Expected 2D array, got 1D array instead。这个报错的原因是 sklearn 的所有模型都要求输入是二维结构,行代表样本,列代表特征。一个长度为 4 的一维数组,在模型眼里是“1 行 4 列”还是“4 行 1 列”是模糊的,它默认不是你要的样子。

解决办法是把单条样本变成一个二维数组,用reshape或者嵌套方括号:

sample = [[5.1, 3.5, 1.4, 0.2]] pred = knn.predict(sample) print(iris.target_names[pred[0]])

嵌套方括号是最直观的写法,[[...]]就表示一个只有一行的二维数组。另一个办法是np.array([5.1, 3.5, 1.4, 0.2]).reshape(1, -1)。顺便说一句,这种“新样本”的预测过程很值得在实验报告里展示,因为它才是模型真正落到应用场景中的样子——用过去的数据训练,预测未来的新数据。

5.3 其他高频问题速查表

很多细节问题会反复出现在不同人的电脑上。这里把它们整理成一个速查表,遇到问题的时候直接翻一下:

问题现象原因解决办法
matplotlib 运行后图形不显示Spyder 的绘图面板没有弹出在菜单 Tools -> Preferences -> IPython console -> Graphics 里把 backend 设为 Automatic,或者强制调用plt.show()
图里中文显示成方块matplotlib 默认字体不含中文设置plt.rcParams['font.sans-serif'] = ['SimHei']和plt.rcParams['axes.unicode_minus'] = False
每次运行结果不一样train_test_split没设random_state划分时固定random_state为任意整数
K 值取偶数时模型有点怪可能出现两类票数相同的平票情况体验 KNN 用奇数 K 值,或者用weights='distance'打破平票
使用load_iris()目标出现报错版本兼容问题检查 scikit-learn 版本,升级到稳定版本后重启内核
训练准确率很高、测试准确率低典型的过拟合或 K 值太小增大 K 值、考虑交叉验证重新评估
数据集特征单位差异大、KNN 效果不好距离计算被大量纲特征主导使用StandardScaler做标准化

有一个细节我要特意说出来:Spyder 的绘图面板和 matplotlib 的兼容性偶尔会出现奇怪的问题。如果你画了图但看不到窗口,别急着重装库。先在 Spyder 的设置里把图形后端改成 Automatic,再重启内核,通常就能解决。如果改用plt.show()后图形出现在 IPython 控制台里而不是独立窗口,那也是后端配置的问题,不是代码逻辑错误。

6. 一些个人实操体会与扩展方向

项目跑到这里已经完成度很高了。最后分享一点我的切身体会,以及在这个项目基础上还能继续做些什么。

6.1 我踩过的那几个坑,你这次可以绕开

第一个坑是刚开始我做预测时没有做数据划分,拿着全部 150 条数据训练又拿同一批数据评估,准确率直接 100%,当时还挺高兴,后来才意识到这种评估毫无意义。理解训练集和测试集分离的意义,比跑通代码重要得多,这也是面试时经常被追问的知识点。

第二个坑是手动调 K 值时把 K 调到了 1。K=1 时模型在训练集上的准确率是 100%,但交叉验证的分数并不高,典型的过拟合信号。后来画了 K 值曲线才直观感受到为什么 K 不宜过小。

第三个坑发生在使用GridSearchCV时,我一上来就设置了一个范围很大的参数网格,比如n_neighbors从 1 到 100,p还同时取多个值,导致十折交叉验证组合数量巨大,等了很久才出结果。后来才学会先做小范围搜索,锁定大致区间后再细化。

6.2 从鸢尾花到更多项目:KNN 这个工具箱还能做什么

如果你做完这个项目还有余力,我给出三个顺理成章的扩展方向。

第一个方向是换数据集。scikit-learn 内置了红酒数据集、乳腺癌数据集、手写数字数据集,它们和鸢尾花一样是经典分类任务。尤其是手写数字数据集,有 1797 张 8x8 的数字图片,KNN 在它上面的表现相当不错,你可以顺便感受一下图像特征怎么处理。

第二个方向是换算法类型。KNN 不仅能分类,也能回归,对应KNeighborsRegressor,用于预测房价、温度这类连续数值。鸢尾花数据里有一个特征相关性技巧,比如花瓣宽度对花瓣长度的依赖关系,你可以尝试用 K 近邻回归去预测它们之间的关系。

第三个方向是更深入的可视化,比如把 KNN 的决策边界画出来。取两个特征,在二维平面上生成密集的网格点,每个点都用模型预测类别并涂上颜色,就能直观看到模型把特征空间划分成了什么形状。不同的 K 值画出来的决策边界差别非常明显,K 越小边界越曲折,K 越大边界越平滑。

我个人的看法是,不要急着把这个项目做完就完事,花点时间把 K 值曲线、决策边界、标准化对比这三件事都跑一遍,你对 KNN 的理解会远超只会调用接口的同学。这个实验虽小,但它是理解监督学习分类流程的一个绝佳样例,弄透了再接触复杂模型会轻松很多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 8:01:19

开源OCR项目斩获7.3万Star:技术解析与实战指南

如果你最近在GitHub上关注文字识别方向,应该已经注意到一件事:一个OCR开源项目的Star数量冲到7.3万以上,直接把一众老牌CV项目甩在了身后。这个数字放在图像分类、目标检测这类本身就热门的方向里都算得上现象级,对一个偏工程落地…

作者头像 李华
网站建设 2026/10/19 8:00:39

FPGA串口传输图像至VGA显示:完整数据链路设计与避坑指南

简介:面向FPGA学习者和数字系统设计爱好者的完整工程资源。项目以UART串口接收PC端图片数据、经FPGA内部缓存与处理后输出至VGA显示器为核心,完整覆盖串行通信协议参数设置、RGB三通道图像编码、显存组织方式以及VGA行同步与场同步时序生成等关键知识点&…

作者头像 李华
网站建设 2026/10/19 8:00:07

AI辅助海洋生态监测:从水下图像识别到赤潮预警的落地实践

想着这几年在沿海省份参与过的近海生态监测项目,有一个感受特别深:海洋数据不是缺,而是太多、太乱、太滞后。传感器铺了满海,卫星影像一抓一大把,但负责看数据的人就那么几个,等人工判读跑完一轮&#xff0…

作者头像 李华
网站建设 2026/10/19 7:59:29

基础模型重塑广告竞价环境建模:Bid2X 解读

广告竞价这个领域,真正难的不是“怎么出价”,而是“出价之后到底会发生什么”。KDD25 这篇 Bid2X,标题里最抓人的就是“环境建模”这四个字——它把视角从策略本身拉远到了策略所处的整个动态拍卖市场。基础模型视角的引入,让环境…

作者头像 李华
网站建设 2026/10/19 7:58:59

AI写作救援队:破解写不出与好焦虑的实用方法

我最怕的不是把事情想清楚,而是坐到屏幕前的那一刻——光标一闪一闪,标题和开头之间空得让人心慌。这种状态几乎人人都经历过:明明脑子里有想法,手却打不出一个字;越写不出来就越急,越急就越觉得自己完蛋了…

作者头像 李华
网站建设 2026/10/19 7:58:40

去除文章AI味的实战手册:从识别到智能体落地

1. AI味到底是什么:三个一眼被看穿的毛病先讲一件我自己的事。有次我帮某内容团队审一篇文章,对方编辑说“文章改了六遍,客户还是说看不懂”。我点开文档扫了十秒,就锁定了问题:每一段结尾都有一句升华,每一…

作者头像 李华