K近邻算法+模型评估

目录

实验一:K近邻算法

一、理论内容:

流程:

数学原理

不同算法之间的联系

优缺点

应用场合

二、算法实例——实现对鸢尾花的分类

代码

分析

三、实验结果分析 

实验二:模型评估

一、理论

 1.常见指标

 2.ROC曲线

 3.PR曲线

 4.ROC曲线和PR曲线的差异

二、代码实现——对鸢尾花分类的模型评估

 1.源码实现

 2.代码分析

三、实验结果分析

1.实验结果

2.实验结果分析 

结论

问题与思考


实验一:K近邻算法

K近邻(K-Nearest Neighbors,KNN)算法是一种基本的分类和回归方法,其核心思想是通过找出与待分类样本最相似的K个训练样本来进行预测。

一、理论内容:

流程:

  1. 输入:

    • 训练集:包含特征向量及其对应的类别标签。
    • 待分类样本:具有特征向量但没有类别标签。
  2. 计算距离:

    • 使用合适的距离度量方法(如欧氏距离、曼哈顿距离等),计算待分类样本与训练集中每个样本的距离。
  3. 确定K值:

    • 选择一个合适的K值,即要考虑多少个最近邻居的信息。
  4. 投票决策:

    • 根据距离最近的K个样本的类别,采用投票法进行分类决策。对于回归问题,可以取K个最近邻居的平均值作为预测结果。

数学原理

  • 距离度量方法: 欧氏距离是常用的距离度量方法,定义为两点之间的直线距离;曼哈顿距离是指两点在坐标系上的绝对轴距总和。

不同算法之间的联系

  • KNN 与 K-means 算法都是基于距离的算法,但 K-means 是一种聚类算法,而 KNN 是一种分类和回归算法。

优缺点

  • 优点:

    • 实现简单,易于理解和实现。
    • 对异常值不敏感,适用于多分类问题。
    • 在数据较为规整的情况下表现良好。
  • 缺点:

    • 需要大量的存储空间来存储训练集。
    • 预测速度较慢,尤其是对于大型数据集。
    • 对于高维数据或特征空间大的数据,效果可能不佳。

应用场合

  • KNN 主要应用于模式识别、图像识别、语音识别等领域,在推荐系统、医学诊断等方面也有广泛应用。

二、算法实例——实现对鸢尾花的分类

  • 代码:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from matplotlib.colors import ListedColormap
#导入iris数据
from sklearn.datasets import load_iris
iris = load_iris()
X=iris.data[:,:2] #只取前两列
y=iris.target

X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y,random_state=42) #划分数据,random_state固定划分方式
#导入模型
from sklearn.neighbors import KNeighborsClassifier
#训练模型
n_neighbors = 5
knn = KNeighborsClassifier(n_neighbors=n_neighbors)
knn.fit(X_train, y_train)
y_pred = knn.predict(X_test)
#查看各项得分
print("y_pred",y_pred)
print("y_test",y_test)
print("score on train set", knn.score(X_train, y_train))
print("score on test set", knn.score(X_test, y_test))
print("accuracy score", accuracy_score(y_test, y_pred))

# 可视化

# 自定义colormap
def colormap():
    return mpl.colors.LinearSegmentedColormap.from_list('cmap', ['#FFC0CB','#00BFFF', '#1E90FF'], 256)

x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
axes=[x_min, x_max, y_min, y_max]
xp=np.linspace(axes[0], axes[1], 500) #均匀500的横坐标
yp=np.linspace(axes[2], axes[3],500) #均匀500个纵坐标
xx, yy=np.meshgrid(xp, yp) #生成500X500网格点
xy=np.c_[xx.ravel(), yy.ravel()] #按行拼接,规范成坐标点的格式
y_pred = knn.predict(xy).reshape(xx.shape) #训练之后平铺

# 可视化方法一
plt.figure(figsize=(15,5),dpi=100)
plt.subplot(1,2,1)
plt.contourf(xx, yy, y_pred, alpha=0.3, cmap=colormap())
#画三种类型的点
p1=plt.scatter(X[y==0,0], X[y==0, 1], color='blue',marker='^')
p2=plt.scatter(X[y==1,0], X[y==1, 1], color='green', marker='o')
p3=plt.scatter(X[y==2,0], X[y==2, 1], color='red',marker='*')
#设置注释
plt.legend([p1, p2, p3], iris['target_names'], loc='upper right',fontsize='large')
#设置标题
plt.title(f"3-Class classification (k = {n_neighbors})", fontdict={'fontsize':15} )

