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

如何实现分组式递归特征消除(RFE)的分组特征选择功能?

分组式递归特征消除(Group RFE)实现方案

实现思路

原生scikit-learn的RFE默认按单个特征的重要性排序剔除,要实现按组剔除,核心逻辑是将同组特征的重要性聚合为组的重要性得分,每次迭代删除得分最低的整组,直到保留指定数量的分组。

完整可运行代码

导入依赖

import numpy as np
from sklearn.base import BaseEstimator, SelectorMixin
from sklearn.utils.validation import check_is_fitted
from sklearn.svm import SVR
from sklearn.datasets import make_classification

自定义分组RFE类(适配sklearn接口规范)

class GroupRFE(BaseEstimator, SelectorMixin):
    def __init__(self, estimator, n_groups_to_select, groups):
        """
        分组递归特征消除类
        :param estimator: 基估计器,需具备coef_或feature_importances_属性
        :param n_groups_to_select: 需要保留的分组数量(对应当你需求里的n_features_to_select)
        :param groups: 分组列表,每个元素是对应分组的特征索引列表,需覆盖所有特征无重叠
        """
        self.estimator = estimator
        self.n_groups_to_select = n_groups_to_select
        self.groups = groups
        self.n_groups = len(groups)
    
    def fit(self, X, y):
        # 初始化全部保留分组
        keep_groups = list(range(self.n_groups))
        
        while len(keep_groups) > self.n_groups_to_select:
            # 提取当前保留分组对应的所有特征
            selected_features = []
            for g_idx in keep_groups:
                selected_features.extend(self.groups[g_idx])
            X_selected = X[:, selected_features]
            
            # 训练基模型
            self.estimator.fit(X_selected, y)
            
            # 获取特征重要性
            if hasattr(self.estimator, 'coef_'):
                importances = np.abs(self.estimator.coef_).ravel()
            elif hasattr(self.estimator, 'feature_importances_'):
                importances = self.estimator.feature_importances_.ravel()
            else:
                raise ValueError("基估计器需支持coef_或feature_importances_属性")
            
            # 聚合计算每个保留分组的平均重要性
            group_importances = []
            ptr = 0
            for g_idx in keep_groups:
                g_len = len(self.groups[g_idx])
                g_imp = np.mean(importances[ptr:ptr+g_len])
                group_importances.append(g_imp)
                ptr += g_len
            
            # 删除重要性最低的分组
            worst_g_idx = np.argmin(group_importances)
            del keep_groups[worst_g_idx]
        
        # 存储最终结果
        self.support_ = np.zeros(X.shape[1], dtype=bool)
        for g_idx in keep_groups:
            self.support_[self.groups[g_idx]] = True
        self.keep_groups_ = keep_groups
        return self
    
    def _get_support_mask(self):
        check_is_fitted(self)
        return self.support_

使用示例

# 生成示例数据
X, y = make_classification(n_samples=100, n_features=20, random_state=42)

# 定义分组规则:前10列为第1组,11-20列为第2组
groups = [
    list(range(0, 10)),
    list(range(10, 20))
]

# 初始化分组RFE,设置保留1组(对应保留10个特征)
estimator = SVR(kernel="linear")
selector = GroupRFE(estimator, n_groups_to_select=1, groups=groups)

# 训练并转换数据
selector.fit(X, y)
X_selected = selector.transform(X)

# 验证结果
print(f"保留的特征数量:{X_selected.shape[1]}")
print(f"保留的分组索引:{selector.keep_groups_}")

注意事项

  • 传入的groups参数需覆盖所有输入特征,且不存在索引重叠
  • 若你需要保留5组共50个特征,只需将n_groups_to_select设置为5,同时将对应50个特征的分组规则传入groups即可
  • 分组重要性默认采用组内特征重要性的平均值计算,可根据需求修改为求和、最大值等其他聚合逻辑

内容的提问来源于stack exchange,提问作者Talha Anwar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 17:36:04