目录
2.1 KNN算法概述
2.1.1 基本概念
简单来说,KNN算法是一种基本的分类与回归方法,它的核心思想是通过找出与待分类样本最近的K个训练样本,然后根据这K个样本的类别进行决策。一般流程如下:
(1)收集数据:可以使用任何方法。
(2)准备数据:距离计算所需要的数值,最好是结构化的数据格式。
(3)分析数据:可以使用任何方法。
(4)训练算法:此步骤不适用于KNN算法。
(5)测试算法:计算错误率。
(6)使用算法:首先需要输入样本数据和结构化的输出结果,然后运行KNN算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续的处理。
KNN算法的优缺点有如下:
1. KNN算法的优点:
高精度:在许多情况下,k-近邻算法能够提供较高的分类精度。
对异常值不敏感:由于分类决策是基于多个最近邻样本的投票结果,因此单个异常值对于分类结果的影响较小。
无需数据分布假设:k-近邻算法不需要假设数据的分布情况,适用于各种不同类型的数据集。
2. KNN算法的缺点:
计算复杂度高:对于每个新样本,需要计算其与训练样本集中所有样本之间的距离,因此计算量较大。
空间复杂度高:需要存储整个训练样本集,因此需要较大的内存空间。
2.1.2 准备:使用python导入数据
1.创建名为KNN.py的python模板
2.导入必要的库
3.读取数据文件
4.提取特征和标签
5.划分训练集和测试集
6.数据预处理
2.1.3 实施KNN分类算法
伪代码如下:
(1)计算已知类别数据集中的点与当前点之间的距离;
(2)按照距离递增次序排序;
(3)选取与当前点距离最小的k个点;
(4)确定前k个点所在类别的出现频率;
(5)返回前k个点出现频率最高的类别作为当前点的预测分类。
2.2 KNN中的距离计算
一般使用欧氏距离:d(x, y) = sqrt((x1 - y1)^2 + (x2 - y2)^2 + ... + (xn - yn)^2)
2.3 KNN算法实例
2.3.1收集数据:
2.3.2 准备数据:从文本文件中解析数据
2.3.3 分析数据:使用Matplotlib创建散点图
2.3.4 准备数据:归一化数值
2.3.5 测试算法:作为完整程序验证分类器
2.3.6 使用算法:构建完整可用系统
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置字体为中文黑体
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
# 2.3.1 准备数据:从文本文件中解析数据
data = pd.read_csv('roses_data.csv')
X = data[['花瓣长度', '花瓣宽度']]
y = data['品种']
# 2.3.2 分析数据:使用Matplotlib创建散点图
plt.figure(figsize=(8, 6)) # 设置图形大小
plt.scatter(data['花瓣长度'], data['花瓣宽度'], c=data['品种'].map({'山茶花': 'red', '月季花': 'blue', '玫瑰花': 'green'}))
plt.xlabel('花瓣长度')
plt.ylabel('花瓣宽度')
plt.title('花朵数据集')
# 添加数据标签
for i, row in data.iterrows():
plt.annotate(row['品种'], (row['花瓣长度'], row['花瓣宽度']))
# 设置坐标轴范围
plt.xlim(0, 7) # 设置x轴范围为0到10
plt.ylim(0, 3) # 设置y轴范围为0到6
plt.show()
# 2.3.3 准备数据:归一化数值
scaler = MinMaxScaler()
X_normalized = scaler.fit_transform(X)
# 2.3.4 测试算法:作为完整程序验证分类器
X_train, X_test, y_train, y_test = train_test_split(X_normalized, y, test_size=0.2, random_state=42)
knn = KNeighborsClassifier(n_neighbors=3) # 调整K值为3
knn.fit(X_train, y_train)
y_pred = knn.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print("准确率:", accuracy)
2.3.7结果图呈现
结果分析:
首先,需要从文本文件中解析数据,然后使用Matplotlib创建散点图来分析数据。接下来,再将数据归一化,并将数据集划分为训练集和测试集。最后,使用KNN算法进行训练和预测,并计算准确率。
1.实验对比:
k=3:
k=10:
2.准确率分析:
如果准确率较高,说明KNN算法在这个数据集上表现较好;如果准确率较低,可能需要调整KNN算法的参数或尝试其他分类算法。此外,我们还可以通过观察散点图来了解数据集中不同品种的分布情况,以及花瓣长度和宽度之间的关系。
3.散点图分析:
通过观察散点图,我们可以了解数据集中不同品种的分布情况,以及花瓣长度和宽度之间的关系。散点图中不同颜色的点代表不同的品种,横轴表示花瓣长度,纵轴表示花瓣宽度
2.4 模型评估
2.4.1 常见的分类模型评估指标以及如何计算
-
混淆矩阵:提供了模型预测结果的详细视图,包含真正例(TP)、假负例(FN)、假正例(FP)和真负例(TN)四个元素。其中对于二分类问题,该混淆矩阵如下所示:
预测为正类别 预测为负类别 真实正类别 TP FN 真实负类别 FP TN -
准确率:
- 准确率是分类器正确分类的样本数占总样本数的比例
- 计算公式:准确率 = (TP + TN) / (TP + TN + FP + FN)
-
精确率:
- 精确率是分类器预测为正类别的样本中,真正为正类别的比例
- 计算公式:精确率 = TP / (TP + FP)
-
错误率:
1. 错误率是分类器错误分类的样本数占总样本数的比例
2.计算公式:错误率 = (FP + FN) / (TP + TN + FP + FN) -
召回率:
- 召回率是真实为正类别的样本中,被分类器正确预测为正类别的比例
- 计算公式:召回率 = TP / (TP + FN)
-
F1 值:
- F1 值是精确率和召回率的调和平均数,综合考虑了精确率和召回率。
- 公式:F1 = 2 * (精确率 * 召回率) / (精确率 + 召回率)
- ROC曲线:描绘了不同阈值下的真正例率和假正例率之间的关系。
- AUC:计算ROC曲线下的面积,用来量化地比较不同模型的性能。AUC值越高,说明模型的性能越好。
2.4.2ROC曲线和PR曲线
1.ROC曲线
- 定义:ROC曲线描绘了不同判定阈值下的真正例率(TPR,即召回率)和假正例率(FPR)之间的关系。
- 横轴:假阳率,计算公式为 FPR = FP / (FP + TN),表示被错误分类为正类别的负样本占所有负样本的比例。
- 纵轴:召回率,计算公式为 TPR = TP / (TP + FN),表示正确分类为正类别的正样本占所有正样本的比例。
- 绘制:通过改变分类器的判定阈值,我们可以得到一系列(TPR, FPR)点,连接这些点就形成了ROC曲线。
- 特点:
1.ROC曲线下的面积(即AUC)可以用来衡量模型的整体性能,AUC值越高,模型的性能越好。
2.对于ROC曲线当一个曲线被另一个曲线完全包含了,则后者性能优于前者。
2.PR曲线
- 定义:其中P为精准率,R为召回率,所以P-R曲线是反映了准确率与召回率之间的关系,一般其X轴是召回率,Y轴是精准率
- 横轴:召回率,计算公式为 R= TP / (TP + FN),表示正确分类为正类别的正样本占所有真实正样本的比例。
- 纵轴:精准率,计算公式为 P= TP / (TP + FP),表示被分类为正类别的样本中,真正为正类别的比例。
- 绘制:首先需要将预测结果按照预测为正类的概率值排序,然后逐步降低概率阈值,从1开始逐渐减小,每次计算出当前的精确率值和召回率值,然后再将这些点以精确率为Y轴,召回率为X轴绘制,最后将所有点连成曲线,从而构成PR曲线。
- 特点:
1.曲线越靠近右上方,性能越好
2.当一个曲线被另一个曲线完全包含了,则后者性能优于前者
3.如果曲线发生交叉时,根据曲线下方面积大小判断,面积更大的更优于面积小的
3.两者之间的差异
(1)ROC曲线本质上是正样本或者负样本召回率计算,因此不受样本分布的影响。但是PR曲线由于涉及到精确率计算,故容易受到样本分布的影响。
(2)当正负样本数量很不均衡时,ROC曲线能够稳定地反映模型本身的好坏,但PR曲线的变化却会非常大,故此时用PR曲线更加能反映出分类器性能的好坏。
2.4.3添加了不同k值下的ROC曲线的代码
from sklearn.metrics import roc_curve
from sklearn.metrics import auc
import matplotlib.pyplot as plt
# 不同 k 值下的 ROC 曲线
k_values = [3, 5, 10, 15] # 不同的 k 值
plt.figure(figsize=(8, 6))
# 绘制不同k值下的KNN分类器的ROC曲线
for k in k_values:
knn = KNeighborsClassifier(n_neighbors=k)
knn.fit(X_train, y_train)
y_scores = knn.predict_proba(X_test)
y_scores = y_scores[:, 1] # 取出正例的概率作为预测分数
fpr, tpr, _ = roc_curve(y_test, y_scores, pos_label='玫瑰花')
roc_auc = auc(fpr, tpr)
plt.plot(fpr, tpr, label='k=%d, AUC=%.2f' % (k, roc_auc))
# 使用Matplotlib库绘制了一个ROC曲线
plt.plot([0, 1], [0, 1], color='darkorange', linestyle='--')
plt.xlabel('False Positive Rate') # 设置了x轴的标签为"False Positive Rate"(假阳性率)
plt.ylabel('True Positive Rate') # 设置了y轴的标签为"True Positive Rate"(真阳性率)
plt.title('ROC 曲线')
plt.legend()
plt.show()
1、代码分析:
(1)首先,导入了必要的库和函数:roc_curve
用于计算ROC曲线的FPR和TPR,auc
用于计算曲线下的面积(AUC),matplotlib.pyplot
用于绘图;
(2)然后,定义了一个列表k_values
,其中包含了不同的k值( 3、5、10、15 );
(3)然后,针对每个 K 值,计算对测试集的预测概率,提取正例的概率作为预测分数;
(4)然后,利用 roc_curve 函数计算每个 K 值下的 FPR 和 TPR,并计算 AUC;
(5)最后,绘制 ROC 曲线,展示不同 K 值下的分类器性能,并标注对应的 AUC 值,并且在绘制完所有k值的ROC曲线后,使用plt.plot
函数绘制了一条对角线,表示随机分类器的ROC曲线。
2、关于ROC曲线的运行结果图:
已知曲线下的面积AUC越接近0.5,表示模型的性能越差;AUC越接近1,表示模型的性能越好,故上述ROC曲线分析有:
(1)随着k值的增加,ROC曲线整体上呈现出上升的趋势,意味着随着k值的增加,分类器对于正例的预测能力逐渐增强
(2)k值为3时,AUC值为0.12,这是一个相对较低的值,意味着分类器的性能不佳。
(3) k值为5时,AUC值为0.20,比起k=3较好些,在相同的FPR下有更高的TPR,说明增加了邻居数量后,分类器对正例样本的识别能力有所提高
(4)k值为10时,AUC值为0.20,和k值为5一样,但是此时更多的邻居被考虑在内,有助于更准确地分类样本
(5)k值为15时,AUC值为0.22,是这几条线中最高的,表明分类器的性能最好,这说明了分类器在较大的k值下表现较好,相对而言能够更好地区分正例和负例
2.5总结:
1. KNN算法
KNN算法是一种基于实例的学习算法,它通过计算待分类样本与训练集中的样本之间的距离来确定其类别,在上述代码中我们使用了KNN算法对花朵数据集进行分类。但KNN算法的性能会受到距离度量、邻居数量等因素的影响。因此,在实际应用中,我们需要根据具体情况选择合适的参数,并进行调优。
2.ROC曲线以及模型改进
通过后面ROC曲线图像和描述的分析,我发现该KNN模型存在一些不足之处:其不同k值的AUC值都太低了,该模型没有很好的学习到数据的一些特征,因此,我又重新去修改数据,如下图是修改数据后的ROC曲线图,可以看出相对于前面的ROC曲线图,其AUC值变高了。
图像解释:
(1)当k值=3时,即使AUC值为0.71属于分类器的性能是比较好的,但是当ROC曲线接近于y轴时,会发现此时在较低的FPR值下,TPR值并不高,即真正例率不高而假正例率较高。这会导致很多实际为负例的样本被预测为正例。故说明当k=3时,在这些特定阈值下的性能不是最佳。
(2)当k值=5时,AUC值为0.61,这意味着模型在整个可能的阈值范围内,能够比较好地区分正类和负类。
(3)当k值=10时,AUC值为0.54,这意味着分类器的性能比较差。
(4)当k值=15时,AUC值为0.89,并且在较低的FPR值下就能达到较高的TPR,这代表了模型在这些特定的阈值下就可以具有较好的性能,故在这四个k值中,k=15时分类器性能最佳。
3.内容补充
(修改后的数据集部分截图及其散点图)