# 可视化方法二
plt.subplot(1,2,2)
cmap_light = ListedColormap(['pink', 'cyan', 'cornflowerblue'])
cmap_bold = ListedColormap(['darkorange', 'c', 'darkblue'])
plt.pcolormesh(xx, yy, y_pred, cmap=cmap_light)

# Plot also the training points
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold,
                edgecolor='k', s=20)
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title(f"3-Class classification (k = {n_neighbors})" ,fontdict={'fontsize':15})
plt.show()
  •  结果

  • 分析

实现了对三种不同鸢尾花的分类,效果较好。且用可视化的效果展示出来。

问题1:numpy版本不匹配
解决思路和过程:

如果代码中使用的numpy函数在你的环境中找不到或者报错,可能是因为你的numpy版本与代码中使用的不兼容。建议更新numpy至最新版本或者根据错误信息调整相应的函数。

问题2:代码报错"ValueError: shapes not aligned"
解决思路和过程:

这个错误通常是由于矩阵形状不匹配引起的。检查涉及矩阵运算的地方,确保矩阵的形状是符合运算规则的。可以通过打印相关矩阵的形状来调试这个问题。

三、实验结果分析 

在本次实验中,对K近邻(K-Nearest Neighbors, KNN)算法进行了性能评估,并观察到以下结果:

1. K值选择
   - 通过交叉验证得出不同K值下的分类准确率,发现随着K值的增大,模型的复杂度降低。但需要注意过大的K值可能导致过拟合,而较小的K值可能导致欠拟合。
   - 我们选择了K=3时获得了相对较好的分类准确率。

2. 泛化能力
   - 通过交叉验证选择最优的K值,提高了模型的泛化能力,使其更好地适应新的数据集。
   - 这表明KNN算法在该数据集上具有较好的泛化性能。

3. 效率问题
   - 需要注意的是,尽管KNN算法在本次实验中表现良好,但在处理大规模数据时可能面临效率问题。这需要在实际应用中加以考虑。

综上所述,KNN算法在本次实验中表现出了较好的分类性能,并且通过交叉验证选择了合适的K值,提高了模型的泛化能力。然而,需注意KNN算法在处理大规模数据时的效率问题。在实际应用中,需要根据具体情况权衡其优缺点并做出合理选择。

实验二:模型评估

一、理论

 1.常见指标

当评估分类模型性能时,常用的指标包括准确率、精确率、召回率、F1分数和混淆矩阵。下面对这些指标进行详细解释:

1.准确率(Accuracy): 准确率是指分类器正确分类的样本数占总样本数的比例。计算公式为:准确率 = (TP + TN) / (TP + TN + FP + FN),其中TP表示真正例(模型将正类别预测为正类别的样本数)、TN表示真负例(模型将负类别预测为负类别的样本数)、FP表示假正例(模型将负类别预测为正类别的样本数)、FN表示假负例(模型将正类别预测为负类别的样本数)。

2.精确率(Precision): 精确率是指分类器预测为正类别的样本中,真正为正类别的比例。计算公式为:精确率 = TP / (TP + FP)。精确率衡量了分类器预测为正类别的准确性

3.召回率(Recall): 召回率是指真正为正类别的样本中,被分类器预测为正类别的比例。计算公式为:召回率 = TP / (TP + FN)。召回率衡量了分类器对正类别的识别能力。

4.F1分数(F1 Score): F1分数是精确率和召回率的调和平均值,综合考虑了分类器的准确性和识别能力。计算公式为:F1 = 2 * (精确率 * 召回率) / (精确率 + 召回率)。

5.混淆矩阵(Confusion Matrix): 混淆矩阵是用于可视化分类模型性能的矩阵,展示了模型预测结果与真实标签之间的对应关系。混淆矩阵包括真正例(TP)、真负例(TN)、假正例(FP)和假负例(FN),帮助我们更直观地了解分类器的表现。 

2.ROC曲线

ROC曲线是一种用于表示分类模型性能的图形工具。它通过将真阳性率(True Positive Rate,TPR)假阳性率(False Positive Rate,FPR)作为横纵坐标来描绘分类器在不同阈值下的性能。

  • 真阳性率 (True Positive Rate, TPR)

真阳性率(True Positive Rate,TPR)通常也被称为敏感性(Sensitivity)或召回率(Recall)。它是指分类器正确识别正例的能力。真阳性率可以理解为所有阳性群体中被检测出来的比率(1-漏诊率),因此TPR越接近1越好。它的计算公式如下:

