今天向大家介绍的是交叉验证和网格搜索。交叉验证(Cross-validation)和网格搜索(Grid Search)是机器学习中两种常用的技术,它们主要用于模型选择和参数调优。
1.交叉验证
交叉验证是一种评估模型性能的方法,主要用于解决模型过拟合和欠拟合的问题。其主要思想是将原始数据集分成k个子集,每个子集都做一次验证集,其余的k-1个子集作为训练集。这样会得到k个模型,用这k个模型最终的验证集的平均分类准确率来作为此k-CV下分类器的性能指标。
如图:
1.将数据集均分为四部分,分别从中选一个作为验证集,其余的为训练集。
2.对这几次的模型分别进行评估 ,取平均值做交叉验证为模型得分。
3.若k=n模型得分最高,再用全部数据集对该模型再进行训练评估。
2.网格搜索
网格搜索(Grid Search)是一种调参技术,用于超参数优化,即寻找机器学习模型最佳参数的过程。在训练模型时,通常需要调整一些参数以优化模型的性能。然而,手动调整这些参数既费时又容易出错,因此网格搜索应运而生,自动进行参数调整。
网格搜索的基本思想是将待调整的参数(通常是一个或多个)进行排列组合,形成一个参数网格。然后,对于网格中的每一组参数,都会训练一个模型,并使用交叉验证来评估这组参数的性能。最后,网格搜索会返回性能最优的参数组合。
以下是网格搜索的基本步骤:
定义参数网格:确定要调整的参数及其可能的取值范围,形成一个参数网格。例如,对于KNN来说,需要调整的超参数就是K的值。
创建模型实例:选择要进行参数优化的模型,并创建模型实例。
使用网格搜索和交叉验证:将模型实例、参数网格和交叉验证策略(如K折交叉验证)输入到网格搜索算法中。网格搜索将遍历参数网格中的每一组参数,并使用交叉验证来评估该组参数的性能。
选择最佳参数组合:网格搜索完成后,它会返回在交叉验证中性能最优的参数组合。
训练最终模型:使用网格搜索找到的最佳参数组合来训练最终的模型。
3.实战
本次实战的内容是预测乳腺癌的良性和恶性。我们需要引入一个数据集load_breast_cancer。该数据集里面包含了乳腺癌的细胞样本的特征和对应的诊断结果(良性或恶性)。数据集详情可以去该数据集的官网查看。sklearn.datasets.load_breast_cancer — scikit-learn 1.4.2 documentation
同时还要引入一个新的库GridSearchCV
。GridSearchCV
是 scikit-learn 库中的一个非常有用的类,用于执行参数网格搜索和交叉验证。它的全称是 "Grid Search with Cross-Validation",即带交叉验证的网格搜索。GridSearchCV
通过穷举搜索指定的参数网格,找到给定评估指标下的最优参数组合。
实例代码如下:
from sklearn.datasets import load_breast_cancer
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import StandardScaler
import pandas as pd
breast_cancer = load_breast_cancer()
# print(breast_cancer.data)
x_train, x_test, y_train, y_test = train_test_split(breast_cancer.data, breast_cancer.target, test_size=0.2, random_state=22)
transformer = StandardScaler()
x_train = transformer.fit_transform(x_train)
x_test = transformer.fit_transform(x_test)
estimator = KNeighborsClassifier()
# 定义参数网格
param_grid = {'n_neighbors': [1, 3, 5]}
# 创建GridSearchCV实例
estimator = GridSearchCV(estimator=estimator, param_grid=param_grid, cv=5)
estimator.fit(x_train, y_train)
myret = pd.DataFrame(estimator.cv_results_)
# score = estimator.score(x_test, y_test)
# print('score:',score)
y_predict = estimator.predict(x_test)
myresult = accuracy_score(y_test, y_predict)
print('accuracy:\n', myresult)