根据(估计的)特征数量选择 KBest
SelectKBest based on (estimated) amount of features
我正在尝试使用 scikit-learn 实现分层文本分类器,其中一个 "root" 分类器将所有输入字符串排列在 ~50 个类别中的一个(或多个)类别中。对于这些类别中的每一个,我将训练一个新的分类器来解决实际任务。
采用这种两层方法的原因是训练性能和内存问题(应该分离 >1k 类 的分类器表现不佳...)。
对于这些 "subclassifiers"
,我的管道是这样的
pipeline = Pipeline([
('vect', CountVectorizer(strip_accents=None, lowercase=True, analyzer='char_wb', ngram_range=(3,8), max_df=0.1)),
('tfidf', TfidfTransformer(norm='l2')),
('feat', SelectKBest(chi2, k=10000)),
('clf', OneVsRestClassifier(SGDClassifier(loss='log', penalty='elasticnet', alpha=0.0001, n_iter=10))),
])
现在我的问题是:我正在使用 SelectKBest
将模型大小限制在一个合理的范围内,但是对于子分类器,有时没有足够的输入数据可用,所以我什至没有得到10k 功能限制,这导致
(...)
File "/usr/local/lib/python3.4/dist-packages/sklearn/feature_selection/univariate_selection.py", line 300, in fit
self._check_params(X, y)
File "/usr/local/lib/python3.4/dist-packages/sklearn/feature_selection/univariate_selection.py", line 405, in _check_params
% self.k)
ValueError: k should be >=0, <= n_features; got 10000.Use k='all' to return all features.
我不知道如果不应用 CountVectorizer
我会有多少功能,但我必须提前定义管道。我的首选解决方案是跳过 SelectKBest
步骤,如果无论如何都少于 k
功能,但我不知道如何在不调用 CountVectorizer
两次(一次在前进,一次作为管道的一部分)。
对此有什么想法吗?
我认为最干净的选择是子类化 SelectKBest 并在您的实现中回退到身份转换,如果 k 超过输入特征的数量,否则只调用超级实现。
我听从了 的建议并创建了 SelectKBest
的子类来实现所需的功能:
class SelectAtMostKBest(SelectKBest):
def _check_params(self, X, y):
if not (self.k == "all" or 0 <= self.k <= X.shape[1]):
# set k to "all" (skip feature selection), if less than k features are available
self.k = "all"
我试图将这个片段添加到他的回答中,但请求被拒绝了,所以你...
你可以使用SelectPercentile
,如果你没有固定数量的特征,这更有意义。
我正在尝试使用 scikit-learn 实现分层文本分类器,其中一个 "root" 分类器将所有输入字符串排列在 ~50 个类别中的一个(或多个)类别中。对于这些类别中的每一个,我将训练一个新的分类器来解决实际任务。
采用这种两层方法的原因是训练性能和内存问题(应该分离 >1k 类 的分类器表现不佳...)。
对于这些 "subclassifiers"
,我的管道是这样的pipeline = Pipeline([
('vect', CountVectorizer(strip_accents=None, lowercase=True, analyzer='char_wb', ngram_range=(3,8), max_df=0.1)),
('tfidf', TfidfTransformer(norm='l2')),
('feat', SelectKBest(chi2, k=10000)),
('clf', OneVsRestClassifier(SGDClassifier(loss='log', penalty='elasticnet', alpha=0.0001, n_iter=10))),
])
现在我的问题是:我正在使用 SelectKBest
将模型大小限制在一个合理的范围内,但是对于子分类器,有时没有足够的输入数据可用,所以我什至没有得到10k 功能限制,这导致
(...)
File "/usr/local/lib/python3.4/dist-packages/sklearn/feature_selection/univariate_selection.py", line 300, in fit
self._check_params(X, y)
File "/usr/local/lib/python3.4/dist-packages/sklearn/feature_selection/univariate_selection.py", line 405, in _check_params
% self.k)
ValueError: k should be >=0, <= n_features; got 10000.Use k='all' to return all features.
我不知道如果不应用 CountVectorizer
我会有多少功能,但我必须提前定义管道。我的首选解决方案是跳过 SelectKBest
步骤,如果无论如何都少于 k
功能,但我不知道如何在不调用 CountVectorizer
两次(一次在前进,一次作为管道的一部分)。
对此有什么想法吗?
我认为最干净的选择是子类化 SelectKBest 并在您的实现中回退到身份转换,如果 k 超过输入特征的数量,否则只调用超级实现。
我听从了 SelectKBest
的子类来实现所需的功能:
class SelectAtMostKBest(SelectKBest):
def _check_params(self, X, y):
if not (self.k == "all" or 0 <= self.k <= X.shape[1]):
# set k to "all" (skip feature selection), if less than k features are available
self.k = "all"
我试图将这个片段添加到他的回答中,但请求被拒绝了,所以你...
你可以使用SelectPercentile
,如果你没有固定数量的特征,这更有意义。