其中,TP(True Positive)表示正确识别的正例数量,FN(False Negative)表示错误地将正例识别为负例的数量。

  • 假阳性率 (False Positive Rate, FPR)

假阳性率(False Positive Rate,FPR)是指在所有实际为负例的样本中,模型错误地预测为正例的样本比例。假阳性率可以理解为所有阴性群体中被检测出来阳性的比率(误诊率),因此FPR越接近0越好。它的计算公式如下:

其中,FP(False Positive)表示错误地将负例识别为正例的数量,TN(True Negative)表示正确识别的负例数量。

FPR的值等于1-特异性。特异性(Specificity)是指在所有实际为负例的样本中,模型正确地预测为负例的样本比例,其衡量的是模型对负例样本的判断能力。假如一个模型的特异性很高,则该模型在预测负例时的准确率很高,也就是说,该模型较少将负例预测为正例,从而使得假阳性率较低。因此,假阳性率和特异性都是用来衡量模型在负例样本上的性能,它们之间是负相关的,即假阳性率越低,特异性越高,反之亦然。 

3.PR曲线

PR曲线,即精确率-召回率曲线(Precision-Recall Curve),是用于评估分类模型性能的一种工具,尤其在处理不平衡数据集时非常有用。

PR曲线通过绘制精确率(Precision)和召回率(Recall)之间的关系来展示模型的性能。其中,精确率是指被预测为正类的样本中实际为正类的比例,而召回率则是指实际为正类的样本中被正确预测为正类的比例。在二分类问题中,这两个指标通常随着分类阈值的变化而变化,通过改变这个阈值,可以得到不同的精确率和召回率组合,从而形成一条曲线。具体特点如下:

  1. 阈值变化:通过调整分类模型的决策阈值,可以得到不同的精确率和召回率组合,这些组合构成了PR曲线。
  2. 评估模型性能:PR曲线可以帮助我们了解模型在不同阈值下的性能表现,特别是在正负样本数量不平衡的情况下。
  3. 选择合适的阈值:通过观察PR曲线,可以选择一个合理的阈值,使得模型在精确率和召回率达到一个较好的平衡点。
  4. 避免极端情况:在进行PR曲线分析时,需要注意避免出现精确率或召回率为0和1的极端情况,这些情况可能会导致模型性能的误判

4.ROC曲线和PR曲线的差异

ROC曲线和PR曲线的主要差异在于它们各自的适用场景和表示的指标不同

首先,ROC曲线主要用于评估模型的整体性能,而PR曲线则更关注于模型在正类样本上的识别能力。ROC曲线是通过绘制不同分类阈值下的真正例率(TPR)和假正例率(FPR)来表现模型性能的,它假设正负样本的先验概率相等,适用于类别均衡的数据集。相比之下,PR曲线则是通过精确率(Precision)和召回率(Recall)来评估模型,通常用于处理正样本先验概率远大于负样本的不平衡数据集。

其次,ROC曲线和PR曲线在视觉表现上也有所不同。一个好的模型在ROC图上的表现通常是偏向左上角的,而在PR曲线中则是偏向右上角的。这意味着在不同的数据分布和问题背景下,我们应该选择合适的曲线来评估模型性能。

二、代码实现——对鸢尾花分类的模型评估

1.源码实现

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from matplotlib.colors import ListedColormap
#导入iris数据
from sklearn.datasets import load_iris
iris = load_iris()
X=iris.data[:,:2] #只取前两列
y=iris.target

X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y,random_state=42) #划分数据,random_state固定划分方式
#导入模型
from sklearn.neighbors import KNeighborsClassifier
#训练模型
n_neighbors = 5
knn = KNeighborsClassifier(n_neighbors=n_neighbors)
knn.fit(X_train, y_train)
y_pred = knn.predict(X_test)
#查看各项得分
print("y_pred",y_pred)
print("y_test",y_test)
print("score on train set", knn.score(X_train, y_train))
print("score on test set", knn.score(X_test, y_test))
print("accuracy score", accuracy_score(y_test, y_pred))

# 可视化

# 自定义colormap
def colormap():
    return mpl.colors.LinearSegmentedColormap.from_list('cmap', ['#FFC0CB','#00BFFF', '#1E90FF'], 256)

