如何使用来自离散和连续特征混合的互信息来 SelectKBest?

W.P*_*ill 4 feature-selection scikit-learn

我正在使用 scikit learn 来训练分类模型。我的训练数据中既有离散特征也有连续特征。我想使用最大互信息进行特征选择。如果我有向量x和标签y并且前三个特征值是离散的,我可以获得 MMI 值,如下所示:

mutual_info_classif(x, y, discrete_features=[0, 1, 2])
Run Code Online (Sandbox Code Playgroud)

现在我想在管道中使用相同的互信息选择。我想做这样的事情

SelectKBest(score_func=mutual_info_classif).fit(x, y)
Run Code Online (Sandbox Code Playgroud)

但没有办法将离散特征掩码传递给SelectKBest. 是否有一些我忽略的语法可以做到这一点,或者我是否必须编写自己的评分函数包装器?

Viv*_*mar 5

不幸的是,我找不到 SelectKBest 的这个功能。但是我们可以轻松做的是将 扩展SelectKBest为我们的自定义类以覆盖fit()将被调用的方法。

这是SelectKBest的当前fit()方法(取自github 上的源

# No provision for extra parameters here
def fit(self, X, y):
    X, y = check_X_y(X, y, ['csr', 'csc'], multi_output=True)

    ....
    ....

    # Here only the X, y are passed to scoring function
    score_func_ret = self.score_func(X, y)

    ....        
    ....

    self.scores_ = np.asarray(self.scores_)

    return self
Run Code Online (Sandbox Code Playgroud)

现在我们将SelectKBestCustom使用更改的fit(). 我已经从上述来源复制了所有内容,只更改了两行(对此发表了评论):

from sklearn.utils import check_X_y

class SelectKBestCustom(SelectKBest):

    # Changed here
    def fit(self, X, y, discrete_features='auto'):
        X, y = check_X_y(X, y, ['csr', 'csc'], multi_output=True)

        if not callable(self.score_func):
            raise TypeError("The score function should be a callable, %s (%s) "
                        "was passed."
                        % (self.score_func, type(self.score_func)))

        self._check_params(X, y)

        # Changed here also
        score_func_ret = self.score_func(X, y, discrete_features)
        if isinstance(score_func_ret, (list, tuple)):
            self.scores_, self.pvalues_ = score_func_ret
            self.pvalues_ = np.asarray(self.pvalues_)
        else:
            self.scores_ = score_func_ret
            self.pvalues_ = None

        self.scores_ = np.asarray(self.scores_)
        return self
Run Code Online (Sandbox Code Playgroud)

这可以简单地称为:

clf = SelectKBestCustom(mutual_info_classif,k=2)
clf.fit(X, y, discrete_features=[0, 1, 2])
Run Code Online (Sandbox Code Playgroud)

编辑:上述解决方案在管道中也很有用,并且discrete_features在调用fit().

另一个解决方案(不太可取):不过,如果您只需要临时SelectKBest使用mutual_info_classif,(仅分析结果),我们还可以制作一个自定义函数,该函数可以mutual_info_classif使用硬编码的discrete_features. 类似的东西:

def mutual_info_classif_custom(X, y):
    # To change discrete_features, 
    # you need to redefine the function each time
    # Because once the func def is supplied to selectKBest, it cant be changed
    discrete_features = [0, 1, 2]

    return mutual_info_classif(X, y, discrete_features)
Run Code Online (Sandbox Code Playgroud)

上面函数的用法:

selector = SelectKBest(mutual_info_classif_custom).fit(X, y)
Run Code Online (Sandbox Code Playgroud)