2-04-模型选择与调优

导入

在KNN算法中,k值的选择对我们最终的预测结果有着很大的影响

那么有没有好的方法能够帮助我们选择好的k值呢?

模型选择与调优

学习目标

在这里插入图片描述

内容预览:

  • 什么是交叉验证(cross validation)
  • 超参数搜索-网格搜索(Grid Search)
  • 鸢尾花案例增加k值调优
  • 案例:预测FaceBook签到位置
  • 总结

什么是交叉验证(cross validation)

交叉验证的定义

将拿到的训练数据,分为训练和验证集,以下图为例:将数据分成4份,其中一份作为验证集,然后经过4次(组)的测试,每次都更换不同的验证集,即得到4组模型的结果,取平均值作为最终结果。由于是将数据分为4份,所以我们称之为4折交叉验证。

在这里插入图片描述

分析

在这里插入图片描述

充分利用已有的数据,对当前的数据进行训练、验证,目的就是为了使预测结果更加可靠,成功率更高。

为什么需要交叉验证?

交叉验证目的:为了让被评估的模型更加准确可信

思考

这个只是对于参数得出更好的结果,那么我们应该如何选择或者调优参数呢?

超参数搜索-网格搜索(Grid Search)

如何选择合适的k值?

我们可以采用穷举法,即事先准备一些k值,比如说

k=[1,2,3,4,5,6]

然后将这几个k值一个一个代入到我们的代码中,检测一下哪个k值才是最合适的

类似于暴力破解一样,遍历,一个一个试

什么是超参数搜索-网格搜索(Grid Search)?

在这里插入图片描述

模型选择与调优API

在这里插入图片描述
在这里插入图片描述

鸢尾花案例增加k值调优

# -*- coding: utf-8 -*-

"""
@Time    : 2021/3/16 18:34
@Author  : yuhui
@Email   : 3476237164@qq.com
@FileName: 2_04_模型选择与调优.py
@Software: PyCharm
"""
from sklearn.datasets import load_iris  # 获取鸢尾花数据
from sklearn.model_selection import train_test_split  # 划分数据集
from sklearn.preprocessing import StandardScaler  # 标准化
from sklearn.neighbors import KNeighborsClassifier  # KNN算法预估器
from sklearn.model_selection import GridSearchCV  # 网格搜索和交叉验证

def knn_iris_GridSearchCV():
	"""用KNN算法对鸢尾花进行分类,添加网格搜索和交叉验证"""
	# 获取数据
	iris = load_iris()

	# 划分数据集
	x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22)
	# 特征工程:标准化
	transfer = StandardScaler()
	x_train = transfer.fit_transform(x_train)  # 对训练集进行标准化
	# 训练集做了标准化,测试集也需要做标准化
	# 训练集做了什么工作,测试集也应该做同样的工作
	x_test = transfer.transform(x_test)  # 注意:是transform而不是fit_transform
	# 也就是说:使用的是训练集的平均值和标准差
	# 目的是为了和训练集保持一致

	# KNN算法评估器
	estimator = KNeighborsClassifier()
	estimator.fit(x_train, y_train)
	# 已经建立好了模型

	# 添加网格搜索和交叉验证
	# 参数准备
	param_dict={"n_neighbors": [1, 3, 5, 7, 9, 11]}
	estimator = GridSearchCV(estimator, param_grid=param_dict, cv=10)
	estimator.fit(x_train, y_train)

	# 模型评估
	# 方法1:直接比对真实值和预测值
	y_predict = estimator.predict(x_test)
	print("y_predict:\n", y_predict)
	print("直接比对真实值和预测值:\n", y_test == y_predict)

	# 方法2:计算准确率
	score = estimator.score(x_test, y_test)
	print("准确率为:\n", score)

	# 最佳参数:best_params_
	print("最佳参数:\n", estimator.best_params_)
	# 最佳结果:best_score_
	print("最佳结果:\n", estimator.best_score_)
	# 最佳估计器:best_estimator_
	print("最佳估计器:\n", estimator.best_estimator_)
	# 交叉验证结果:cv_results_
	print("交叉验证结果:\n", estimator.cv_results_)

if __name__ == '__main__':
    knn_iris_GridSearchCV()
D:\Anaconda3\Installation\envs\math\python.exe D:/Machine_Learning/Machine_Learning_1/code/2_04_模型选择与调优.py
y_predict:
 [0 2 1 2 1 1 1 2 1 0 2 1 2 2 0 2 1 1 1 1 0 2 0 1 2 0 2 2 2 2 0 0 1 1 1 0 0
 0]
直接比对真实值和预测值:
 [ True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True  True  True  True False  True  True  True  True  True
  True  True  True  True  True  True  True  True  True  True  True  True
  True  True]
准确率为:
 0.9736842105263158
最佳参数:
 {'n_neighbors': 3}
最佳结果:
 0.9553030303030303
最佳估计器:
 KNeighborsClassifier(n_neighbors=3)
交叉验证结果:
 {'mean_fit_time': array([0.00049872, 0.00069816, 0.00069818, 0.00059848, 0.0004988 ,
       0.00055275]), 'std_fit_time': array([0.00049872, 0.00045705, 0.00045707, 0.00048866, 0.0004988 ,
       0.00047017]), 'mean_score_time': array([0.00149605, 0.00149603, 0.00109696, 0.00129654, 0.00149589,
       0.00149271]), 'std_score_time': array([0.0009196 , 0.00049877, 0.00029922, 0.00045741, 0.00066914,
       0.00050213]), 'param_n_neighbors': masked_array(data=[1, 3, 5, 7, 9, 11],
             mask=[False, False, False, False, False, False],
       fill_value='?',
            dtype=object), 'params': [{'n_neighbors': 1}, {'n_neighbors': 3}, {'n_neighbors': 5}, {'n_neighbors': 7}, {'n_neighbors': 9}, {'n_neighbors': 11}], 'split0_test_score': array([0.91666667, 0.91666667, 1.        , 1.        , 0.91666667,
       0.91666667]), 'split1_test_score': array([1., 1., 1., 1., 1., 1.]), 'split2_test_score': array([0.90909091, 0.90909091, 0.90909091, 0.90909091, 0.90909091,
       0.90909091]), 'split3_test_score': array([0.90909091, 1.        , 0.90909091, 0.90909091, 0.90909091,
       1.        ]), 'split4_test_score': array([1., 1., 1., 1., 1., 1.]), 'split5_test_score': array([0.90909091, 0.90909091, 0.90909091, 0.90909091, 0.90909091,
       0.90909091]), 'split6_test_score': array([0.90909091, 0.90909091, 0.90909091, 1.        , 1.        ,
       1.        ]), 'split7_test_score': array([0.90909091, 0.90909091, 0.81818182, 0.81818182, 0.81818182,
       0.81818182]), 'split8_test_score': array([1., 1., 1., 1., 1., 1.]), 'split9_test_score': array([1., 1., 1., 1., 1., 1.]), 'mean_test_score': array([0.94621212, 0.95530303, 0.94545455, 0.95454545, 0.94621212,
       0.95530303]), 'std_test_score': array([0.04397204, 0.0447483 , 0.06030227, 0.06098367, 0.05988683,
       0.0604591 ]), 'rank_test_score': array([4, 1, 6, 3, 4, 1])}

Process finished with exit code 0

在这里插入图片描述

补充

在KNN算法中,我们常用的距离有:

  • 曼哈顿距离
  • 欧式距离
  • 明可夫斯基距离

那么我们在代码中,是如何体现我们使用的是哪种距离的呢?

在这里插入图片描述

打开之后就是下面的这个样子的

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值