赞
踩
- '''
- 功能:使用鸢尾花卉数据集和 K 折交叉验证,选取最优的 KNN 算法参数 k
- '''
-
-
- # 导包
- from sklearn import datasets
- import numpy as np
- import pandas as pd
- from sklearn import model_selection
- from sklearn import neighbors
- import math
- from sklearn import metrics
- import seaborn as sns
- import matplotlib.pyplot as plt
- plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
- plt.rcParams['axes.unicode_minus'] = False
-
-
-
- # 使用 k 折交叉验证,选取最优的参数
- def choose_bestK(myData, data_train, label_train):
- K = np.arange(1, math.floor(math.sqrt(myData.shape[0])))
- scores = []
- for k in K:
- knn = neighbors.KNeighborsClassifier(n_neighbors=k)
- scores.append(model_selection.cross_val_score(knn, data_train, label_train, cv=10).mean())
-
- bestK_ind = np.array(scores).argmax() # 最优的 k 参数
-
- # 对不同的 k 值得分可视化
- plt.figure()
- plt.plot(K, scores)
- plt.scatter(K, scores)
- plt.text(K[bestK_ind], scores[bestK_ind], '最佳k值为%d' %int(K[bestK_ind]))
- # plt.show()
-
- return K, scores, bestK_ind
-
-
- # 使用最优 k 值进行模型训练及预测,并构建混淆矩阵
- def model_train_knn(bestK, x_train, y_train, x_test, y_test):
- knn = neighbors.KNeighborsClassifier(n_neighbors=bestK)
- knn.fit(x_train, y_train)
- y_test_pre = knn.predict(x_test)
-
- # 构建混淆矩阵
- tmp = []
- for i in range(len(y_test)):
- tmp.append(y_test.values[i][0])
- tmp = np.array(tmp)
- cm = pd.crosstab(y_test_pre, tmp) # pd.crosstab()的输入数据类型应该是 narray!
-
- return cm, y_test_pre
-
-
- # 构造混淆矩阵热度图
- def Confusion_matrix_hp(cm):
- # 将混淆矩阵构造成数据框,并加上字段名和行名称,用于行或列的含义说明
- cm = pd.DataFrame(cm)
-
- # 绘制热力图
- sns.heatmap(cm, annot=True, cmap='GnBu')
-
- plt.xlabel('Real Label')
- plt.ylabel('Predict Label')
- # plt.show()
-
-
- # 模型评价和报告输出
- def scoreAndReport(y_test, y_test_pre):
- y_test_ndarray = y_test.values # dataframe 转成 ndarray
- y_test_ndarray = y_test_ndarray.ravel() # 将 ndarray 拉成一维数组
-
- accur = metrics.accuracy_score(y_test_ndarray, y_test_pre)
- report = metrics.classification_report(y_test_ndarray, y_test_pre)
-
- # precision = metrics.precision_score(y_test_ndarray, y_test_pre) # 该指标多分类不可用
- # recall = metrics.recall_score(y_test_ndarray, y_test_pre) # 该指标多分类不可用
- # f1_score = metrics.f1_score(y_test_ndarray, y_test_pre) # 该指标多分类不可用
- # AUC = metrics.auc(y_test_ndarray, y_test_pre) # 该指标多分类不可用
- # fpr, tpr, thesholds = metrics.roc_curve(y_test_ndarray, y_test_pre) # 该指标多分类不可用
- # metrics.auc(fpr, tpr) # 该指标多分类不可用
-
- return accur, report
-
-
-
- if __name__ == '__main__':
- # 导入数据集
- dataset = datasets.load_iris()
- feaName = dataset.feature_names # 数据集特征名称 >> ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
- tarName = dataset.target_names # 数据集标签名称 >> ['setosa' 'versicolor' 'virginica']
-
- myData = pd.DataFrame(data=dataset.data) # 特征数据
- labels = pd.DataFrame(data=dataset.target) # 标签
-
- # 划分训练集和测试集
- data_train, data_test, label_train, label_test = model_selection.train_test_split(myData, labels, test_size=0.2)
-
- K, scores, bestK_ind = choose_bestK(myData, data_train, label_train)
- bestK = K[bestK_ind] # 最优参数k
-
- cm, label_test_pre = model_train_knn(bestK, data_train, label_train, data_test, label_test)
-
- Confusion_matrix_hp(cm)
-
- score, report = scoreAndReport(label_test, label_test_pre)
- print(score, '\n', report)
(参考:Python 第三方库Knn算法)
运行结果:
argmax 返回的是最大数的索引。argmax 有一个参数 axis,默认为0,表示第几维的最大值。
(1)list 转 ndarray:b = np.array(a)
(2)ndarray 转 list:a = b.tolist()
功能:将数组维度拉成一维数组
- a = [[1], [2], [2], [3]]
- b = a.ravel() # 该函数不会修改原始 a 的值,所以需要开辟新内存
- print(b)
-
- >> [1, 2, 2, 3]
metrics.accuracy_score() 的输入需要是 (n_samples, ),否则会报错。
此时,使用 np.ravel() 函数将数组维度拉成一维,该问题解决。~
(参考:python中ravel()用法)
二分类常见的评价指标:准确率accuracy,精确的precision,召回率recall,f1-score,ROC曲线,AUC等。(详见:【20210914】【机器/深度学习】模型评价指标:精确率、召回率、特异性、敏感性、F1-score、ROC曲线、AUC)
其中只有准确率accuracy 可用于多分类~其他都会报错!常见的多分类评价指标:宏平均 Macro F1,微平均 Micro F1 等。
(参考:多分类f1分数_【评价指标】详解F1-score与多分类MacroF1&MicroF1)
(参考:target is multiclass but average='binary'. please choose another average setting.)
交叉验证可以解决:数据集量不够大的问题、参数调优的问题。
交叉验证主要有三种方式:简单交叉验证(HoldOut检验)、k折交叉验证(k-fold交叉验证)、自助法。
(1)简单交叉验证(HoldOut检验)
原理:将原始数据随机划分成训练集和验证集两个部分。
缺点:数据都只被用了一次,没有被充分利用;在验证集上计算出来的最后的评估指标与原始分组有很大关系。
(2)k-fold交叉验证
原理:将全部样本划分成 k 个大小相等的样本子集;依次遍历这 k 个子集,每次把当前子集作为验证集,其余所有样本作为训练集,进行模型的训练和评估;最终把 k 次评估指标的平均值作为最终的评估指标。
(参考:使用sklearn的cross_val_score进行交叉验证)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。