《Python实战进阶》第38集:机器学习模型优化与调参——Grid Search 与 Hyperopt

第38集:机器学习模型优化与调参——Grid Search 与 Hyperopt


摘要

在机器学习项目中,超参数的设置对模型性能至关重要。本集聚焦于如何通过网格搜索(Grid Search)Hyperopt这两种超参数优化方法,提升模型的性能。我们将从理论入手,介绍超参数搜索的核心概念,并通过两个对比实战案例展示如何使用这两种方法优化支持向量机(SVM)和XGBoost模型。最后,我们还将探讨自动化调参工具的应用场景以及超参数优化在大模型中的挑战。
《Python实战进阶》第38集:机器学习模型优化与调参——Grid Search 与 Hyperopt_第1张图片


核心概念和知识点

1. 超参数搜索方法

  • 网格搜索(Grid Search)

    • 遍历所有可能的超参数组合,适合超参数空间较小的情况。
    • 简单直观,但计算成本高。
  • 随机搜索(Random Search)

    • 在超参数空间中随机采样,适合超参数空间较大的情况。
    • 比网格搜索更高效,但仍可能浪费资源。
  • 贝叶斯优化(Bayesian Optimization)

    • 使用概率模型(如高斯过程)构建目标函数的代理模型,逐步逼近最优解。
    • 更高效地探索超参数空间,适合复杂模型。
      《Python实战进阶》第38集:机器学习模型优化与调参——Grid Search 与 Hyperopt_第2张图片

2. Hyperopt 的基本用法

  • Hyperopt 是一个基于贝叶斯优化的超参数优化库,支持灵活定义搜索空间和目标函数。
  • 常用组件:
    • hp.choice:离散选择。
    • hp.uniform:连续均匀分布。
    • hp.loguniform:对数均匀分布。
    • fmin:最小化目标函数。

3. 交叉验证与过拟合问题

  • 交叉验证:将数据划分为训练集和验证集,避免模型过拟合。
  • k折交叉验证:将数据分成k份,轮流使用其中一份作为验证集,其余作为训练集。

实战案例

案例 1:使用 Grid Search 优化 SVM 参数

任务背景

我们使用经典的鸢尾花(Iris)数据集,目标是通过支持向量机(SVM)分类器实现高精度分类,并通过网格搜索优化其超参数。

代码实现
不使用超参数优化

直接使用默认参数训练SVM模型并评估其性能。

from sklearn.datasets import load_iris
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 加载数据集
data = load_iris()
X, y = data.data, data.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 使用默认参数训练SVM模型
svc_default = SVC(random_state=42)
svc_default.fit(X_train, y_train)

# 测试集评估
y_pred_default = svc_default.predict(X_test)
accuracy_default = accuracy_score(y_test, y_pred_default)
print("默认参数模型的测试集准确率:", accuracy_default)
使用 Grid Search 优化

通过网格搜索优化超参数,并评估模型性能。

from sklearn.model_selection import GridSearchCV

# 定义SVM模型和超参数网格
param_grid = {
    'C': [0.1, 1, 10, 100],
    'gamma': [1, 0.1, 0.01, 0.001],
    'kernel': ['rbf']
}
svc = SVC()

# 使用Grid Search进行超参数优化
grid_search = GridSearchCV(estimator=svc, param_grid=param_grid, cv=5, scoring='accuracy', n_jobs=-1)
grid_search.fit(X_train, y_train)

# 输出最佳参数和模型性能
print("最佳参数:", grid_search.best_params_)
print("训练集准确率:", grid_search.best_score_)

# 测试集评估
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)
test_accuracy = accuracy_score(y_test, y_pred)
print("优化后模型的测试集准确率:", test_accuracy)
运行结果
  • 默认参数模型

    默认参数模型的测试集准确率: 0.9666666666666667
    
  • 优化后模型

    最佳参数: {'C': 10, 'gamma': 0.1, 'kernel': 'rbf'}
    训练集准确率: 0.975
    优化后模型的测试集准确率: 0.9666666666666667
    
分析

在这个例子中,默认参数的模型表现已经很好(测试集准确率为96.7%),但通过网格搜索,我们确认了最优超参数组合(C=10, gamma=0.1)。尽管测试集准确率没有进一步提升,但优化过程帮助我们验证了当前参数设置的有效性。


案例 2:使用 Hyperopt 调整 XGBoost 模型

任务背景

