KNN算法核心原理

机器学习中的k-近邻算法(k-NN)是一种基于实例的监督学习算法,适用于分类和回归任务。其核心思想是通过测量目标数据点与训练集中其他点的距离,找到最近的k个邻居,并根据这些邻居的类别(分类)或平均值(回归)进行预测。

距离度量通常采用欧氏距离或曼哈顿距离:

欧氏距离:点到点之间的直线距离;
曼哈顿距离:是一种在几何度量空间中计算两点之间距离的方法。

KNN算法的实现:


1.加载数据集:使用pandas库读取excel数据。
2.选择模型:选择knn算法。
3.训练模型:使用fit方法进行模型训练。
4.模型测试:使用test方法进行模型测试。
5.模型评估:计算模型的正确率

数据预处理和特征选择
1.读取数据集并进行预处理,将数据集拆分为特征值和标签值。
2.确定特征值和标签值的列索引,并进行数据提取。
3.初始化kneighbors类,并传递特征值和标签值进行模型训练。
模型训练和预测
1.初始化kneighbors类,并传递k值和算法参数进行模型训练。
2.调用fit(X_train, y_train)方法训练模型,并传递特征值和标签值。
3.使用predict(X_new)对新数据预测,传递新的数据点进行分类或回归预测。
支持批量预测,可一次性传入多个样本提高效率。
KNN算法的函数接口
1.kneighbors_classify用于分类任务,计算最近邻的类别并进行预测。
2.kneighbors_regression用于回归任务,计算最近邻的平均值并进行预测

import numpy as np
from sklearn.neighbors import KNeighborsClassifier#从机器学习库中导入knn算法

data = np.loadtxt('datingTestSet2.txt')#使用numpy库读取txt文件
X=data[:,:-1]#获取data数据中的每一行每一列,但是不包含最后一列
y=data[:,-1]#表示获取data数据中的最后一列
neigh = KNeighborsClassifier(n_neighbors=5)#创建模型对象
neigh.fit(X,y)#fit训练

print(neigh.predict([[3656,1.7869,1.5333456]]))#predict表示预测,传入一个新的数据,来看看这个数据是哪个模型的

predict_data=[[10003,11.440364,0.760461],
              [23291,5.102300,0.605619],
              [4277,3.519852,1.058602],
              [37353,2.41595,1.5626]]

print("请再次多人同时预测")
print(neigh.predict(predict_data))

n_neighbors:k值,邻居的个数,默认为5.【关键参数】
weights:权重项,默认uniform方达Uniform:所有最近邻样本的权重都一样。【一般使用这一个】←Distance:权重和此离呈反比,比离越近的样本具有更高的权重。【确认样本分介情况,混乱使用这种形式】←
Callable:用户自定义权示。
algorithm :用于计算最近邻的算法。←
ball tree:球树实现←
kd tree:KD实现,是一种对n维空间中的实例点进行存储以便对其进行快速搜索的义树结构。e
brule:暴力实现eauto:白动选择,权衡上述三种算法。【一般按自动即叫】←eaf size :空值D 树或者球树的参数,停止建子树的叶子节点的阌值。←p:距离的计算力式。P=1为曼哈顿距离,p=2为欧式距离,←

机器学习实例:需要搭建1套智能的寝室分配系统

通过可视化的方式展示了如何在三维空间中应用k-NN算法进行学生性格分类,将爱学习、一般和爱玩的学生分别用不同颜色标记,并解释了如何通过调查问卷和辅导员的专业分析来获取和分类学生数据。最终,通过matplotlib库绘制出三维散点图,直观展示了不同性格学生的聚集效应。

智能寝室分配系统
1.背景:解决大学寝室矛盾,避免性格不同的学生分配在同一寝室。
2.目标:搭建智能寝室分配系统,根据学生性格进行分配。
3.步骤:收集数据、建立模型、训练模型、测试模型

数据集介绍
1.数据集来源:大二、大三、大四学生的调查问卷。
2.数据集内容:每年旅行路程、玩游戏百分比、零食消耗重量、学生类别。
3.数据集格式:四列数据,每列代表不同维度。

1.模型训练与可视化
1.训练模型:使用KNN算法对数据进行分类。
2.可视化:通过matplotlib库将数据展示为三维立体图。
3.结果:不同性格的学生聚集在不同的颜色区域。

import matplotlib.pyplot as plt
import numpy as np

#加载数据
data = np.loadtxt('datingTestSet2.txt')
data_1=data[data[:,-1]==1]#找出类别为1的数据赋值给data_1
a = data[:,-1]#a是最后一列的数据
b = [a==1]#等于1返回True,不等于1返回False
data_2=data[data[:,-1]==2]#找出类别为2的数据赋值给data_2
data_3=data[data[:,-1]==3]#找出类别为3的数据赋值给data_3

#创建画布和3d坐标轴
fig=plt.figure()#创建一个图像对象,默认值为2维 fig:Figure(968*726)
ax = plt.axes(projection="3d")#图像轴位3维   ax:Axes30Subplot(0.125,0.11;0.775*0.77)
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="#FF5511",marker="^")
ax.scatter(data_3[:,0],data_3[:,1],zs=data_3[:,2],c="#000011",marker="+")
ax.set(xlabel="Xaxes",ylabel="Yaxes",zlabel="Zaxes")

# 设置 3D 视角的仰角和方位角
ax.set_ylim(0, 20)
plt.show()#图像显示

调试结果:

运行结果:

2.数据预处理:使用标准化进行特征缩放

为什么要用标准化:旅行路程是几万的量级,而零食重量是零点几的量级。如果直接计算欧式距离,旅行路程的影响会被无限放大,导致模型预测不准确。我们需要对特征进行标准化(Scale)处理,让所有特征都处于同一量级

(1).0-1标准化

将原始数据线性地映射到 [0, 1](或指定的)区间内。

(2).Z标准化

将数据转换为均值为 0,标准差为 1 的分布

  • 如果数据比较“规整”,没有极端异常值,想把数据压缩到 0-1 之间,用 Min-Max
  • 如果数据有异常值,或者分布比较分散,建议用 Z-Score
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import MinMaxScaler, StandardScaler
data = np.loadtxt('datingTestSet2.txt')
X=data[:,:-1]
y=data[:,-1]
# 零一标准化
minmax_scaler = MinMaxScaler()
X_minmax = minmax_scaler.fit_transform(X)

# Z-score标准化
std_scaler = StandardScaler()
X_std = std_scaler.fit_transform(X)

3.数据分割

# 数据分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
  • X: 特征数据矩阵或数组,包含所有样本的特征值
  • y: 目标变量数组,包含与特征数据对应的标签或输出值
  • test_size=0.2: 指定测试集占总数据的比例为20%,剩余80%自动作为训练集
  • random_state=42: 设置随机种子确保每次分割结果相同,便于结果复现

4.模型训练:初始化 KNeighborsClassifier 设置 n_neighbors=5 

knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(X_train_std, y_train)

5.模型评估与测试

train_pred = knn.predict(X_train_std)
test_pred = knn.predict(X_test_std)

print(f"训练集准确率: {accuracy_score(y_train, train_pred):.2f}")
print(f"测试集准确率: {accuracy_score(y_test, test_pred):.2f}")

运行结果:


 

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