一、K近邻(KNN)算法原理概述

K近邻属于惰性监督学习分类算法,无显式训练过程,核心逻辑:

  1. 计算待预测样本与全部训练样本之间的欧式距离;
  2. 筛选距离最近的K个样本;
  3. 采用投票机制,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 代码运行说明

  1. 数据:数据不可靠,是用来练习的
  2. 可视化效果:运行代码后弹出3D坐标轴画布,三种颜色标记三类学生,直观观察不同行为学生的分布聚集情况;
  3. 现有缺陷:本案例未做特征标准化,行走里程数值远大于游戏占比、零食克重,计算距离时会被行走里程单一特征主导,分类存在偏差,下方案鸢尾花案例通过标准化解决该问题。

三、实战二:鸢尾花数据集二分类

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 关键注意事项

  1. 标准化作用:消除不同特征数值尺度差距,保证每一项特征在距离计算中权重均等;
  2. 工程规范:标准工业流程应保存训练集均值、标准差,使用训练集参数转换测试集,本文为简化教学,分别对训练、测试集独立标准化;
  3. 输入要求:模型预测时必须传入标准化后的特征,直接使用原始未标准化数据会导致预测结果完全失真。

四、整体实验总结

  1. 学生行为分类项目:实现txt文本数据读取、3D特征可视化、KNN单样本/批量样本预测,直观演示KNN基础使用方法,但未做标准化,存在特征量纲失衡问题;
  2. 鸢尾花花卉分类项目:针对尺度缺陷引入Z-Score标准化,采用Excel结构化数据集,划分独立训练集与测试集,通过score函数量化模型分类精度,更贴合真实机器学习建模流程;
  3. KNN算法使用核心要点
    1. 特征数值范围差异较大时,必须执行标准化或归一化操作;
    2. K值超小容易发生过拟合,K值过大容易欠拟合,实际项目需要交叉验证寻找最优K;
    3. 海量样本场景预测速度慢,更适合中小规模数据集分类任务。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