在KNN算法中,k值的选择对我们最终的预测结果有着很大的影响
那么有没有好的方法能够帮助我们选择好的k值呢?
模型选择与调优
内容预览:
将拿到的训练数据,分为训练和验证集,以下图为例:将数据分成4份,其中一份作为验证集,然后经过4次(组)的测试,每次都更换不同的验证集,即得到4组模型的结果,取平均值作为最终结果。由于是将数据分为4份,所以我们称之为4折交叉验证。
充分利用已有的数据,对当前的数据进行训练、验证,目的就是为了使预测结果更加可靠,成功率更高。
交叉验证目的:为了让被评估的模型更加准确可信
这个只是对于参数得出更好的结果,那么我们应该如何选择或者调优参数呢?
我们可以采用穷举法,即事先准备一些k值,比如说
k=[1,2,3,4,5,6]
然后将这几个k值一个一个代入到我们的代码中,检测一下哪个k值才是最合适的
类似于暴力破解一样,遍历,一个一个试
# -*- coding: utf-8 -*-
"""
@Time : 2021/3/16 18:34
@Author : yuhui
@Email : [email protected]
@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算法中,我们常用的距离有:
那么我们在代码中,是如何体现我们使用的是哪种距离的呢?
打开之后就是下面的这个样子的