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. 是否有一些我忽略的语法可以做到这一点,或者我是否必须编写自己的评分函数包装器?
不幸的是,我找不到 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)