本文目录导读:

我来详细讲解如何使用Scikit-learn进行网格搜索(Grid Search)和交叉验证(CV),这是调参的重要方法。
基础概念
网格搜索(Grid Search):在指定的参数范围内,遍历所有可能的参数组合 交叉验证(Cross Validation):将数据分成多份,轮流作为验证集
完整示例代码
1 基础网格搜索
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
# 加载数据
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)
# 定义模型
svm = SVC()
# 定义参数网格
param_grid = {
'C': [0.1, 1, 10, 100],
'gamma': [0.001, 0.01, 0.1, 1],
'kernel': ['rbf', 'linear']
}
# 创建网格搜索对象
grid_search = GridSearchCV(
estimator=svm,
param_grid=param_grid,
cv=5, # 5折交叉验证
scoring='accuracy', # 评分标准
n_jobs=-1, # 使用所有CPU核心
verbose=1 # 显示进度
)
# 执行网格搜索
grid_search.fit(X_train, y_train)
# 查看结果
print("最佳参数:", grid_search.best_params_)
print("最佳交叉验证得分:", grid_search.best_score_)
# 在测试集上评估
y_pred = grid_search.predict(X_test)
print("测试集得分:", grid_search.score(X_test, y_test))
# 显示详细结果
print("\n所有参数组合的得分:")
results = grid_search.cv_results_
for mean_score, params in zip(results['mean_test_score'], results['params']):
print(f"参数: {params}, 平均得分: {mean_score:.3f}")
2 不同评分指标
from sklearn.metrics import make_scorer, f1_score, recall_score, precision_score
# 使用F1分数作为评分指标
grid_search_f1 = GridSearchCV(
svm, param_grid, cv=5,
scoring='f1_macro', # 多分类F1
n_jobs=-1
)
# 自定义评分函数
def custom_scorer(y_true, y_pred):
"""自定义评分函数:F1和准确率的加权平均"""
f1 = f1_score(y_true, y_pred, average='micro')
accuracy = sum(y_true == y_pred) / len(y_true)
return 0.3 * f1 + 0.7 * accuracy
custom_scorer = make_scorer(custom_scorer)
grid_search_custom = GridSearchCV(
svm, param_grid, cv=5,
scoring=custom_scorer,
n_jobs=-1
)
3 随机森林的网格搜索
from sklearn.ensemble import RandomForestClassifier
# 随机森林的参数网格
rf_param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [None, 10, 20, 30],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4]
}
rf = RandomForestClassifier(random_state=42)
rf_grid_search = GridSearchCV(
rf, rf_param_grid, cv=5,
scoring='accuracy',
n_jobs=-1,
verbose=2
)
# 执行搜索(由于参数组合多,可能需要较长时间)
rf_grid_search.fit(X_train, y_train)
print("\n随机森林最佳参数:", rf_grid_search.best_params_)
print("随机森林最佳得分:", rf_grid_search.best_score_)
4 多阶段网格搜索
# 第一阶段:粗搜索
stage1_param_grid = {
'n_estimators': [10, 50, 100, 200],
'max_depth': [None, 10, 20, 50]
}
stage1_search = GridSearchCV(rf, stage1_param_grid, cv=3, n_jobs=-1)
stage1_search.fit(X_train, y_train)
print("第一阶段最佳参数:", stage1_search.best_params_)
# 第二阶段:在最佳参数附近精细搜索
best_params = stage1_search.best_params_
stage2_param_grid = {
'n_estimators': [
best_params['n_estimators'] - 25,
best_params['n_estimators'],
best_params['n_estimators'] + 25
],
'max_depth': [
best_params['max_depth'] - 5 if best_params['max_depth'] else 15,
best_params['max_depth'],
best_params['max_depth'] + 5 if best_params['max_depth'] else 25
],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4]
}
stage2_search = GridSearchCV(rf, stage2_param_grid, cv=5, n_jobs=-1)
stage2_search.fit(X_train, y_train)
print("第二阶段最佳参数:", stage2_search.best_params_)
5 可视化结果
import matplotlib.pyplot as plt
import numpy as np
def plot_grid_search_results(grid_search, param1, param2):
"""可视化网格搜索结果"""
results = grid_search.cv_results_
scores = results['mean_test_score'].reshape(
len(grid_search.param_grid[param1]),
len(grid_search.param_grid[param2])
)
plt.figure(figsize=(10, 8))
plt.imshow(scores, interpolation='nearest', cmap='viridis')
plt.xlabel(param2)
plt.ylabel(param1)
plt.colorbar(label='Accuracy')
# 设置刻度
plt.xticks(range(len(grid_search.param_grid[param2])),
grid_search.param_grid[param2])
plt.yticks(range(len(grid_search.param_grid[param1])),
grid_search.param_grid[param1])
# 显示数值
for i in range(scores.shape[0]):
for j in range(scores.shape[1]):
plt.text(j, i, f'{scores[i, j]:.3f}',
ha='center', va='center', color='white')
plt.title('Grid Search Results')
plt.tight_layout()
plt.show()
# 使用示例
plot_grid_search_results(grid_search, 'C', 'gamma')
高级技巧
1 使用Pipeline进行网格搜索
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
# 创建Pipeline
pipeline = Pipeline([
('scaler', StandardScaler()),
('pca', PCA()),
('classifier', SVC())
])
# Pipeline的参数网格
pipeline_param_grid = {
'pca__n_components': [2, 3, 4],
'classifier__C': [0.1, 1, 10],
'classifier__kernel': ['rbf', 'linear']
}
pipeline_grid_search = GridSearchCV(
pipeline, pipeline_param_grid, cv=5, n_jobs=-1
)
pipeline_grid_search.fit(X_train, y_train)
2 并行处理和早停
from sklearn.model_selection import PredefinedSplit
from sklearn.exceptions import FitFailedWarning
import warnings
warnings.filterwarnings('ignore', category=FitFailedWarning)
# 自定义交叉验证
test_fold = np.zeros(len(X_train))
test_fold[:int(len(X_train)*0.8)] = -1 # 最后20%作为验证集
ps = PredefinedSplit(test_fold)
# 带错误处理的网格搜索
grid_search_robust = GridSearchCV(
svm, param_grid, cv=ps,
scoring='accuracy',
n_jobs=-1,
error_score=0, # 失败的参数组合得分为0
return_train_score=True # 返回训练分数
)
grid_search_robust.fit(X_train, y_train)
3 保存和加载结果
import joblib
# 保存网格搜索对象
joblib.dump(grid_search, 'grid_search_model.pkl')
# 加载网格搜索对象
loaded_grid_search = joblib.load('grid_search_model.pkl')
# 保存最佳模型
best_model = grid_search.best_estimator_
joblib.dump(best_model, 'best_svm_model.pkl')
# 保存结果到CSV
import pandas as pd
results_df = pd.DataFrame(grid_search.cv_results_)
results_df.to_csv('grid_search_results.csv', index=False)
实用建议
1 参数网格设计建议
# 合理的参数搜索范围
param_grid_suggestions = {
# SVM
'svm': {
'C': [0.01, 0.1, 1, 10, 100],
'gamma': [0.001, 0.01, 0.1, 1, 'scale', 'auto'],
'kernel': ['rbf', 'poly', 'sigmoid']
},
# Random Forest
'rf': {
'n_estimators': [50, 100, 200, 500],
'max_depth': [None, 10, 20, 30, 50],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4],
'max_features': ['sqrt', 'log2']
},
# XGBoost
'xgb': {
'learning_rate': [0.01, 0.1, 0.3],
'max_depth': [3, 5, 7, 10],
'n_estimators': [100, 200, 500],
'subsample': [0.8, 0.9, 1.0]
}
}
2 注意事项
- 计算资源:参数组合过多时,考虑使用RandomizedSearchCV
- 过拟合:使用交叉验证防止过拟合
- 数据泄露:确保只在训练集上进行特征选择和预处理
- 结果解释:关注参数对模型性能的实际影响
网格搜索是机器学习中不可或缺的调参工具,合理使用可以显著提升模型性能。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播