You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确使用sklearn.feature_selection.mutual_info_classif?特征选择疑问求解

特征选择中mutual_info_classif的discrete_features参数问题解答

核心结论

mutual_info_classif完全不会自动识别nom__OnlineSecurity_No Internet Service、nom__OnlineSecurity_Yes、nom__OnlineSecurity_No这类独热编码后的列属于同一个原始特征。它会把每一列当成独立的离散特征,单独计算互信息,这会导致同一个原始特征的信息被分散,无法体现其整体重要性。

当前设置的问题

你现在的discrete_features参数设置(判断特征名是否以"nom"开头来标记离散)本身没问题,但因为独热编码拆分了原始特征,最终得到的是每个独热子列的互信息,而非原始特征的整体得分。

解决方案

方案1:编码前计算原始特征的互信息(推荐)

直接对未编码的原始特征计算互信息,这样能得到每个原始特征的整体重要性,再基于此做特征选择,之后再进行编码处理:

# 假设你已经定义了原始特征的分类:标称、序数、数值特征列表
nominal_features = ["OnlineSecurity", ...]  # 原始标称特征
ordinal_features = ["..."]  # 原始序数特征
numerical_features = ["..."]  # 原始数值特征

# 直接对原始特征计算互信息
y_train_final = y_train.map({'No': 0, 'Yes': 1})
mi_raw = mutual_info_classif(
    X=X_train[nominal_features + ordinal_features + numerical_features],
    y=y_train_final,
    # 对应标记每个特征是否离散:标称和序数是离散,数值是连续
    discrete_features=[True]*len(nominal_features) + [True]*len(ordinal_features) + [False]*len(numerical_features)
)

# 生成原始特征的互信息结果表
df_raw_mi = pd.DataFrame({
    'feature': nominal_features + ordinal_features + numerical_features,
    'mi': mi_raw
}).sort_values(by='mi', ascending=False)
display(df_raw_mi.style.background_gradient(cmap='coolwarm'))

方案2:编码后对独热特征分组聚合

如果必须在编码后计算,可以通过特征名前缀提取原始特征,对互信息得分做聚合(求和/均值),得到原始特征的整体得分:

def isolate():
    composer.fit(X=X_train)
    X_train_final = composer.transform(X=X_train)
    y_train_final = y_train.map({'No': 0, 'Yes': 1})
    mi = mutual_info_classif(
        X=X_train_final, 
        y=y_train_final,
        # 序数编码的特征也标记为离散
        discrete_features=[feature.startswith("nom") or feature.startswith("ord") for feature in composer.get_feature_names_out()]
    )
    df_c = pd.DataFrame()
    df_c['mi'] = mi
    df_c['feature'] = composer.get_feature_names_out()
    
    # 从编码后的特征名中提取原始特征名(分割__取前两部分)
    df_c['original_feature'] = df_c['feature'].apply(lambda x: '__'.join(x.split('__')[:2]))
    
    # 按原始特征分组,求和得到整体互信息
    df_original_mi = df_c.groupby('original_feature')['mi'].sum().reset_index()
    display(df_original_mi.sort_values(by='mi', ascending=False).style.background_gradient(cmap='coolwarm'))

isolate()

补充说明

  • 序数编码如果是单列形式(没有拆分成独热),当前的离散标记逻辑是合理的,mutual_info_classif可以正确处理这类离散的有序特征。
  • 如果序数特征也做了独热编码,同样需要用方案2的分组聚合方式计算原始特征的整体互信息。

内容的提问来源于stack exchange,提问作者Jason Rich Darmawan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 08:45:30