问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

机器学习入门:K近邻算法(KNN)原理与实践

创作时间:
作者:
@小白创作中心

机器学习入门:K近邻算法(KNN)原理与实践

引用
CSDN
1.
https://blog.csdn.net/qq_35240689/article/details/127083410

KNN(K-Nearest Neighbor)算法是机器学习中一个非常基础且直观的分类算法。它通过测量不同特征值之间的距离来判断各个数据点之间的相似性,从而实现对新数据点的分类。本文将从KNN算法的基本原理出发,详细讲解其工作流程、距离度量方法、数据预处理技巧以及K值选择策略,帮助读者全面理解这一经典算法。

1. 为什么学习KNN算法

KNN是监督学习分类算法,主要解决现实生活中分类问题。根据目标的不同将监督学习任务分为了分类学习及回归预测问题。

KNN(K-Nearest Neihbor,KNN)K近邻是机器学习算法中理论最简单,最好理解的算法,是一个非常适合入门的算法,拥有如下特性:

  • 思想极度简单,应用数学知识少(近乎为零),对于很多不擅长数学的小伙伴十分友好
  • 虽然算法简单,但效果也不错

2. KNN 原理

上图中每一个数据点代表一个肿瘤病历:

  • 横轴表示肿瘤大小,纵轴表示发现时间
  • 恶性肿瘤用蓝色表示,良性肿瘤用红色表示

疑问:新来了一个病人(下图绿色的点),如何判断新来的病人(即绿色点)是良性肿瘤还是恶性肿瘤?

解决方法:k-近邻算法的做法如下:

(1)取一个值k=3(k值后面介绍,现在可以理解为算法的使用者根据经验取的最优值)

(2)在所有的点中找到距离绿色点最近的三个点

(3)让最近的点所属的类别进行投票

(4)最近的三个点都是蓝色的,所以该病人对应的应该也是蓝色,即恶性肿瘤。

3. 距离度量方法

机器学习算法中,经常需要判断两个样本之间是否相似,比如KNN,K-means,推荐算法中的协同过滤等等,常用的套路是将相似的判断转换成距离的计算,距离近的样本相似程度高,距离远的相似程度低。所以度量距离是很多算法中的关键步骤。

KNN算法中要求数据的所有特征都用数值表示。若在数据特征中存在非数值类型,必须采用手段将其进行量化为数值。

  • 比如样本特征中包含有颜色(红、绿、蓝)一项,颜色之间没有距离可言,可通过将颜色转化为灰度值来实现距离计算

  • 每个特征都用数值表示,样本之间就可以计算出彼此的距离来

3.1 欧式距离

3.2 曼哈顿距离

3.3 切比雪夫距离(了解)

3.4 闵式距离

闵氏距离不是一种距离,而是一组距离的定义,是对多个距离度量公式的概括性的表述。

其中p是一个变参数:

  • 当 p=1 时,就是曼哈顿距离;

  • 当 p=2 时,就是欧氏距离;

  • 当 p→∞ 时,就是切比雪夫距离。

根据 p 的不同,闵氏距离可以表示某一类/种的距离。

4. 归一化和标准化

样本中有多个特征,每一个特征都有自己的定义域和取值范围,他们对距离计算也是不同的,如取值较大的影响力会盖过取值较小的参数。因此,为了公平,样本参数必须做一些归一化处理,将不同的特征都缩放到相同的区间或者分布内。

4.1 归一化

from sklearn.preprocessing import MinMaxScaler

# 1. 准备数据
data = [[90, 2, 10, 40],
        [60, 4, 15, 45],
        [75, 3, 13, 46]]

# 2. 初始化归一化对象
transformer = MinMaxScaler()

# 3. 对原始特征进行变换
data = transformer.fit_transform(data)

# 4. 打印归一化后的结果
print(data)

归一化受到最大值与最小值的影响,这种方法容易受到异常数据的影响, 鲁棒性较差,适合传统精确小数据场景

4.2 标准化

from sklearn.preprocessing import StandardScaler

# 1. 准备数据
data = [[90, 2, 10, 40],
        [60, 4, 15, 45],
        [75, 3, 13, 46]]

# 2. 初始化标准化对象
transformer = StandardScaler()

# 3. 对原始特征进行变换
data = transformer.fit_transform(data)

# 4. 打印归一化后的结果
print(data)

对于标准化来说,如果出现异常点,由于具有一定数据量,少量的异常点对于平均值的影响并不大

5. K 值选择问题

KNN算法的关键是什么?

答案一定是K值的选择,下图中K=3,属于红色三角形,K=5属于蓝色的正方形。这个时候就是K选择困难的时候。

使用 scikit-learn 提供的

GridSearchCV

工具, 配合交叉验证法可以搜索参数组合.

from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 加载数据集
iris = load_iris()
X = iris.data
y = iris.target

# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.3, random_state=42)

# 定义KNN分类器
knn = KNeighborsClassifier()

# 定义参数网格
param_grid = {'n_neighbors': range(1, 31)}

# 使用GridSearchCV进行参数搜索
grid_search = GridSearchCV(knn, param_grid, cv=5)
grid_search.fit(X_train, y_train)

# 输出最佳参数
print("Best parameters: ", grid_search.best_params_)

# 使用最佳参数进行预测
best_knn = grid_search.best_estimator_
y_pred = best_knn.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy: ", accuracy)

这段代码展示了如何使用GridSearchCV来自动寻找最佳的K值。通过交叉验证,可以有效地避免过拟合问题,选择出最适合当前数据集的K值。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号