超参数调优 #
概述 #
超参数调优是寻找模型最优参数配置的过程,对模型性能至关重要。
超参数 vs 参数 #
| 类型 | 描述 | 示例 |
|---|---|---|
| 参数 | 模型学习得到 | 权重、偏置 |
| 超参数 | 训练前设置 | 学习率、树深度 |
调优方法 #
| 方法 | 特点 | 适用场景 |
|---|---|---|
| GridSearch | 穷举搜索 | 参数空间小 |
| RandomSearch | 随机采样 | 参数空间大 |
| Bayes优化 | 智能搜索 | 计算资源有限 |
| Hyperband | 早停策略 | 大规模搜索 |
网格搜索 #
基本使用 #
python
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
from sklearn.datasets import load_iris
iris = load_iris()
X, y = iris.data, iris.target
param_grid = {
'C': [0.1, 1, 10],
'kernel': ['linear', 'rbf'],
'gamma': ['scale', 'auto']
}
grid_search = GridSearchCV(
SVC(),
param_grid,
cv=5,
scoring='accuracy',
n_jobs=-1
)
grid_search.fit(X, y)
print(f"最佳参数: {grid_search.best_params_}")
print(f"最佳分数: {grid_search.best_score_:.4f}")
参数说明 #
| 参数 | 描述 |
|---|---|
estimator |
估计器 |
param_grid |
参数网格 |
cv |
交叉验证折数 |
scoring |
评估指标 |
n_jobs |
并行任务数 |
verbose |
日志详细程度 |
refit |
是否用最佳参数重训练 |
多指标评估 #
python
scoring = ['accuracy', 'precision_macro', 'recall_macro', 'f1_macro']
grid_search = GridSearchCV(
SVC(),
param_grid,
cv=5,
scoring=scoring,
refit='f1_macro'
)
grid_search.fit(X, y)
获取结果 #
python
import pandas as pd
results = pd.DataFrame(grid_search.cv_results_)
print(results[['params', 'mean_test_score', 'std_test_score']].head())
best_model = grid_search.best_estimator_
print(f"最佳模型: {best_model}")
条件参数网格 #
python
param_grid = [
{'kernel': ['linear'], 'C': [0.1, 1, 10]},
{'kernel': ['rbf'], 'C': [0.1, 1, 10], 'gamma': ['scale', 'auto']},
{'kernel': ['poly'], 'C': [0.1, 1, 10], 'degree': [2, 3]}
]
grid_search = GridSearchCV(SVC(), param_grid, cv=5)
随机搜索 #
基本使用 #
python
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import uniform, randint
param_distributions = {
'C': uniform(0.1, 10),
'kernel': ['linear', 'rbf', 'poly'],
'gamma': ['scale', 'auto'],
'degree': randint(2, 5)
}
random_search = RandomizedSearchCV(
SVC(),
param_distributions,
n_iter=50,
cv=5,
random_state=42,
n_jobs=-1
)
random_search.fit(X, y)
print(f"最佳参数: {random_search.best_params_}")
print(f"最佳分数: {random_search.best_score_:.4f}")
参数说明 #
| 参数 | 描述 |
|---|---|
n_iter |
采样次数 |
param_distributions |
参数分布 |
分布类型 #
python
from scipy.stats import uniform, randint, loguniform, expon
param_distributions = {
'C': loguniform(1e-3, 1e3),
'gamma': loguniform(1e-4, 1e1),
'learning_rate': uniform(0.01, 0.3),
'n_estimators': randint(50, 500),
'max_depth': randint(3, 15)
}
GridSearch vs RandomSearch #
python
import matplotlib.pyplot as plt
import numpy as np
grid_scores = []
random_scores = []
for _ in range(10):
gs = GridSearchCV(SVC(), param_grid, cv=5)
gs.fit(X, y)
grid_scores.append(gs.best_score_)
rs = RandomizedSearchCV(SVC(), param_distributions, n_iter=10, cv=5, random_state=np.random.randint(1000))
rs.fit(X, y)
random_scores.append(rs.best_score_)
plt.boxplot([grid_scores, random_scores], labels=['GridSearch', 'RandomSearch'])
plt.ylabel('Best Score')
plt.title('GridSearch vs RandomSearch')
Halving 搜索 #
HalvingGridSearchCV #
python
from sklearn.experimental import enable_halving_search_cv
from sklearn.model_selection import HalvingGridSearchCV
param_grid = {
'C': [0.1, 1, 10, 100],
'kernel': ['linear', 'rbf'],
'gamma': ['scale', 'auto']
}
halving_search = HalvingGridSearchCV(
SVC(),
param_grid,
cv=5,
factor=3,
random_state=42,
n_jobs=-1
)
halving_search.fit(X, y)
print(f"最佳参数: {halving_search.best_params_}")
print(f"最佳分数: {halving_search.best_score_:.4f}")
HalvingRandomSearchCV #
python
from sklearn.model_selection import HalvingRandomSearchCV
halving_random = HalvingRandomSearchCV(
SVC(),
param_distributions,
n_candidates=50,
cv=5,
factor=3,
random_state=42
)
halving_random.fit(X, y)
参数说明 #
| 参数 | 描述 |
|---|---|
factor |
每轮淘汰比例 |
resource |
资源类型 |
max_resources |
最大资源 |
min_resources |
最小资源 |
Pipeline 调参 #
基本使用 #
python
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
pipe = Pipeline([
('scaler', StandardScaler()),
('clf', LogisticRegression(max_iter=1000))
])
param_grid = {
'scaler__with_mean': [True, False],
'clf__C': [0.1, 1, 10],
'clf__penalty': ['l1', 'l2'],
'clf__solver': ['liblinear', 'saga']
}
grid_search = GridSearchCV(pipe, param_grid, cv=5)
grid_search.fit(X, y)
ColumnTransformer 调参 #
python
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
preprocessor = ColumnTransformer([
('num', StandardScaler(), [0, 1]),
('cat', OneHotEncoder(), [2, 3])
])
pipe = Pipeline([
('preprocessor', preprocessor),
('clf', LogisticRegression())
])
param_grid = {
'preprocessor__num__with_mean': [True, False],
'clf__C': [0.1, 1, 10]
}
多模型调参 #
比较多个模型 #
python
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
models = {
'RF': {
'model': RandomForestClassifier(random_state=42),
'params': {
'n_estimators': [50, 100, 200],
'max_depth': [5, 10, None]
}
},
'SVM': {
'model': SVC(),
'params': {
'C': [0.1, 1, 10],
'kernel': ['linear', 'rbf']
}
},
'LR': {
'model': LogisticRegression(max_iter=1000),
'params': {
'C': [0.1, 1, 10],
'penalty': ['l1', 'l2']
}
}
}
best_score = 0
best_model = None
for name, config in models.items():
gs = GridSearchCV(config['model'], config['params'], cv=5)
gs.fit(X, y)
print(f"{name}: {gs.best_score_:.4f}")
if gs.best_score_ > best_score:
best_score = gs.best_score_
best_model = gs.best_estimator_
print(f"\n最佳模型: {type(best_model).__name__}")
print(f"最佳分数: {best_score:.4f}")
可视化调参结果 #
热力图 #
python
import seaborn as sns
import pandas as pd
results = pd.DataFrame(grid_search.cv_results_)
pivot = results.pivot_table(
values='mean_test_score',
index='param_C',
columns='param_kernel'
)
plt.figure(figsize=(8, 6))
sns.heatmap(pivot, annot=True, fmt='.4f', cmap='YlGnBu')
plt.title('Grid Search Results')
参数影响图 #
python
plt.figure(figsize=(12, 4))
plt.subplot(131)
plt.plot(results['param_C'], results['mean_test_score'], 'o-')
plt.xlabel('C')
plt.ylabel('Score')
plt.subplot(132)
results.groupby('param_kernel')['mean_test_score'].mean().plot(kind='bar')
plt.xlabel('Kernel')
plt.ylabel('Mean Score')
plt.tight_layout()
并行化 #
使用 n_jobs #
python
grid_search = GridSearchCV(
SVC(),
param_grid,
cv=5,
n_jobs=-1,
verbose=1
)
分布式调参 #
python
from joblib import parallel_backend
with parallel_backend('multiprocessing', n_jobs=-1):
grid_search.fit(X, y)
早停策略 #
使用验证集 #
python
from sklearn.model_selection import train_test_split
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)
best_score = 0
best_params = None
for C in [0.1, 1, 10]:
for kernel in ['linear', 'rbf']:
model = SVC(C=C, kernel=kernel)
model.fit(X_train, y_train)
score = model.score(X_val, y_val)
if score > best_score:
best_score = score
best_params = {'C': C, 'kernel': kernel}
增量调参 #
python
from sklearn.ensemble import GradientBoostingClassifier
param_grid = {
'n_estimators': [100, 200, 500],
'learning_rate': [0.01, 0.1, 0.2],
'max_depth': [3, 5, 7]
}
grid_search = GridSearchCV(
GradientBoostingClassifier(
n_iter_no_change=10,
validation_fraction=0.1
),
param_grid,
cv=5
)
最佳实践 #
1. 搜索策略 #
| 数据量 | 推荐方法 |
|---|---|
| 小 | GridSearch |
| 中 | RandomSearch |
| 大 | HalvingSearch |
2. 参数范围 #
python
param_grid = {
'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000],
'learning_rate': [0.001, 0.01, 0.1, 0.3]
}
3. 粗细搜索 #
python
coarse_grid = {'C': [0.1, 1, 10, 100]}
coarse_search = GridSearchCV(SVC(), coarse_grid, cv=5)
coarse_search.fit(X, y)
best_C_coarse = coarse_search.best_params_['C']
fine_grid = {'C': np.linspace(best_C_coarse/2, best_C_coarse*2, 10)}
fine_search = GridSearchCV(SVC(), fine_grid, cv=5)
fine_search.fit(X, y)
4. 保存结果 #
python
import joblib
joblib.dump(grid_search, 'grid_search_results.pkl')
loaded = joblib.load('grid_search_results.pkl')
5. 避免数据泄露 #
python
from sklearn.pipeline import Pipeline
pipe = Pipeline([
('scaler', StandardScaler()),
('clf', SVC())
])
GridSearchCV(pipe, param_grid, cv=5)
下一步 #
掌握超参数调优后,继续学习 特征选择 了解如何选择最优特征!
最后更新:2026-04-04