KNN算法基本原理

KNN算法又称K邻近算法。K近邻算法(K-Nearest Neighbors,简称KNN)是一种用于分类和回归的统计方法。KNN 可以说是最简单的分类算法之一,同时,它也是最常用的分类算法之一。

KNN的基本原理:给定一个已知标签类别的训练数据集,输入没有标签的新数据后,在训练数据集中找到与新数据最邻近的 K 个实例,如果这 K 个实例的多数属于某个类别,那么新数据就属于这个类别。即由那些离新数据最近的 K 个实例来投票决定新数据归为哪一类。

分类模型的性能度量

概述

性能度量是对学习器的泛化性能进行评估,不仅需要有效可行的实验估计方法,还需要有衡量模型泛化能力的评价标准,这就是性能度量。

混淆矩阵

混淆矩阵是一种用于评估分类模型性能的重要工具。它通过矩阵形式清晰地展示了模型对样本进行分类的结果,帮助我们理解模型在不同类别上的表现。

混淆矩阵的基本结构:
在这里插入图片描述

· TP: 模型将实际为正类别的样本正确预测为正类别。
· FN: 模型将实际为正类别的样本错误预测为负类别。
· FP: 模型将实际为负类别的样本错误预测为正类别。
· TN: 模型将实际为负类别的样本正确预测为负类别。
这些元素帮助我们理解模型在分类任务中所做的预测,并将这些预测与实际情况进行对比。

精确率(查准率)

预测结果为正例样本中真实为正例的比例(查得准)
Precision = TP/(TP+FP)
即正确预测的正例数 /预测正例总数

在这里插入图片描述

召回率(查全率)

真实为正例的样本中预测结果为正例的比例(查的全,对正样本的区分能力)
Recall = TP/(TP+FN)
即正确预测的正例数 /实际正例总数

在这里插入图片描述

PR曲线

在很多情形下,我们可根据学习器的预测结果对样例进行排序,排在前面的是学习器认为"最可能"是正例的样本,排在最后的则是学习器认为"最不可能"是正例的样本。按此顺序逐个把样本作为正例进行预测,则每次可以计算出当前的查全率、查准率,以查准率为纵轴、查全率为横轴作图,就得到了查准率-查全率曲线,简称"P-R 曲线"。

在这里插入图片描述
如何通过P-R曲线比较两个机器学习模型的效果:
(1)若一个学习器的P-R 曲线被另一个学习器的曲线完全"包住" , 则可断言后者的性能优于前者, 例如图2.3 中学习器A 的性能优于学习器C;
(2) 如果两个学习器的P-R 曲线发生了交叉, 例如图2.3 中的A 与B,则难以一般性地断言两者的优劣。其中一个的判断依据是,当P=R时成为平衡点(BEP),如果这个值较大,则说明学习器的性能较好。所以 PR 曲线越靠近右上角性能越好。另一个判断依据是,比较P-R曲线下面积的大小,它在一定程度上表征了学习器在查准率和查全率上取得相对"双高"的比例,面积越大性能越好。

ROC曲线

ROC曲线(Receiver Operating Characteristic Curve)是用来评估二分类模型性能的一种常见方法。它是基于分类模型对不同阈值下的预测结果进行排序,并计算真正率(True Positive Rate,即召回率)和假正率(False Positive Rate)之间的关系而得到的曲线。

· 真正率指分类器在所有实际为正例中正确预测为正例的比例,可以通过以下公式计算: 真正率 = TP / (TP + FN)
· 假正率指分类器在所有实际为负例中错误预测为正例的比例,可以通过以下公式计算: 假正率 = FP / (FP + TN)

ROC曲线横轴表示假正率(FPR),纵轴表示真正率(TPR)。分类器在不同阈值下会得到一系列不同的真正率和假正率值,通过将这些值以假正率为横坐标、真正率为纵坐标绘制成曲线,即为ROC曲线。曲线上每个点表示了在对应假正率下的最大真正率值。因此ROC曲线越靠近左上角性能越好。

在这里插入图片描述

如何通过ROC曲线比较两个机器学习模型的效果:
·ROC曲线的面积越大,表示分类模型在FPR和TPR之间有更好的权衡,性能越好。常用的评估指标是ROC曲线下的面积,即ROC AUC(Area Under the ROC Curve),范围在0到1之间,数值越大越好。

