Python中多数据集多分类器下GridSearchCV迭代寻优实现
代码问题修正说明
你现有代码存在几类可直接导致运行失败/结果不符合预期的问题:
- 语法错误:
params2字典内classifier参数赋值误用等号=,且字典缺少闭合花括号 - 变量未定义:代码引用了不存在的
subset_features变量,会直接触发名称错误 - 输入格式不兼容:
GridSearchCV不支持直接传入字典结构的多组特征/标签,必须逐数据集单独执行网格搜索,无法一次性传入所有数据集完成拟合 - 冗余预处理:当前管道默认对所有分类器执行特征标准化,随机森林属于树模型,对特征尺度不敏感,标准化操作不会提升效果,属于冗余计算
- 结果不可复现:所有分类器的
random_state设为None,每次运行的最优参数结果会随机波动,固定随机种子可保证结果可复现
修正后可运行实现
import pandas as pd import numpy as np from sklearn.experimental import enable_iterative_imputer from sklearn.impute import IterativeImputer from sklearn.base import BaseEstimator, TransformerMixin from sklearn.preprocessing import StandardScaler from sklearn.compose import ColumnTransformer from sklearn.pipeline import Pipeline from sklearn.model_selection import GridSearchCV from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier # 固定随机种子保证结果可复现 np.random.seed(42) RANDOM_STATE = 42 # 多数据集特征/标签 X = {'df1': np.random.normal(0, 1, (200, 5)), 'df2': np.random.normal(0, 1, (200, 5))} y = {'df1': np.random.choice([0, 1], 200), 'df2': np.random.choice([0, 1], 200)} # 数值列索引(numpy数组按位置索引,DataFrame可替换为列名字符串列表) num_columns = [0,1,2,3,4] num_transformer = Pipeline([ ('imputer', IterativeImputer(random_state=RANDOM_STATE)), ('scaler', StandardScaler()) ]) # 列预处理器 ct = ColumnTransformer([('numeric_pipeline', num_transformer, num_columns)]) # 初始化分类器 clf1 = LogisticRegression(solver='liblinear', random_state=RANDOM_STATE) clf2 = RandomForestClassifier(random_state=RANDOM_STATE) # 基础管道 pipe = Pipeline([('ct', ct), ('classifier', clf1)]) # 两个分类器的参数搜索空间 params1 = { 'classifier__penalty': ['l1', 'l2'], 'classifier__C': [0.1, 1, 10], 'classifier': [clf1] } params2 = { 'classifier__n_estimators': [100, 150, 200], 'classifier__min_samples_leaf': [1, 2], 'classifier': [clf2] } params = [params1, params2] # 逐数据集执行网格搜索,存储每个数据集的最优结果 dataset_best_results = {} for dataset_name, X_data in X.items(): y_data = y[dataset_name] # 初始化网格搜索,可根据需求设置cv折数、评分指标 gs = GridSearchCV(pipe, params, cv=5, scoring='accuracy') gs.fit(X_data, y_data) # 保存当前数据集的最优参数、最优得分 dataset_best_results[dataset_name] = { 'best_params': gs.best_params_, 'best_cv_score': gs.best_score_ } # 打印所有数据集的最优结果 for name, res in dataset_best_results.items(): print(f"===== 数据集{name}最优结果 =====") print(f"最优参数:{res['best_params']}") print(f"交叉验证最优得分:{res['best_cv_score']:.4f}\n")
如果你需要让随机森林跳过标准化步骤,可以分别为两个分类器构建独立管道,再传入GridSearchCV做搜索,能减少不必要的计算量。
内容的提问来源于stack exchange,提问作者GSA
相关产品推荐
相关产品推荐

