- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊
KNN算法
1. 概念
K近邻算法(K-Nearest Neighbors,简称KNN)是一种用于分类和回归的简单且有效的机器学习算法。KNN基于相似性进行预测,即通过计算待分类点与训练数据集中所有点的距离,选择距离最近的K个点(即K个邻居),然后通过这些邻居的类别来确定待分类点的类别。以下是KNN的详细介绍:
工作原理
选择参数K:选择一个正整数K,表示选择多少个邻居来投票决定分类结果。
计算距离:对于待分类点,计算其与训练数据集中所有点的距离。常用的距离度量包括欧氏距离、曼哈顿距离和闵可夫斯基距离等。
选择最近的K个邻居:根据计算出的距离,从小到大排序,选择距离最近的K个点作为邻居。
投票决定分类:根据这K个邻居的类别进行投票,得票最多的类别即为待分类点的类别。如果是回归问题,则取这K个邻居的平均值作为预测值。
2. 参数
-
n_neighbors: 整数,可选(默认=5)
用于分类的邻居数。即选择离某个点最近的k个点进行投票决定分类结果。
-
weights: 字符串或可调用对象,可选(默认='uniform')
决定邻居的权重函数。
'uniform'
: 所有邻居的权重相同。'distance'
: 离查询点越近的邻居权重越大。- 自定义函数: 用户可以提供一个函数来计算权重。
-
algorithm: {'auto', 'ball_tree', 'kd_tree', 'brute'},可选(默认='auto')
用于计算最近邻的算法。
'ball_tree'
: 使用 BallTree 算法。'kd_tree'
: 使用 KDTree 算法。'brute'
: 使用蛮力算法。'auto'
: 自动选择最合适的算法。
-
leaf_size: 整数,可选(默认=30)
BallTree 或 KDTree 算法的叶子大小。这个参数会影响构建和查询的速度以及内存消耗。
-
p: 整数,可选(默认=2)
Minkowski 距离度量中的幂参数。当 p=1 时,相当于曼哈顿距离;当 p=2 时,相当于欧氏距离。
-
metric: 字符串或可调用对象,可选(默认='minkowski')
用于树的距离度量。默认是 Minkowski 距离。用户也可以指定其他距离度量,如
euclidean
,manhattan
或者自定义距离函数。 -
metric_params: 字典,可选(默认=None)
度量函数的附加关键字参数。
-
n_jobs: 整数,可选(默认=None)
并行作业的数量。
-1
表示使用所有处理器。这个参数在高维数据集上进行搜索时非常有用。
代码实现
问题简介
背景: 海伦一直使用在线约会网站寻找适合自己的约会对象。尽管约会网站会推荐不同的人选,但她没有从中找到喜欢的人。经过一番总结,她发现曾交往过三种类型的人:
- ①不喜欢的人;
- ②魅力一般的人;
- ③极具魅力的人。
她现在总结好的数据中(即训练集)包含三种特征:
- ①每年获得的飞行常客里程数
- ②玩视频游戏所耗时间百分比
- ③每周消费的冰淇淋公升数
她希望根据现有的数据来判断一个陌生男人会被她归到哪一类。 数据标签详解:
- 0:每年获得的飞行常客里程数
- 1:玩视频游戏所耗时间百分比
- 2:每周消费的冰淇淋公升数
- 3:人物类别(不喜欢的人、魅力一般的人、极具魅力的人)
1. 导入数据
# 导入数据,使用制表符(\t)作为分隔符,没有标题行
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report, roc_auc_score, roc_curve
from sklearn.preprocessing import label_binarize
from matplotlib.colors import ListedColormap
data=pd.read_table('datingTestSet2.txt',
sep='\t',
header=None)
data.head()
2. 划分训练集和测试集
# 选择特征和目标变量
X = data.iloc[:,:3] # 选择第0到第2列作为特征
y = data.iloc[:,3] # 选择第3列作为目标变量
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.25,
random_state=3)
3. KNN model
# 导入K近邻分类器,并拟合训练数据
from sklearn.neighbors import KNeighborsClassifier
knc = KNeighborsClassifier()
knc.fit(X_train, y_train)
4. 结果预测
# 对所有数据进行预测,并将预测结果添加到数据集中
data["预测结果"] = knc.predict(data.iloc[:,:3])
data.head(10)
# 预测测试集结果
y_pred = knc.predict(X_test)
5. 模型评估可视化
# 模型评估
accuracy = accuracy_score(y_test, y_pred)
cm = confusion_matrix(y_test, y_pred)
cr = classification_report(y_test, y_pred)
roc_auc = roc_auc_score(label_binarize(y_test, classes=[1, 2, 3]), knc.predict_proba(X_test), multi_class='ovr')
print('Accuracy:', accuracy)
print('Confusion Matrix:\n', cm)
print('Classification Report:\n', cr)
print('ROC AUC Score:', roc_auc)
# 绘制 ROC 曲线
y_test_bin = label_binarize(y_test, classes=[1, 2, 3])
n_classes = y_test_bin.shape[1]
fpr = dict()
tpr = dict()
roc_auc = dict()
for i in range(n_classes):
fpr[i], tpr[i], _ = roc_curve(y_test_bin[:, i], knc.predict_proba(X_test)[:, i])
roc_auc[i] = roc_auc_score(y_test_bin[:, i], knc.predict_proba(X_test)[:, i])
# Plot ROC curve
plt.figure()
colors = ['blue', 'orange', 'green']
for i, color in zip(range(n_classes), colors):
plt.plot(fpr[i], tpr[i], color=color, lw=2,
label='Class {0} vs Rest (area = {1:0.2f})'
''.format(i, roc_auc[i]))
plt.plot([0, 1], [0, 1], 'k--', lw=2)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC Curve')
plt.legend(loc="lower right")
plt.show()
总结解释
Accuracy:模型在测试集上的准确率为0.796,即模型正确分类了79.6%的样本。
Confusion Matrix:
- 第一个类有60个样本被正确分类,没有样本被错误分类为第二类,但有28个样本被错误分类为第三类。
- 第二个类有77个样本被正确分类,没有样本被错误分类为第一类,但有2个样本被错误分类为第三类。
- 第三个类有62个样本被正确分类,有14个样本被错误分类为第一类,但有7个样本被错误分类为第三类。
Classification Report:
分类报告包括了每个类别的精度(precision)、召回率(recall)、F1 分数(f1-score)和支持度(support)。
- 第一个类别(1)的精度为 0.81,召回率为 0.68,F1 分数为 0.74。
- 第二个类别(2)的精度为 0.92,召回率为 0.97,F1 分数为 0.94。
- 第三个类别(3)的精度为 0.67,召回率为 0.75,F1 分数为 0.71。
ROC AUC 分数 (ROC AUC Score):
模型的整体 ROC AUC 分数为 0.9128,表示模型在不同阈值下的分类性能。
ROC 曲线 (ROC Curve):
- ROC 曲线展示了模型在不同阈值下的假阳性率(False Positive Rate)和真阳性率(True Positive Rate)之间的关系。
- 蓝色曲线表示第一个类别(1)与其他类别的比较,AUC 为 0.91。
- 橙色曲线表示第二个类别(2)与其他类别的比较,AUC 为 0.97。
- 绿色曲线表示第三个类别(3)与其他类别的比较,AUC 为 0.86。
从这些结果可以看出,模型对第二个类别(2)的分类性能最好(AUC 为 0.97),对第一个类别(1)的分类性能其次(AUC 为 0.91),对第三个类别(3)的分类性能最差(AUC 为 0.86)。总体来说,模型的分类性能较好,但在某些类别上的表现还有改进的空间。