代码实战

创建模拟数据集

该数据集调用sklearn库中的make_classification()函数,生成5000个两个特征的二分类样本。

def createData():
    features, actual_labels = make_classification(n_samples=5000, n_classes=2, n_features=2, n_informative=2, n_redundant=0, n_clusters_per_class=1)
    return features, actual_labels
# 生成数据
features, actual_labels = createData()

划分训练集和测试集

按7:3比例随机拆分训练集和测试集

# 划分训练集和测试集
features_train_set, features_test_set, labels_train_set, labels_test_set = train_test_split(features, actual_labels, test_size=0.3, random_state=0)

KNN模型训练

初始化KNN分类器(K=3)并用训练数据拟合模型。

knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(features_train_set, labels_train_set)

模型预测

获取测试样本属于正类的预测概率(predict_proba)

labels_scores = knn.predict_proba(features_test_set)[:, 1]

PR曲线计算与绘制

计算并绘制精确率-召回率曲线,评估类别不平衡时的性能。

# 计算 PR 曲线
precision, recall, _ = precision_recall_curve(labels_test_set, labels_scores)
pr_auc = auc(recall[::-1], precision[::-1])  # 确保 recall 是单调递增的

# 绘制 PR 曲线
plt.figure(figsize=(20, 6))
plt.subplot(1, 2, 1)
plt.plot(recall, precision, label=f'PR curve (AUC = {pr_auc:.2f})')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.title('Precision-Recall Curve')
plt.legend(loc="lower left")

ROC曲线计算与绘制

计算并绘制真/假阳性率曲线,附加对角线作为随机分类基准。

# 计算 ROC 曲线
fpr, tpr, _ = roc_curve(labels_test_set, labels_scores)
roc_auc = auc(fpr, tpr)

# 绘制 ROC 曲线
plt.subplot(1, 2, 2)
plt.plot(fpr, tpr, label=f'ROC curve (AUC = {roc_auc:.2f})')
plt.plot([0, 1], [0, 1], 'k--')  # 对角线参考线
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic (ROC)')
plt.legend(loc="lower right")

显示图片

# 显示图像
plt.show()

总结

全部代码

from sklearn.metrics import auc, precision_recall_curve, roc_curve
from sklearn.datasets import make_classification
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt


def createData():
    features, actual_labels = make_classification(n_samples=5000, n_classes=2, n_features=2, n_informative=2,n_redundant=0, n_clusters_per_class=1)
    return features, actual_labels


# 生成数据
features, actual_labels = createData()

# 划分训练集和测试集
features_train_set, features_test_set, labels_train_set, labels_test_set = train_test_split(features, actual_labels, test_size=0.3, random_state=0)

# 训练 KNN 模型
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(features_train_set, labels_train_set)

# 预测概率
labels_scores = knn.predict_proba(features_test_set)[:, 1]

# 计算 PR 曲线
precision, recall, _ = precision_recall_curve(labels_test_set, labels_scores)
pr_auc = auc(recall[::-1], precision[::-1])  # 确保 recall 是单调递增的

# 计算 ROC 曲线
fpr, tpr, _ = roc_curve(labels_test_set, labels_scores)
roc_auc = auc(fpr, tpr)

# 绘制 PR 曲线
plt.figure(figsize=(20, 6))
plt.subplot(1, 2, 1)
plt.plot(recall, precision, label=f'PR curve (AUC = {pr_auc:.2f})')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.title('Precision-Recall Curve')
plt.legend(loc="lower left")

# 绘制 ROC 曲线
plt.subplot(1, 2, 2)
plt.plot(fpr, tpr, label=f'ROC curve (AUC = {roc_auc:.2f})')
plt.plot([0, 1], [0, 1], 'k--')  # 对角线参考线
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic (ROC)')
plt.legend(loc="lower right")

# 显示图像
plt.show()

运行结果

请添加图片描述

感受

通过PR和ROC两种互补的评估曲线,可以全面了解模型在不同阈值下的表现,AUC值则提供了量化的性能指标。这种评估方式适用于大多数二分类问题,是机器学习中的重要分析方法。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