Scikit-learn模型调优实战
学习目标
本课程将深入探讨如何使用Scikit-learn进行模型调优,通过网格搜索和随机搜索等方法,帮助学员找到最佳的模型参数,提高模型的预测性能。
相关知识点
- Scikit-learn模型调优
学习内容
1 Scikit-learn模型调优
1.1 网格搜索
网格搜索是一种常用的模型调优方法,它通过遍历所有可能的参数组合来寻找最佳的模型参数。这种方法虽然计算成本较高,但能够确保找到最优解。在Scikit-learn中,GridSearchCV
类提供了实现网格搜索的功能。
理论知识
网格搜索的基本思想是穷举所有可能的参数组合,然后通过交叉验证来评估每个组合的性能,最终选择性能最佳的参数组合。这种方法适用于参数空间较小的情况,因为参数空间的大小会随着参数数量和每个参数的可能值数量的增加而呈指数增长。因此,网格搜索可能不适合参数空间非常大的情况。
在Scikit-learn中,GridSearchCV
类允许用户指定一个模型、一个参数网格和一个交叉验证策略。GridSearchCV
会自动执行交叉验证,并返回最佳的模型参数。此外,GridSearchCV
还提供了访问最佳模型、最佳参数和最佳得分的方法。
实践代码
下面是一个使用GridSearchCV
进行网格搜索的示例代码,我们将使用一个简单的线性回归模型来演示如何进行网格搜索。
%pip install scikit-learn==1.1
%pip install scipy==1.10.1
from sklearn.datasets import load_diabetes
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.linear_model import Ridge
from sklearn.metrics import mean_squared_error
# 加载数据集
diabetes = load_diabetes()
X, y = diabetes.data, diabetes.target
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 定义模型
model = Ridge()
# 定义参数网格
param_grid = {
'alpha': [0.1, 1.0, 10.0, 100.0]
}
# 创建GridSearchCV对象
grid_search = GridSearchCV(model, param_grid, cv=5, scoring='neg_mean_squared_error')
# 拟合模型
grid_search.fit(X_train, y_train)
# 输出最佳参数
print("最佳参数:", grid_search.best_params_)
# 输出最佳模型
best_model = grid_search.best_estimator_
print("最佳模型:", best_model)
# 在测试集上评估最佳模型
y_pred = best_model.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
print("测试集上的均方误差:", mse)
最佳参数: {'alpha': 0.1}
最佳模型: Ridge(alpha=0.1)
测试集上的均方误差: 2856.4868876706546
1.2 随机搜索
随机搜索是一种更高效的模型调优方法,它通过随机采样参数空间来寻找最佳的模型参数。与网格搜索不同,随机搜索不需要遍历所有可能的参数组合,因此计算成本较低。在Scikit-learn中,RandomizedSearchCV
类提供了实现随机搜索的功能。
理论知识
随机搜索的基本思想是从参数空间中随机采样一定数量的参数组合,然后通过交叉验证来评估每个组合的性能,最终选择性能最佳的参数组合。这种方法适用于参数空间较大的情况,因为随机采样可以有效地减少计算成本,同时仍然有较高的概率找到接近最优的参数组合。
在Scikit-learn中,RandomizedSearchCV
类允许用户指定一个模型、一个参数分布和一个交叉验证策略。RandomizedSearchCV
会自动执行交叉验证,并返回最佳的模型参数。此外,RandomizedSearchCV
还提供了访问最佳模型、最佳参数和最佳得分的方法。
实践代码
下面是一个使用RandomizedSearchCV
进行随机搜索的示例代码,我们将使用一个随机森林分类器来演示如何进行随机搜索。
from sklearn.datasets import load_iris
from sklearn.model_selection import RandomizedSearchCV, train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
import numpy as np
# 加载数据集
iris = load_iris()
X, y = iris.data, iris.target
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 定义模型
model = RandomForestClassifier()
# 定义参数分布
param_distributions = {
'n_estimators': np.arange(10, 200, 10),
'max_depth': [None] + list(np.arange(1, 20)),
'min_samples_split': np.arange(2, 10),
'min_samples_leaf': np.arange(1, 10)
}
# 创建RandomizedSearchCV对象
random_search = RandomizedSearchCV(model, param_distributions, n_iter=100, cv=5, scoring='accuracy', random_state=42)
# 拟合模型
random_search.fit(X_train, y_train)
# 输出最佳参数
print("最佳参数:", random_search.best_params_)
# 输出最佳模型
best_model = random_search.best_estimator_
print("最佳模型:", best_model)
# 在测试集上评估最佳模型
y_pred = best_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print("测试集上的准确率:", accuracy)
最佳参数: {'n_estimators': 170, 'min_samples_split': 8, 'min_samples_leaf': 3, 'max_depth': 12}
最佳模型: RandomForestClassifier(max_depth=12, min_samples_leaf=3, min_samples_split=8,
n_estimators=170)
测试集上的准确率: 1.0
1.3 交叉验证
交叉验证是一种评估模型性能的方法,它通过将数据集划分为多个子集,然后在不同的子集上训练和验证模型,从而获得更稳定和可靠的性能评估。在Scikit-learn中,cross_val_score
函数提供了实现交叉验证的功能。
理论知识
交叉验证的基本思想是将数据集划分为多个子集(通常称为“折”),然后在每个子集上进行训练和验证。常见的交叉验证方法包括K折交叉验证、留一法交叉验证和分层K折交叉验证。K折交叉验证是最常用的方法,它将数据集划分为K个子集,然后进行K次训练和验证,每次选择一个子集作为验证集,其余子集作为训练集。最终的性能评估是K次验证结果的平均值。
在Scikit-learn中,cross_val_score
函数允许用户指定一个模型、数据集和交叉验证策略。cross_val_score
会自动执行交叉验证,并返回每次验证的得分。此外,cross_val_score
还支持多种评分方法,如准确率、均方误差等。
实践代码
下面是一个使用cross_val_score
进行交叉验证的示例代码,我们将使用一个逻辑回归模型来演示如何进行交叉验证。
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import cross_val_score, train_test_split
from sklearn.linear_model import LogisticRegression
# 加载数据集
cancer = load_breast_cancer()
X, y = cancer.data, cancer.target
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 定义模型
model = LogisticRegression(max_iter=3000)
# 执行交叉验证
scores = cross_val_score(model, X_train, y_train, cv=5, scoring='accuracy')
# 输出每次验证的得分
print("每次验证的得分:", scores)
# 输出平均得分
mean_score = np.mean(scores)
print("平均得分:", mean_score)
# 在测试集上评估模型
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print("测试集上的准确率:", accuracy)
每次验证的得分: [0.95604396 0.95604396 0.96703297 0.96703297 0.92307692]
平均得分: 0.9538461538461538
测试集上的准确率: 0.956140350877193
通过本课程的学习,学员将能够掌握如何使用Scikit-learn进行模型调优,包括网格搜索、随机搜索和交叉验证等方法,从而提高模型的预测性能。