如何通过GridSearchCV获取带列名的特征重要性分数?
问题:如何从GridSearchCV的Pipeline中获取带列名的特征重要性分数?
我想要获取变量的特征重要性分数,并将其与列名关联生成DataFrame。我使用GridSearchCV进行调参,代码如下:
grid_search = GridSearchCV(model, parameters, cv=10) #tuning grid_search.fit(X_train2, y_train2.values.ravel())
通过grid_search.best_estimator_.named_steps["regressor"].feature_importances_得到的分数数组长度大于数据集列数,无法匹配列名。请问能否直接从GridSearchCV输出带有对应列名的特征重要性分数?以下是我的模型Pipeline供参考:
# Define the pipeline numeric_transformer = Pipeline(steps=[ #('imputer', KNNImputer()), # for missing values ('scaler', StandardScaler()), # standardizing #('scaler', MinMaxScaler()), # normalizing #('to_df', FunctionTransformer(lambda x: pd.DataFrame(x, columns=X_train2.select_dtypes(include=['int64', 'float64']).columns))) ]) categorical_transformer = Pipeline(steps=[ ('onehot', OneHotEncoder(handle_unknown='ignore')) ]) preprocessor = ColumnTransformer( transformers=[ ('num', numeric_transformer, X_train2.select_dtypes(include=['int64', float64']).columns.tolist()), ('cat', categorical_transformer, categorical_cols), # ("pca", PCA(random_state=548, n_components=25), indices_pca), # ('smotenc', SmoteNCWrapper(categorical_features=[1, 2], random_state=548)), ]) model = Pipeline(steps=[ # ('over', SMOTE(random_state=548)), # ('smotenc', SmoteNCWrapper(categorical_features=[1, 2], random_state=548)), ('preprocessor', preprocessor), ('regressor', XGBClassifier(random_state=548)) ]) parameters = { 'regressor__n_estimators': [1000], 'regressor__max_depth': [5], 'regressor__learning_rate': [0.01], # 'regressor__num_leaves': [31], # 'regressor__min_child_samples': [20], 'regressor__reg_alpha': [0.1], 'regressor__reg_lambda': [0.1] }
解决方案
问题根源是分类特征经过OneHotEncoder后会被拆分成多个哑变量,导致预处理后的特征总数远大于原始数据集列数,直接用原始列名匹配必然出错。可以通过以下步骤获取带对应名称的特征重要性:
- 提取预处理后的所有特征名称
从GridSearchCV的最佳模型中取出预处理模块,分别获取数值特征和独热编码后的分类特征名称:
import pandas as pd # 获取最佳模型的预处理步骤 best_preprocessor = grid_search.best_estimator_.named_steps['preprocessor'] # 获取数值特征列名 num_features = best_preprocessor.transformers_[0][2] # 获取独热编码后的分类特征列名 cat_encoder = best_preprocessor.named_transformers_['cat'].named_steps['onehot'] cat_features = cat_encoder.get_feature_names_out(categorical_cols) # 合并所有特征名称 all_features = list(num_features) + list(cat_features)
- 提取特征重要性并生成DataFrame
# 获取特征重要性分数 feature_importances = grid_search.best_estimator_.named_steps['regressor'].feature_importances_ # 生成DataFrame importance_df = pd.DataFrame({ 'feature': all_features, 'importance': feature_importances }).sort_values(by='importance', ascending=False)
生成的DataFrame会准确对应每个预处理后的特征及其重要性分数。如果需要对同一原始分类特征的哑变量分数进行聚合,可根据特征名称前缀分组求和。
内容的提问来源于stack exchange,提问作者Tudor Orosz
相关产品推荐
相关产品推荐

