5 - L4 机器学习|K-邻近算法模型(KNN)

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 距离。用户也可以指定其他距离度量,如 euclideanmanhattan 或者自定义距离函数。

  • 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)。总体来说,模型的分类性能较好,但在某些类别上的表现还有改进的空间。

  • 13
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值