x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
axes=[x_min, x_max, y_min, y_max]
xp=np.linspace(axes[0], axes[1], 500) #均匀500的横坐标
yp=np.linspace(axes[2], axes[3],500) #均匀500个纵坐标
xx, yy=np.meshgrid(xp, yp) #生成500X500网格点
xy=np.c_[xx.ravel(), yy.ravel()] #按行拼接,规范成坐标点的格式
y_pred = knn.predict(xy).reshape(xx.shape) #训练之后平铺

# 可视化方法一
plt.figure(figsize=(15,5),dpi=100)
plt.subplot(1,2,1)
plt.contourf(xx, yy, y_pred, alpha=0.3, cmap=colormap())
#画三种类型的点
p1=plt.scatter(X[y==0,0], X[y==0, 1], color='blue',marker='^')
p2=plt.scatter(X[y==1,0], X[y==1, 1], color='green', marker='o')
p3=plt.scatter(X[y==2,0], X[y==2, 1], color='red',marker='*')
#设置注释
plt.legend([p1, p2, p3], iris['target_names'], loc='upper right',fontsize='large')
#设置标题
plt.title(f"3-Class classification (k = {n_neighbors})", fontdict={'fontsize':15} )

# 可视化方法二
plt.subplot(1,2,2)
cmap_light = ListedColormap(['pink', 'cyan', 'cornflowerblue'])
cmap_bold = ListedColormap(['darkorange', 'c', 'darkblue'])
plt.pcolormesh(xx, yy, y_pred, cmap=cmap_light)

# Plot also the training points
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold,
                edgecolor='k', s=20)
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title(f"3-Class classification (k = {n_neighbors})" ,fontdict={'fontsize':15})
plt.show()


########实验二###########
from sklearn.metrics import precision_score, recall_score, f1_score, roc_curve, auc, precision_recall_curve, roc_auc_score
# 计算精确率、召回率和F1分数
precision = precision_score(y_test, knn.predict(X_test), average='weighted')
recall = recall_score(y_test, knn.predict(X_test), average='weighted')
f1 = f1_score(y_test, knn.predict(X_test), average='weighted')

print("Precision:", precision)
print("Recall:", recall)
print("F1 Score:", f1)

#############不同k值下的ROC曲线###########
from sklearn.preprocessing import label_binarize

k_values = [3, 5, 7]  # 不同的k值
plt.figure(figsize=(8, 6))
y_test_bin = label_binarize(y_test, classes=[0, 1, 2])  # 将多分类标签转换为二进制格式

for k in k_values:
    knn = KNeighborsClassifier(n_neighbors=k)
    knn.fit(X_train, y_train)
    y_proba = knn.predict_proba(X_test)

    fpr = dict()
    tpr = dict()
    roc_auc = dict()

    for i in range(3):  # 有3个类别
        fpr[i], tpr[i], _ = roc_curve(y_test_bin[:, i], y_proba[:, i])
        roc_auc[i] = roc_auc_score(y_test_bin[:, i], y_proba[:, i])

        plt.plot(fpr[i], tpr[i], label='k = %d, class %d (AUC = %0.2f)' % (k, i, roc_auc[i]))

plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC Curve for Different k Values')
plt.legend(loc="lower right")
plt.show()

 2.代码分析

在现有代码的基础上计算常见的分类模型评估指标。

第一部分:计算常见的分类模型评估指标:准确率(Accuracy)、精确率(Precision)、召回率(Recall)、F1分数(F1 Score)和混淆矩阵(Confusion Matrix)。

第二部分: 

 不同k值下的ROC曲线:针对不同的k值(3, 5, 7),计算并绘制了多类别的ROC曲线,用于比较不同k值下模型的性能。

三、实验结果分析

1.实验结果

2.实验结果分析 

  • 结论

在实验二中,计算了模型的精确率、召回率和F1分数,进一步评估了模型的性能。

得到的指标表明模型在多个方面都取得了较好的性能表现。 

针对不同的k值,绘制了多类别的ROC曲线,用于比较不同k值下模型的性能。

通过观察ROC曲线,可以发现在不同k值下,模型的性能有所差异。随着k值的增加,模型的整体性能存在一定的变化,这表明选择合适的k值对模型的性能影响较大。

  • 问题与思考

如何确定最佳的k值?在实际应用中,需要对不同的k值进行交叉验证或者网格搜索,以确定最优的超参数。

对于多分类问题,是否可以尝试其他的分类算法,并与KNN进行比较,以获得更全面的模型评估?

虽然在二维空间下的可视化结果表现良好,但在实际应用中,如何处理高维数据的可视化呈现是一个挑战。

  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值