html
掌握 GridSearchCV 以优化机器学习模型:全面指南
目录
- GridSearchCV 简介
- 理解数据集
- 数据预处理
- 处理缺失数据
- 编码分类变量
- 特征选择
- 特征缩放
- 实现 GridSearchCV
- 使用 StratifiedKFold 设置交叉验证
- 解释 GridSearchCV 参数
- 构建和调整机器学习模型
- K-最近邻(KNN)
- 逻辑回归
- 高斯朴素贝叶斯
- 支持向量机(SVM)
- 决策树
- 随机森林
- AdaBoost
- XGBoost
- 性能分析
- 优化 GridSearchCV
- 结论和下一步
1. GridSearchCV 简介
GridSearchCV 是机器学习中用于超参数调优的技术。超参数是决定训练过程和模型结构的关键参数。与常规参数不同,超参数是在训练阶段开始之前设置的,且可以显著影响模型的性能。
GridSearchCV 通过详尽地搜索指定的参数网格,使用交叉验证评估每个组合,并根据所选择的指标(例如 F1 分数、准确率)识别出最佳性能的组合。
为什么选择 GridSearchCV?
- 全面搜索:评估所有可能的超参数组合。
- 交叉验证:确保模型的性能稳健,不仅仅针对特定数据子集进行调整。
- 自动化:简化调优过程,节省时间和计算资源。
然而,需要注意的是,GridSearchCV 可能在计算上非常密集,尤其是在处理大型数据集和广泛的参数网格时。本指南将探讨有效应对这些挑战的策略。
2. 理解数据集
在本演示中,我们使用一个专注于航空乘客满意度的数据集。数据集最初包含超过 100,000 条记录,但为了本例的可行性,已缩减至 5,000 条记录。每条记录包含 23 个特征,包括人口统计信息、航班详情和满意度水平。
数据集样本
性别
客户类型
年龄
旅行类型
舱位
飞行距离
...
满意度
女性
忠诚客户
41
个人旅行
经济高级
746
...
中立或不满意
男性
忠诚客户
53
商务旅行
商务舱
3095
...
满意
男性
不忠诚客户
21
商务旅行
经济舱
125
...
满意
...
...
...
...
...
...
...
...
目标变量是 满意度,分类为“满意”或“中立或不满意”。
3. 数据预处理
有效的数据预处理对于确保机器学习模型的最佳性能至关重要。步骤包括处理缺失数据、编码分类变量、特征选择和特征缩放。
处理缺失数据
数值数据:使用 均值填补 策略处理数值列中的缺失值。
123456789101112
from sklearn.impute import SimpleImputerimport numpy as np # 初始化数值数据的填补器imp_mean = SimpleImputer(missing_values=np.nan, strategy='mean') # 识别数值列numerical_cols = list(np.where((X.dtypes == np.int64) | (X.dtypes == np.float64))[0]) # 拟合并转换数据imp_mean.fit(X.iloc[:, numerical_cols])X.iloc[:, numerical_cols] = imp_mean.transform(X.iloc[:, numerical_cols])
分类数据:对于基于字符串的列,采用 最频繁值填补 策略。
123456789
# 初始化分类数据的填补器imp_freq = SimpleImputer(missing_values=np.nan, strategy='most_frequent') # 识别字符串列string_cols = list(np.where((X.dtypes == object))[0]) # 拟合并转换数据imp_freq.fit(X.iloc[:, string_cols])X.iloc[:, string_cols] = imp_freq.transform(X.iloc[:, string_cols])
编码分类变量
使用 标签编码 和 独热编码 将分类变量转换为数值格式。
123456789101112131415161718192021222324252627282930
from sklearn.preprocessing import LabelEncoder, OneHotEncoderfrom sklearn.compose import ColumnTransformer def LabelEncoderMethod(series): le = LabelEncoder() return le.fit_transform(series) def OneHotEncoderMethod(indices, data): columnTransformer = ColumnTransformer( [('encoder', OneHotEncoder(), indices)], remainder='passthrough' ) return columnTransformer.fit_transform(data) def EncodingSelection(X, threshold=10): string_cols = list(np.where((X.dtypes == object))[0]) one_hot_encoding_indices = [] for col in string_cols: unique_vals = len(pd.unique(X[X.columns[col]])) if unique_vals == 2 or unique_vals > threshold: X[X.columns[col]] = LabelEncoderMethod(X[X.columns[col]]) else: one_hot_encoding_indices.append(col) X = OneHotEncoderMethod(one_hot_encoding_indices, X) return X # 应用编码X = EncodingSelection(X)
特征选择
为了提升模型性能并减少计算复杂度,使用具有卡方(χ²)统计的 SelectKBest 选择前 10 个特征。
123456789101112
from sklearn.feature_selection import SelectKBest, chi2from sklearn.preprocessing import MinMaxScaler # 初始化 SelectKBestkbest = SelectKBest(score_func=chi2, k=10) # 缩放特征scaler = MinMaxScaler()X_scaled = scaler.fit_transform(X) # 拟合 SelectKBestX_selected = kbest.fit_transform(X_scaled, y)
特征缩放
特征缩放确保所有特征对模型性能的贡献均等。
123456789
from sklearn.preprocessing import StandardScaler # 初始化 StandardScalersc = StandardScaler(with_mean=False) # 拟合并转换训练数据sc.fit(X_train)X_train = sc.transform(X_train)X_test = sc.transform(X_test)
4. 实现 GridSearchCV
在数据预处理完成后,下一步涉及设置 GridSearchCV 以调整各种机器学习模型的超参数。
使用 StratifiedKFold 设置交叉验证
StratifiedKFold 确保交叉验证的每个折叠保持相同的类别标签比例,这对于不平衡的数据集至关重要。
1234
from sklearn.model_selection import StratifiedKFold # 初始化 StratifiedKFoldcv = StratifiedKFold(n_splits=2)
解释 GridSearchCV 参数
- Estimator:要调整的机器学习模型。
- Param_grid:定义要探索的超参数及其各自的值的字典。
- Verbose:控制输出的详细程度;设置为 1 以显示进度。
- Scoring:要优化的性能指标,例如 'f1'。
- n_jobs:使用的 CPU 核心数量;设置为 -1 可使用所有可用核心。
123456789101112131415161718192021
from sklearn.model_selection import GridSearchCV # 示例:为 KNN 设置 GridSearchCVfrom sklearn.neighbors import KNeighborsClassifier model = KNeighborsClassifier()params = { 'n_neighbors': [4, 5, 6, 7], 'leaf_size': [1, 3, 5], 'algorithm': ['auto', 'kd_tree'], 'weights': ['uniform', 'distance']} grid_search_cv = GridSearchCV( estimator=model, param_grid=params, verbose=1, cv=cv, scoring='f1', n_jobs=-1)
5. 构建和调整机器学习模型
5.1 K-最近邻(KNN)
KNN 是一种简单而有效的分类算法。GridSearchCV 有助于选择最佳的邻居数量、叶大小、算法和加权方案。
123456
# 拟合 GridSearchCVgrid_search_cv.fit(X_train, y_train) # 最佳参数print("最佳估计器", grid_search_cv.best_estimator_)print("最佳分数", grid_search_cv.best_score_)
输出:
12
最佳估计器 KNeighborsClassifier(leaf_size=1)最佳分数 0.8774673417446253
5.2 逻辑回归
逻辑回归建模二元结果的概率。GridSearchCV 调整求解器类型、惩罚项和正则化强度。
123456789101112131415161718192021
from sklearn.linear_model import LogisticRegression model = LogisticRegression()params = { 'solver': ['newton-cg', 'lbfgs', 'liblinear'], 'penalty': ['l1', 'l2'], 'C': [100, 10, 1.0, 0.1, 0.01]} grid_search_cv = GridSearchCV( estimator=model, param_grid=params, verbose=1, cv=cv, scoring='f1', n_jobs=-1) grid_search_cv.fit(X_train, y_train)print("最佳估计器", grid_search_cv.best_estimator_)print("最佳分数", grid_search_cv.best_score_)
输出:
12
最佳估计器 LogisticRegression(C=0.01, solver='newton-cg')最佳分数 0.8295203666687819
5.3 高斯朴素贝叶斯
高斯朴素贝叶斯假设特征遵循正态分布。它的超参数较少,使得 GridSearchCV 的计算强度较低。
123456789
from sklearn.naive_bayes import GaussianNBfrom sklearn.metrics import accuracy_score, classification_report model_GNB = GaussianNB()model_GNB.fit(X_train, y_train)y_pred = model_GNB.predict(X_test) print(accuracy_score(y_pred, y_test))print(classification_report(y_pred, y_test))
输出:
123456789
0.84 precision recall f1-score support 0 0.86 0.86 0.86 564 1 0.82 0.81 0.82 436 accuracy 0.84 1000 macro avg 0.84 0.84 0.84 1000weighted avg 0.84 0.84 0.84 1000
5.4 支持向量机(SVM)
SVM 是多功能的分类器,适用于线性和非线性数据。GridSearchCV 调整核类型、正则化参数 C
、次数、系数 coef0
和核系数 gamma
。
1234567891011121314151617181920212223
from sklearn.svm import SVC model = SVC()params = { 'kernel': ['linear', 'poly', 'rbf', 'sigmoid'], 'C': [1, 5, 10], 'degree': [3, 8], 'coef0': [0.01, 10, 0.5], 'gamma': ['auto', 'scale']} grid_search_cv = GridSearchCV( estimator=model, param_grid=params, verbose=1, cv=cv, scoring='f1', n_jobs=-1) grid_search_cv.fit(X_train, y_train)print("最佳估计器", grid_search_cv.best_estimator_)print("最佳分数", grid_search_cv.best_score_)
输出:
12
最佳估计器 SVC(C=5, coef0=0.01)最佳分数 0.9168629045108148
5.5 决策树
决策树基于特征值对数据进行分割以进行预测。GridSearchCV 优化如最大叶节点数和拆分内部节点所需的最小样本数等参数。
1234567891011121314151617181920
from sklearn.tree import DecisionTreeClassifier model = DecisionTreeClassifier()params = { 'max_leaf_nodes': list(range(2, 100)), 'min_samples_split': [2, 3, 4]} grid_search_cv = GridSearchCV( estimator=model, param_grid=params, verbose=1, cv=cv, scoring='f1', n_jobs=-1) grid_search_cv.fit(X_train, y_train)print("最佳估计器", grid_search_cv.best_estimator_)print("最佳分数", grid_search_cv.best_score_)
输出:
12
最佳估计器 DecisionTreeClassifier(max_leaf_nodes=29, min_samples_split=4)最佳分数 0.9098148654372425
5.6 随机森林
随机森林通过聚合多个决策树来提升性能并控制过拟合。GridSearchCV 调整如估计器数量、最大深度、特征数量和样本拆分等参数。
123456789101112131415161718192021222324
from sklearn.ensemble import RandomForestClassifier model = RandomForestClassifier()params = { 'bootstrap': [True], 'max_depth': [80, 90, 100, 110], 'max_features': [2, 3], 'min_samples_leaf': [3, 4, 5], 'min_samples_split': [8, 10, 12], 'n_estimators': [100, 200, 300, 1000]} grid_search_cv = GridSearchCV( estimator=model, param_grid=params, verbose=1, cv=cv, scoring='f1', n_jobs=-1) grid_search_cv.fit(X_train, y_train)print("最佳估计器", grid_search_cv.best_estimator_)print("最佳分数", grid_search_cv.best_score_)
输出:
12
最佳估计器 RandomForestClassifier(max_leaf_nodes=82, min_samples_split=4)最佳分数 0.9225835186933584
5.7 AdaBoost
AdaBoost 结合多个弱分类器形成强分类器。GridSearchCV 调整估计器数量和学习率。
1234567891011121314151617181920
from sklearn.ensemble import AdaBoostClassifier model = AdaBoostClassifier()params = { 'n_estimators': np.arange(10, 300, 10), 'learning_rate': [0.01, 0.05, 0.1, 1]} grid_search_cv = GridSearchCV( estimator=model, param_grid=params, verbose=1, cv=cv, scoring='f1', n_jobs=-1) grid_search_cv.fit(X_train, y_train)print("最佳估计器", grid_search_cv.best_estimator_)print("最佳分数", grid_search_cv.best_score_)
输出:
12
最佳估计器 AdaBoostClassifier(learning_rate=1, n_estimators=30)最佳分数 0.8938313525749858
5.8 XGBoost
XGBoost 是一种高效且可扩展的梯度提升实现。由于其广泛的超参数空间,GridSearchCV 可能耗时较长。
1234567891011121314151617181920212223242526
import xgboost as xgb model = xgb.XGBClassifier()params = { 'min_child_weight': [1, 5, 10], 'gamma': [0.5, 1, 1.5, 2, 5], 'subsample': [0.6, 0.8, 1.0], 'colsample_bytree': [0.6, 0.8, 1.0], 'max_depth': [3, 4, 5], 'n_estimators': [100, 500, 1000], 'learning_rate': [0.01, 0.3, 0.5, 0.1], 'reg_lambda': [1, 2]} grid_search_cv = GridSearchCV( estimator=model, param_grid=params, verbose=1, cv=cv, scoring='f1', n_jobs=-1) grid_search_cv.fit(X_train, y_train)print("最佳估计器", grid_search_cv.best_estimator_)print("最佳分数", grid_search_cv.best_score_)
输出:
123456789
最佳估计器 XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1, colsample_bynode=1, colsample_bytree=0.8, gamma=0.5, gpu_id=-1, importance_type='gain', interaction_constraints='', learning_rate=0.01, max_delta_step=0, max_depth=5, min_child_weight=1, missing=nan, monotone_constraints='()', n_estimators=500, n_jobs=12, num_parallel_tree=1, random_state=0, reg_alpha=0, reg_lambda=1, scale_pos_weight=1, subsample=1.0, tree_method='exact', validate_parameters=1, verbosity=None)最佳分数 0.9267223852716081
注意:由于超参数组合众多,XGBoost 的 GridSearchCV 运行时间显著较长。
6. 性能分析
调整后,每个模型根据达到的最佳 F1 分数表现出不同的性能水平:
- KNN:0.877
- 逻辑回归:0.830
- 高斯朴素贝叶斯:0.840
- SVM:0.917
- 决策树:0.910
- 随机森林:0.923
- AdaBoost:0.894
- XGBoost:0.927
解释
- XGBoost 和 随机森林 显示出最高的 F1 分数,表明在数据集上具有卓越的表现。
- SVM 也表现出强劲的性能。
- KNN 和 AdaBoost 提供了具有竞争力的结果,F1 分数略低。
- 逻辑回归 和 高斯朴素贝叶斯 虽然较简单,但仍提供了可观的性能指标。
7. 优化 GridSearchCV
鉴于 GridSearchCV 的计算强度,尤其是在处理大型数据集或广泛的参数网格时,探索优化策略至关重要:
7.1 RandomizedSearchCV
与 GridSearchCV 不同,RandomizedSearchCV 从指定的分布中随机采样固定数量的参数设置。这种方法可以显著减少计算时间,同时仍探索多样的超参数。
1234567891011121314151617
from sklearn.model_selection import RandomizedSearchCV # RandomizedSearchCV 的示例设置random_search_cv = RandomizedSearchCV( estimator=model, param_distributions=params, n_iter=100, # 采样的参数设置数量 verbose=1, cv=cv, scoring='f1', n_jobs=-1, random_state=42) random_search_cv.fit(X_train, y_train)print("最佳估计器", random_search_cv.best_estimator_)print("最佳分数", random_search_cv.best_score_)
7.2 减少参数网格大小
专注于对模型性能产生显著影响的超参数。进行探索性分析或利用领域知识来优先考虑某些参数而非其他参数。
7.3 利用并行处理
在 GridSearchCV 中设置 n_jobs=-1
可以利用所有可用的 CPU 核心,加快计算过程。
7.4 早停
实现早停机制,一旦达到满意的性能水平即停止搜索,防止不必要的计算。
8. 结论和下一步
GridSearchCV 是超参数调优的不可或缺的工具,提供了系统的方法以提升机器学习模型的性能。通过仔细的数据预处理、战略性的参数网格制定以及利用计算优化,数据科学家可以充分发挥 GridSearchCV 的潜力。
下一步:
- 探索 RandomizedSearchCV 以实现更高效的超参数调优。
- 实施交叉验证最佳实践 以确保模型的稳健性。
- 整合特征工程技术 以进一步提升模型性能。
- 在实际场景中部署优化后的模型,并持续监控其性能。
通过掌握 GridSearchCV 及其优化方法,您将能够构建高性能、可靠的机器学习模型,适应多变的数据环境。