当前位置:   article > 正文

【20210924】【机器/深度学习】以鸢尾花卉数据集为例,使用K折交叉验证选取KNN算法最优的模型参数实例_在鸢尾花分类数据集上寻找最佳的k近邻分类模型超参数,请用留一交叉验证(交叉验证

在鸢尾花分类数据集上寻找最佳的k近邻分类模型超参数,请用留一交叉验证(交叉验证

 一、代码实现

  1. '''
  2. 功能:使用鸢尾花卉数据集和 K 折交叉验证,选取最优的 KNN 算法参数 k
  3. '''
  4. # 导包
  5. from sklearn import datasets
  6. import numpy as np
  7. import pandas as pd
  8. from sklearn import model_selection
  9. from sklearn import neighbors
  10. import math
  11. from sklearn import metrics
  12. import seaborn as sns
  13. import matplotlib.pyplot as plt
  14. plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
  15. plt.rcParams['axes.unicode_minus'] = False
  16. # 使用 k 折交叉验证,选取最优的参数
  17. def choose_bestK(myData, data_train, label_train):
  18. K = np.arange(1, math.floor(math.sqrt(myData.shape[0])))
  19. scores = []
  20. for k in K:
  21. knn = neighbors.KNeighborsClassifier(n_neighbors=k)
  22. scores.append(model_selection.cross_val_score(knn, data_train, label_train, cv=10).mean())
  23. bestK_ind = np.array(scores).argmax() # 最优的 k 参数
  24. # 对不同的 k 值得分可视化
  25. plt.figure()
  26. plt.plot(K, scores)
  27. plt.scatter(K, scores)
  28. plt.text(K[bestK_ind], scores[bestK_ind], '最佳k值为%d' %int(K[bestK_ind]))
  29. # plt.show()
  30. return K, scores, bestK_ind
  31. # 使用最优 k 值进行模型训练及预测,并构建混淆矩阵
  32. def model_train_knn(bestK, x_train, y_train, x_test, y_test):
  33. knn = neighbors.KNeighborsClassifier(n_neighbors=bestK)
  34. knn.fit(x_train, y_train)
  35. y_test_pre = knn.predict(x_test)
  36. # 构建混淆矩阵
  37. tmp = []
  38. for i in range(len(y_test)):
  39. tmp.append(y_test.values[i][0])
  40. tmp = np.array(tmp)
  41. cm = pd.crosstab(y_test_pre, tmp) # pd.crosstab()的输入数据类型应该是 narray!
  42. return cm, y_test_pre
  43. # 构造混淆矩阵热度图
  44. def Confusion_matrix_hp(cm):
  45. # 将混淆矩阵构造成数据框,并加上字段名和行名称,用于行或列的含义说明
  46. cm = pd.DataFrame(cm)
  47. # 绘制热力图
  48. sns.heatmap(cm, annot=True, cmap='GnBu')
  49. plt.xlabel('Real Label')
  50. plt.ylabel('Predict Label')
  51. # plt.show()
  52. # 模型评价和报告输出
  53. def scoreAndReport(y_test, y_test_pre):
  54. y_test_ndarray = y_test.values # dataframe 转成 ndarray
  55. y_test_ndarray = y_test_ndarray.ravel() # 将 ndarray 拉成一维数组
  56. accur = metrics.accuracy_score(y_test_ndarray, y_test_pre)
  57. report = metrics.classification_report(y_test_ndarray, y_test_pre)
  58. # precision = metrics.precision_score(y_test_ndarray, y_test_pre) # 该指标多分类不可用
  59. # recall = metrics.recall_score(y_test_ndarray, y_test_pre) # 该指标多分类不可用
  60. # f1_score = metrics.f1_score(y_test_ndarray, y_test_pre) # 该指标多分类不可用
  61. # AUC = metrics.auc(y_test_ndarray, y_test_pre) # 该指标多分类不可用
  62. # fpr, tpr, thesholds = metrics.roc_curve(y_test_ndarray, y_test_pre) # 该指标多分类不可用
  63. # metrics.auc(fpr, tpr) # 该指标多分类不可用
  64. return accur, report
  65. if __name__ == '__main__':
  66. # 导入数据集
  67. dataset = datasets.load_iris()
  68. feaName = dataset.feature_names # 数据集特征名称 >> ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
  69. tarName = dataset.target_names # 数据集标签名称 >> ['setosa' 'versicolor' 'virginica']
  70. myData = pd.DataFrame(data=dataset.data) # 特征数据
  71. labels = pd.DataFrame(data=dataset.target) # 标签
  72. # 划分训练集和测试集
  73. data_train, data_test, label_train, label_test = model_selection.train_test_split(myData, labels, test_size=0.2)
  74. K, scores, bestK_ind = choose_bestK(myData, data_train, label_train)
  75. bestK = K[bestK_ind] # 最优参数k
  76. cm, label_test_pre = model_train_knn(bestK, data_train, label_train, data_test, label_test)
  77. Confusion_matrix_hp(cm)
  78. score, report = scoreAndReport(label_test, label_test_pre)
  79. print(score, '\n', report)

        (参考:Python 第三方库Knn算法) 

运行结果:

二、知识点

1. numpy 的 argmax 的用法

        argmax 返回的是最大数的索引。argmax 有一个参数 axis,默认为0,表示第几维的最大值。

        (参考:(Python)numpy的argmax用法

2. list 和 ndarray 的相互转化

        (1)list 转 ndarray:b = np.array(a)

        (2)ndarray 转 list:a = b.tolist()

        (参考:Python:list和ndarray的互相转化

3. ravel() 的用法

        功能:将数组维度拉成一维数组

  1. a = [[1], [2], [2], [3]]
  2. b = a.ravel() # 该函数不会修改原始 a 的值,所以需要开辟新内存
  3. print(b)
  4. >> [1, 2, 2, 3]

        metrics.accuracy_score() 的输入需要是 (n_samples, ),否则会报错。

        此时,使用 np.ravel() 函数将数组维度拉成一维,该问题解决。~

        (参考:python中ravel()用法

4. 二分类的评价指标不可直接用于多分类

        二分类常见的评价指标:准确率accuracy,精确的precision,召回率recall,f1-score,ROC曲线,AUC等。(详见:【20210914】【机器/深度学习】模型评价指标:精确率、召回率、特异性、敏感性、F1-score、ROC曲线、AUC

        其中只有准确率accuracy 可用于多分类~其他都会报错!常见的多分类评价指标:宏平均 Macro F1,微平均 Micro F1 等。

        (参考:二分类和多分类的性能评价指标及python计算

        (参考:多分类f1分数_【评价指标】详解F1-score与多分类MacroF1&MicroF1

        (参考:【评价指标】详解F1-score与多分类F1

        (参考:target is multiclass but average='binary'. please choose another average setting.

 5. k 折交叉验证及 sklearn 中 cross_val_score 的使用

        交叉验证可以解决:数据集量不够大的问题、参数调优的问题。

        交叉验证主要有三种方式:简单交叉验证(HoldOut检验)、k折交叉验证(k-fold交叉验证)、自助法。

(1)简单交叉验证(HoldOut检验)

        原理:将原始数据随机划分成训练集和验证集两个部分。

        缺点:数据都只被用了一次,没有被充分利用;在验证集上计算出来的最后的评估指标与原始分组有很大关系。

(2)k-fold交叉验证

        原理:将全部样本划分成 k 个大小相等的样本子集;依次遍历这 k 个子集,每次把当前子集作为验证集,其余所有样本作为训练集,进行模型的训练和评估;最终把 k 次评估指标的平均值作为最终的评估指标。

         (参考:使用sklearn的cross_val_score进行交叉验证

         (参考:交叉验证以及scikit-learn中的cross_val_score详解

        (参考:为什么cross_val_score返回几个分数?

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号