机器学习K近邻(KNN)算法实战:学生行为分类+鸢尾花花卉分类
·
一、K近邻(KNN)算法原理概述
K近邻属于惰性监督学习分类算法,无显式训练过程,核心逻辑:
- 计算待预测样本与全部训练样本之间的欧式距离;
- 筛选距离最近的K个样本;
- 采用投票机制,K个样本中数量最多的类别作为最终预测结果。
优点:原理简单、极易实现、无需假设数据分布;缺点:海量数据预测速度慢、对特征数值尺度敏感,数值差距大的特征会主导距离计算,因此必须做标准化处理。
本文使用sklearn内置KNeighborsClassifier搭建模型。
二、实战一:基于用户行为的学生优劣分类
2.1 数据集介绍
数据集文件:datingTestSet2.txt
每行共4列数据,前3列为学生行为特征,最后一列为学生类别标签:
特征说明:
- 第1列:学生日常行走里程
- 第2列:每日玩游戏时间占比
- 第3列:每日零食食用克重
标签说明:
- 1 = 爱学习的学生
- 2 = 学习程度一般的学生
- 3 = 贪玩不爱学习的学生
2.2 行为分析
import matplotlib.pyplot as plt
import numpy as np
data=np.loadtxt('datingTestSet2.txt')
data_1=data[data[:,-1]==1]
data_2=data[data[:,-1]==2]
data_3=data[data[:,-1]==3]
fig=plt.figure()
ax=plt.axes(projection='3d')
ax.scatter(data_1[:,0],data_1[:,1],zs=data_1[:,2],c='#00DDAA',marker='o')
ax.scatter(data_2[:,0],data_2[:,1],zs=data_2[:,2],c='#FF0000',marker='^')
ax.scatter(data_3[:,0],data_3[:,1],zs=data_3[:,2],c='#FF0000',marker='v')
ax.set(xlabel='X',ylabel='Y',zlabel='Z')
plt.show()
2.3多个数据预测
import numpy as np
from sklearn.neighbors import KNeighborsClassifier #从机器学习库sklearn中导入knn算法
data=np.loadtxt('datingTestSet2.txt')
x=data[:,:-1]
y=data[:,-1]
neigh=KNeighborsClassifier(n_neighbors=10,weights="distance")
neigh.fit(x,y)
print(neigh.predict([[35083,5.273169,0.508053]]))#35483 12.273169 1.508053 3
predict_data=[[70406,10.196378,0.836326], #70406 11.196378 0.836326 1
[8550,0.000000,0.539131], #11303 0.000000 0.539131 2
[18520,0.791084,0.304072], #18520 3.791084 0.304072 2
[67902,13.649402,10.052618]] #67902 13.649402 1.052618 1
print("再次多人预测")
print(neigh.predict(predict_data))
2.4 代码运行说明
- 数据:数据不可靠,是用来练习的
- 可视化效果:运行代码后弹出3D坐标轴画布,三种颜色标记三类学生,直观观察不同行为学生的分布聚集情况;
- 现有缺陷:本案例未做特征标准化,行走里程数值远大于游戏占比、零食克重,计算距离时会被行走里程单一特征主导,分类存在偏差,下方案鸢尾花案例通过标准化解决该问题。
三、实战二:鸢尾花数据集二分类
3.1 数据集介绍
两份Excel文件:鸢尾花训练数据.xlsx、鸢尾花测试数据.xlsx
特征字段:萼片长(cm)、萼片宽(cm)、花瓣长(cm)、花瓣宽(cm)
标签字段:类型_num,0和1代表两种不同鸢尾花品种
数据集划分逻辑:训练集用于拟合KNN模型,测试集用来验证模型泛化分类能力。
3.2 鸢尾花数据集的训练与测试
import pandas as pd
from sklearn.preprocessing import scale
from sklearn.neighbors import KNeighborsClassifier
#1.读取训练集、测试集Excel表格数据
train_data = pd.read_excel("鸢尾花训练数据.xlsx")
test_data = pd.read_excel("鸢尾花测试数据.xlsx")
#2.拆分训练集特征与标签
train_X = train_data[['萼片长(cm)', '萼片宽(cm)', '花瓣长(cm)', '花瓣宽(cm)']]
train_y = train_data[['类型_num']]
#3.对训练集特征做Z-Score标准化处理
train_std = pd.DataFrame()
train_std['萼片长标准化'] = scale(train_X['萼片长(cm)'])
train_std['萼片宽标准化'] = scale(train_X['萼片宽(cm)'])
train_std['花瓣长标准化'] = scale(train_X['花瓣长(cm)'])
train_std['花瓣宽标准化'] = scale(train_X['花瓣宽(cm)'])
#4.搭建KNN模型,K值设置为2,执行模型训练拟合
knn = KNeighborsClassifier(n_neighbors=2)
knn.fit(train_std, train_y)
#5.训练集内部预测并计算训练集分类准确率
train_predicted = knn.predict(train_std)
train_score = knn.score(train_std, train_y)
print("训练集分类准确率:", train_score)
#6.提取测试集特征与真实标签
test_X = test_data[['萼片长(cm)', '萼片宽(cm)', '花瓣长(cm)']]
test_y = test_data[['类型_num']]
#7.测试集特征标准化
test_std = pd.DataFrame()
test_std['萼片长标准化'] = scale(test_X['萼片长(cm)'])
test_std['萼片宽标准化'] = scale(test_X['萼片宽(cm)'])
test_std['花瓣长标准化'] = scale(test_X['花瓣长(cm)'])
test_std['花瓣宽标准化'] = scale(test_X['花瓣宽(cm)'])
#8.测试集预测并输出测试集准确率
test_predicted = knn.predict(test_std)
test_score = knn.score(test_std, test_y)
print("测试集分类准确率:", test_score)
3.3 关键注意事项
- 标准化作用:消除不同特征数值尺度差距,保证每一项特征在距离计算中权重均等;
- 工程规范:标准工业流程应保存训练集均值、标准差,使用训练集参数转换测试集,本文为简化教学,分别对训练、测试集独立标准化;
- 输入要求:模型预测时必须传入标准化后的特征,直接使用原始未标准化数据会导致预测结果完全失真。
四、整体实验总结
- 学生行为分类项目:实现txt文本数据读取、3D特征可视化、KNN单样本/批量样本预测,直观演示KNN基础使用方法,但未做标准化,存在特征量纲失衡问题;
- 鸢尾花花卉分类项目:针对尺度缺陷引入Z-Score标准化,采用Excel结构化数据集,划分独立训练集与测试集,通过score函数量化模型分类精度,更贴合真实机器学习建模流程;
- KNN算法使用核心要点:
- 特征数值范围差异较大时,必须执行标准化或归一化操作;
- K值超小容易发生过拟合,K值过大容易欠拟合,实际项目需要交叉验证寻找最优K;
- 海量样本场景预测速度慢,更适合中小规模数据集分类任务。
更多推荐



所有评论(0)