机器学习之用于找到最优K值的K折交叉验证详解(附高阶鸢尾花分类的代码实现)

机器学习14_K折交叉验证(2021.05.27)

机器学习之用于找到最优K值的K折交叉验证详解(附高阶鸢尾花分类的代码实现)_第1张图片

一. 解惑

  • 为什么需要用到K折交叉验证?K值交叉验证的基本思想是什么?
    1.目的:虽然有时候画出了KNN算法的学习曲线,找到了貌似最优的K值,但在使用KNN算法进行模型的训练时,难免会出现由于刚好这组测试集的测试结果良好,而导致的预测或分类结果假好的情况。因此,为了选出最为合适的模型超参数K的取值,从而将该超参数K的值作用到模型的创建中,K折交叉验证就是必须的了。
    2.基本思想:将样本数据中的训练数据交叉地拆分出不同的训练集和测试集,使用交叉拆分出不同的训练集和测试集分别测试模型的精准度,然后求出精准度的均值,就是本次交叉验证的结果。从而将交叉验证的结果作用到不同的超参数中,选取出平均精确度最高的超参数K作为模型的超参数即可。
  • K折交叉验证的实现思路
    1.将数据集中的训练数据平均分割为K个等份
    2.使用其中的1份数据作为测试数据,其余作为训练数据
    3.计算测试准确率
    4.使用不同的测试集,重复2、3步骤
    5.对准确率做平均,作为对未知数据预测准确率的估计
  • K折交叉验证的API:from sklearn.model_selection import cross_val_score(estimator, X, y, cv)
    参数解析:estimator:模型对象 X,y:训练集数据 cv:折数
  • K折交叉验证的其他功能:K折交叉验证同样也可以用来评判模型(预测、分类方法)选择上的好坏。

二. 使用KNN算法并进行K折交叉验证后的鸢尾花分类

(效果提升的对比可参照博主上一篇博文。上一篇博文中博主随机选取了3作为超参数K值,而未进行K折交叉验证,虽然最终的对同一未知分类的鸢尾花进行分类的结果相同,但明显可以看到预测分类结果的评分从0.96666666667提升到了1.0:链接在此)

"""使用交叉验证和学习曲线找到最优的超参数K"""

import sklearn.datasets as datasets  # 导入数据库
from sklearn.neighbors import KNeighborsClassifier  # 导入KNN分类法
from sklearn.model_selection import train_test_split  # 导入数据集划分器
from sklearn.model_selection import cross_val_score  # K折交叉验证
import numpy as np
import matplotlib.pyplot as plt  # 用于绘制学习曲线

# 捕获并提取鸢尾花数据
iris = datasets.load_iris()
feature = iris['data']
target = iris['target']

# 样本数据拆分
x_train, x_test, y_train, y_test = train_test_split(feature, target, test_size=0.2, random_state=2021)

# K折交叉验证与学习曲线的联合使用来获取最优K值
scores_cross = []
Ks = []
for k in range(3, 20):
    knn = KNeighborsClassifier(n_neighbors=k)  # 实例化模型对象
    score_cross = cross_val_score(knn, x_train, y_train, cv=6).mean()  # 根据训练数据进行交叉验证,并返回交叉验证的评分
    scores_cross.append(score_cross)
    Ks.append(k)

# 转为数组类型
scores_arr = np.array(scores_cross)
Ks_arr = np.array(Ks)
# 绘制学习曲线
plt.plot(Ks, scores_cross)
plt.show()

# 获取最高的评分,以及最高评分对应的数组下标,从而获得最优的K值
score_best = scores_arr.max()  # 在存储评分的array中找到最高评分
index_best = scores_arr.argmax()  # 找到array中最高评分所对应的下标
Ks_best = Ks_arr[index_best]  # 根据下标找到最高评分所对应的K值
print(Ks_best)  # 12 

# 将基于K折交叉验证和学习曲线联合使用而找到的最优的K值用来实例化模型对象
knn = KNeighborsClassifier(n_neighbors=Ks_best).fit(x_train, y_train)
# 显示评分
score_test = knn.score(x_test, y_test)
print(score_test)  # 发现评分直接涨到了1.0 而之前的是0.96666666667

# 当出现一个未知分类的鸢尾花时,对其的分类进行预测
test1 = knn.predict([[6.1, 3.1, 4.7, 2.1]])
print(test1)  # 结果为 [2],意味将该鸢尾花分为了第二类

学习曲线如下:
机器学习之用于找到最优K值的K折交叉验证详解(附高阶鸢尾花分类的代码实现)_第2张图片

三. 感悟

  1. 如果单纯地信赖一次随机的样本数据拆分来进行预测或分类模型的创建明显是不可取的,因此K折交叉验证是KNN算法实现过程中不可缺少的一部分。
  2. 如果无法彻底理解K折交叉验证的中心概念的话,只需要记得它其实就相当于是一道用于避免随机状况发生的保险,只要在根据学习曲线选取最优超参数K前加上就可以了。

如有问题,敬请指正。欢迎转载,但请注明出处。

你可能感兴趣的:(机器学习自学整理,机器学习,python)