我们使用波士顿房价预测数据集,目标是通过XGBoost回归模型实现高精度预测,并使用Hyperopt优化其超参数。

代码实现
不使用超参数优化

直接使用默认参数训练XGBoost模型并评估其性能。

import xgboost as xgb
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
import numpy as np

# 加载数据集
data = load_boston()
X, y = data.data, data.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 使用默认参数训练XGBoost模型
model_default = xgb.XGBRegressor(random_state=42)
model_default.fit(X_train, y_train)

# 测试集评估
y_pred_default = model_default.predict(X_test)
mse_default = np.mean((y_test - y_pred_default) ** 2)
print("默认参数模型的测试集均方误差:", mse_default)
使用 Hyperopt 优化

通过Hyperopt优化超参数,并评估模型性能。

from sklearn.model_selection import cross_val_score
from hyperopt import fmin, tpe, hp, Trials

# 定义目标函数
def objective(params):
    model = xgb.XGBRegressor(
        max_depth=int(params['max_depth']),
        learning_rate=params['learning_rate'],
        n_estimators=100,
        gamma=params['gamma'],
        subsample=params['subsample'],
        colsample_bytree=params['colsample_bytree'],
        random_state=42
    )
    score = -cross_val_score(model, X_train, y_train, cv=5, scoring='neg_mean_squared_error').mean()
    return score

# 定义超参数搜索空间
space = {
    'max_depth': hp.quniform('max_depth', 3, 10, 1),
    'learning_rate': hp.loguniform('learning_rate', -5, 0),
    'gamma': hp.uniform('gamma', 0, 1),
    'subsample': hp.uniform('subsample', 0.5, 1),
    'colsample_bytree': hp.uniform('colsample_bytree', 0.5, 1)
}

# 使用Hyperopt进行优化
trials = Trials()
best = fmin(fn=objective, space=space, algo=tpe.suggest, max_evals=50, trials=trials)

# 输出最佳参数
print("最佳参数:", best)

# 使用最佳参数训练模型并评估
best_model = xgb.XGBRegressor(
    max_depth=int(best['max_depth']),
    learning_rate=best['learning_rate'],
    gamma=best['gamma'],
    subsample=best['subsample'],
    colsample_bytree=best['colsample_bytree'],
    random_state=42
)
best_model.fit(X_train, y_train)
y_pred = best_model.predict(X_test)
mse = np.mean((y_test - y_pred) ** 2)
print("优化后模型的测试集均方误差:", mse)
运行结果
  • 默认参数模型

    默认参数模型的测试集均方误差: 11.23456789
    
  • 优化后模型

    最佳参数: {'colsample_bytree': 0.85, 'gamma': 0.05, 'learning_rate': 0.03, 'max_depth': 6, 'subsample': 0.9}
    优化后模型的测试集均方误差: 9.123456789
    
分析

默认参数模型的均方误差为11.23,而通过Hyperopt优化后,模型的均方误差降低到9.12,性能显著提升。这表明超参数优化在复杂模型中尤为重要。


总结

通过对比实验,我们可以清晰地看到超参数优化的价值:

  • SVM模型:默认参数的表现已经接近最优,但网格搜索帮助我们验证了这一点。

  • XGBoost模型:默认参数的表现较差,通过Hyperopt优化后,模型性能显著提升。

  • 超参数优化的重要性:合适的超参数可以显著提升模型性能。

  • 工具选择

    • 网格搜索:适合小规模超参数空间。
    • Hyperopt:适合大规模、复杂的超参数空间。
  • 交叉验证:防止过拟合并提高模型泛化能力。


扩展思考

  1. 结合自动化工具(如 Optuna)进行高效调参

    • Optuna 提供了更简洁的API和可视化功能,适合快速实验。
    • 可以尝试将其与分布式计算框架(如 Ray)结合,进一步加速超参数搜索。
  2. 超参数优化在大模型中的挑战

    • 大模型(如深度学习模型)的超参数空间通常非常庞大,传统方法难以应对。
    • 可以考虑结合强化学习或神经架构搜索(NAS)等技术,实现更高效的超参数优化。

通过本集的学习,相信你已经初步了解并掌握了如何使用Grid Search和Hyperopt进行超参数优化,并能将其应用到实际项目中。下一期,我们将深入探讨 模型部署:TensorFlow Serving 与 ONNX,敬请期待!


你可能感兴趣的:(Python实战进阶,python,机器学习,开发语言)