「作者主页」:士别三日wyx
「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者
「推荐专栏」:零基础快速入门人工智能《机器学习入门到精通》

K-近邻算法的K是指邻居的个数,「K值」不同,算法的「准确率」也不同,我们需要不断调整K值,以提高算法的准确率。在「调整」过程中,我们需要用到「交叉验证」

1、交叉验证

交叉验证(Cross-Validation)是在机器学习建立模型和验证模型「参数」时常用的方法,用于「评估」机器模型的性能指标,从而进行「模型选择」

交叉验证的「基本思想」是,把原始数据分组,一部分当做训练集,另一部分作为验证集,先用训练集对算法模型进行训练,再用验证集测试训练得到的算法模型。

比如,把数据分成四份,先用第一份数据当验证集,把后面三份的训练结果与第一份做验证;再用第二份数据当验证集,把其他三份数据的训练结果和第二份做验证;以此类推。。。

在这里插入图片描述

交叉验证常配合网格搜索一同使用。

2、网格搜索

网格搜索也叫超「参数搜索」,比如K-近邻算法的K值需要手动指定参数,这种参数就叫超参数。网格搜索通过预设几组超参数组合,每组超参数都用交叉验证进行评估,从而选出「最优」的参数组合来建立模型。

sklearn 模块 GridSearchCV 很好的实现了网格搜索,它可以自动调参,只要把参数输进去,就能给出最优的结果和参数。


3、模型选择与调优API

sklearn.model_selection.GridSearchCV( estimator,param_grid,cv)

  • estimator:需要使用的分类器
  • param_grid:需要优化的参数,字典或列表格式{ "n_neighbors": [1, 3, 5] , }
  • cv:交叉验证次数

返回值属性

  • best_params_:(dict)最佳参数
  • best_score_ :(float)最佳结果
  • best_estimator_:(estimator)最佳分类器
  • cv_results_:(dict)交叉验证结果
  • best_index_:(int)最佳参数的索引
  • n_splits_:(int)交叉验证的次数

4、案例演示

接下来,我们使用 GridSearchCV 来选择 K-近邻算法的「最佳K值」

4.1、特征集获取划分

使用 sklearn 自带的的鸢尾花「数据集」,数据集划分为60%训练,40%测试。

from sklearn import datasets
from sklearn import model_selection

# 1、获取数据集
iris = datasets.load_iris()
# 2、划分数据集
# x_train:训练集特征,x_test:测试集特征,y_train:训练集目标,y_test:测试集目标
x_train, x_test, y_train, y_test = model_selection.train_test_split(iris.data, iris.target, random_state=6)
print('训练集特征:', len(x_train))
print('测试集特征:', len(x_test))
print('训练集目标:', len(y_train))
print('测试集特征:', len(y_test))

输出:

训练集特征: 112
测试集特征: 38
训练集目标: 112
测试集特征: 38

从输出结果可以看到,训练集和测试集的比例符合预期


4.2、特征标准化

接下来,对训练集特征和测试集特征进行「标准化」处理

from sklearn import datasets
from sklearn import model_selection
from sklearn import preprocessing

# 1、获取数据集
iris = datasets.load_iris()
# 2、划分数据集
# x_train:训练集特征,x_test:测试集特征,y_train:训练集目标,y_test:测试集目标
x_train, x_test, y_train, y_test = model_selection.train_test_split(iris.data, iris.target, random_state=6)
# 3、特征标准化
ss = preprocessing.StandardScaler()
x_train = ss.fit_transform(x_train)
x_test = ss.fit_transform(x_test)
print(x_train)

输出:

[[-0.18295405 -0.192639    0.25280554 -0.00578113]
 [-1.02176094  0.51091214 -1.32647368 -1.30075363]
 [-0.90193138  0.97994624 -1.32647368 -1.17125638]

从输出结果可以看到,特征已经标准化。


4.3、KNN算法处理

将训练特征集和测试特征集传给KNN,并查看「准确率」

from sklearn import datasets
from sklearn import model_selection
from sklearn import preprocessing
from sklearn import neighbors

# 1、获取数据集
iris = datasets.load_iris()
# 2、划分数据集
# x_train:训练集特征,x_test:测试集特征,y_train:训练集目标,y_test:测试集目标
x_train, x_test, y_train, y_test = model_selection.train_test_split(iris.data, iris.target, random_state=6)
# 3、特征标准化
ss = preprocessing.StandardScaler()
x_train = ss.fit_transform(x_train)
x_test = ss.fit_transform(x_test)
# 4、KNN算法处理
knn = neighbors.KNeighborsClassifier(n_neighbors=2)
knn.fit(x_train, y_train)
print(knn.score(x_test, y_test))

输出:

0.8947368421052632

从输出结果可以看到,准确率是89%,一般般。


4.4、参数调优

将不同的K值封装成字典,传给 GridSearchCV,计算「最优」的参数。

from sklearn import datasets
from sklearn import model_selection
from sklearn import preprocessing
from sklearn import neighbors

# 1、获取数据集
iris = datasets.load_iris()
# 2、划分数据集
# x_train:训练集特征,x_test:测试集特征,y_train:训练集目标,y_test:测试集目标
x_train, x_test, y_train, y_test = model_selection.train_test_split(iris.data, iris.target, random_state=6)
# 3、特征标准化
ss = preprocessing.StandardScaler()
x_train = ss.fit_transform(x_train)
x_test = ss.fit_transform(x_test)
# 4、KNN算法处理
knn = neighbors.KNeighborsClassifier(n_neighbors=2)
# 5、参数调优
params = {"n_neighbors": [1, 3, 5, 7]}
knn = model_selection.GridSearchCV(knn, param_grid=params, cv=10)
knn.fit(x_train, y_train)
print('最优参数:', knn.best_params_)
print('最优准确率:', knn.best_score_)
print('最优分类器:', knn.best_estimator_)

输出:

最优参数: {'n_neighbors': 5}
最优准确率: 0.9727272727272729
最优分类器: KNeighborsClassifier()

从输出结果可以看到,最优的K值参数是5,准确率达到了97%

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