【机器学习 KNN算法】代码实现:智能寝室分配 鸢尾花分类
一、机器学习基础概念
定义: 机器学习是利用数学公式总结数据中的规律,以进行预测或决策。
构建机器学习项目通常包含三个步骤:第一步收集数据,第二步建立数学模型并进行训练,第三步使用训练好的模型进行预测。
常用库: 机器学习依赖于numpy(数据处理)、pandas(表格数据)、matplotlib(绘图)和scikit-learn(sklearn,核心机器学习库)等Python库。
机器学习任务类型
回归: 用于预测连续型数值,如房价、股票价格、植物生长量等。
分类: 用于预测离散的类别标签,如人脸识别、邮件是否为垃圾邮件、学生性格类型等。
二、KNN算法详解
基本原理: KNN算法通过寻找与待预测样本距离最近的K个邻居,来确定其属性。若用于回归,则计算K个邻居的属性值的平均数;若用于分类,则统计K个邻居中各类别的数量,数量最多的类别即为预测结果。
关键参数K值的选择至关重要。K值过小会使结果受个别异常点影响较大;K值过大则会使结果趋于整体均值,失去局部特征。K值的选择需根据数据量和具体问题进行调整。
距离计算: 算法依赖于距离度量。最常用的是欧式距离,用于计算N维空间中两点间的距离。此外,还有曼哈顿距离等多种距离计算方式。
1. 欧式距离
欧式距离就是我们直观理解的直线距离,比如平面上两个点之间的直线距离。
在二维空间中,给定点A(x₁,y₁)和点B(x₂,y₂),两点间的欧氏距离计算公式为: d = √[(x₁ - x₂)² + (y₁ - y₂)²]
扩展到三维空间,对于点A(x₁,y₁,z₁)和点B(x₂,y₂,z₂),距离公式变为: d = √[(x₁ - x₂)² + (y₁ - y₂)² + (z₁ - z₂)²]
以此类推,把每个特征的差值平方和再开根号即可。
比如在用户推荐场景中,两个用户的“距离”就是他们在年龄、浏览时长、消费金额三个特征上的欧式距离,距离越小,说明用户行为越相似,KNN算法就可以据此做推荐。
2. 曼哈顿距离
曼哈顿距离也叫城市街区距离,想象在网格状的城市里走路,只能横向或纵向移动,不能斜着走,这段路程就是曼哈顿距离。
二维空间:给定点A(x₁,y₁)和点B(x₂,y₂),其曼哈顿距离计算公式为: d = |x₁ - x₂| + |y₁ - y₂|
该公式可推广至高维空间,即各维度坐标差值的绝对值之和。
举个例子:判断商品相似度,用曼哈顿距离计算价格、销量、评分的差值总和,只做加减运算,计算简单,对异常值不敏感。
3. 两者在KNN中的核心区别
欧式距离:斜着走,平方+开根号,适合低维连续数据,KNN最常用。
曼哈顿距离:横竖走,绝对值相加,适合高维、离散数据。
相同两个样本,曼哈顿距离一定大于等于欧式距离。
三、sklearn库的应用
sklearn是机器学习的第三方库,提供了大量现成的算法实现,可以简化模型的构建和训练过程,避免重复编写复杂的数学公式。
安装库:CMD中输入
pip install scikit-learn
通过查阅其官方文档(API),我们可以找到并使用相应的算法函数

(sklearn.neighbors.KNeighborsClassifier用于分类,sklearn.neighbors.KNeighborsRegressor用于回归)。

四、实战演练
智能寝室分配项目
项目背景: 为降低大学寝室矛盾,提出一个智能寝室分配系统,旨在将性格类型相似的学生分配到同一寝室。
数据收集: 通过设计调查问卷收集学生信息,并将这些信息作为特征(Features),学生最终被归类的结果作为标签(Label)。
特征1:每年旅行的路程
特征2:每天玩游戏的时间占比
特征3:每周消耗的零食重量
标签:1=爱学习 2=一般般 3=喜欢玩
数据流程: 使用大二、大三、大四学生的问卷数据作为历史数据进行模型训练;使用大一新生的问卷数据作为预测数据,输入模型以预测其性格类型,从而实现智能分配。
代码实现:

逐行代码讲解
导入numpy用于读取数据;导入sklearn内置的KNN分类算法,用来根据3个特征判断性格标签。
读取数据集文件,文件里每行=1个人的3个特征 + 1个性格标签。
X:提取全部人的3个特征(旅行路程、游戏占比、零食重量),是模型的输入
Y:提取全部人的标签(1/2/3),是模型要学习的输出结果
初始化KNN模型,K=50:
判断一个人的性格时,找和他特征最像的50个人,少数服从多数:
50人里多数是1 → 预测爱学习;多数是3 → 预测喜欢玩。
neigh.fit(X,Y)
模型训练:把所有人的特征和标签喂给KNN,让模型记住“什么样的特征对应什么性格”。
预测2个人的性格:
第1个人:旅行路程69673、游戏占比14.24、零食0.26
第2个人:旅行路程7917、游戏占比3.01、零食0.29
输出结果:[1/2/3],对应爱学习/一般般/喜欢玩
批量定义5个待预测的人的3个特征
批量输出5个人的性格标签(1/2/3)
输出展示:


这里我们改变n_neighbors(邻居数量)也就是K值(KNN里的K)从10改为了50,可以看到结果发生了改变因为我们这里的测试数据有1000条,K值为10的时候太小过拟合,当改为50时预测效果变准确了


可视化实现:
用3D散点图,把三类人(爱学习/一般般/喜欢玩)的3个特征(旅行路程、游戏占比、零食重量)画出来,直观观察三类人是否能明显分开,验证KNN算法好不好用。

代码讲解:
import matplotlib.pyplot as plt:导入绘图库matplotlib,用来画3D散点图。
把三类人从大表格里,分成3个小表格。
fig=plt.figure():创建一张画布
ax=plt.axes(projection='3d'):创建3D坐标轴(x/y/z三个轴,对应3个特征)
x轴:第0列 → 每年旅行路程
y轴:第1列 → 每天游戏时间占比
z轴:第2列 → 每周零食重量
• marker标记:o圆、^三角、s正方形
• 3D图可以鼠标拖拽旋转,从不同角度观察数据分布
输出展示:

鸢尾花分类项目
根据花的一些特征对其进行三种类型划分
特征1:萼片长
特征2:萼片宽
特征3:花瓣长
特征4:花瓣宽
标签:类型1 类型2 类型3
代码实现:

这个项目我们用来练习标准化处理
读取Excel数据:
import pandas as pd:导入pandas库,专门读取Excel表格,上例用np.loadtxt()读纯文本txt文件;本例用pandas读Excel表格,支持列名、表头,更适合真实业务数据。
KNN用欧式距离计算相似度:
• 萼片长范围:4~7cm,花瓣宽:0.1~2cm,数值大小差距极大
• 不标准化:数值大的特征直接主导距离,KNN预测完全不准
• scale():Z‑score标准化,把所有特征缩放到均值0,方差1,让4个特征权重一样
自测(训练集score) 用训练过的数据去测试,模型见过这些数据,分数很高,就说明模型记住了训练数据。
最终测试(测试集score_test)用完全陌生、模型没见过的数据测试,这个分数才是KNN真实的预测准确率。
输出结果:

更多推荐

所有评论(0)