Scikit Learn:未选择所需数量的最佳特征(k)

8

我正在尝试使用卡方检验(scikit-learn 0.10)选择最佳特征。从80个训练文档中,我首先提取了227个特征,然后从这些特征中选择前10个。

my_vectorizer = CountVectorizer(analyzer=MyAnalyzer())      
X_train = my_vectorizer.fit_transform(train_data)
X_test = my_vectorizer.transform(test_data)
Y_train = np.array(train_labels)
Y_test = np.array(test_labels)
X_train = np.clip(X_train.toarray(), 0, 1)
X_test = np.clip(X_test.toarray(), 0, 1)    
ch2 = SelectKBest(chi2, k=10)
print X_train.shape
X_train = ch2.fit_transform(X_train, Y_train)
print X_train.shape

以下是结果。
(80, 227)
(80, 14)

如果我将k设置为100,它们是相似的。
(80, 227)
(80, 227)

为什么会发生这种情况?

*编辑:一个完整的输出示例,现在没有剪切,我请求30而得到了32:

Train instances: 9 Test instances: 1
Feature extraction...
X_train:
[[0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 1 0 1 1 0 1 1 0 0 0 1 0 1 0 0 0 0 1 1 1 0 0 1 0 0 1 0 0 0 0]
 [0 0 2 1 0 0 0 0 0 1 0 0 0 1 1 0 0 0 1 0 0 0 0 1 0 1 1 0 0 1 0 1]
 [1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0]
 [0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0]]
Y_train:
[0 0 0 0 0 0 0 0 1]
32 features extracted from 9 training documents.
Feature selection...
(9, 32)
(9, 32)
Using 32(requested:30) best features from 9 training documents
get support:
[ True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True  True]
get support with vocabulary :
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 25 26 27 28 29 30 31]
Training...
/usr/local/lib/python2.6/dist-packages/scikit_learn-0.10-py2.6-linux-x86_64.egg/sklearn/svm/sparse/base.py:23: FutureWarning: SVM: scale_C will be True by default in scikit-learn 0.11
  scale_C)
Classifying...

以下是一个没有剪切的例子,当我请求10时,实际得到了11:

Train instances: 9 Test instances: 1
Feature extraction...
X_train:
[[0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 1 0 1 1 0 1 1 0 0 0 1 0 1 0 0 0 0 1 1 1 0 0 1 0 0 1 0 0 0 0]
 [0 0 2 1 0 0 0 0 0 1 0 0 0 1 1 0 0 0 1 0 0 0 0 1 0 1 1 0 0 1 0 1]
 [1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0]
 [0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0]]
Y_train:
[0 0 0 0 0 0 0 0 1]
32 features extracted from 9 training documents.
Feature selection...
(9, 32)
(9, 11)
Using 11(requested:10) best features from 9 training documents
get support:
[ True  True  True False False  True False False False False  True False
 False False  True False False False  True False  True False  True  True
 False False False False  True False False False]
get support with vocabulary :
[ 0  1  2  5 10 14 18 20 22 23 28]
Training...
/usr/local/lib/python2.6/dist-packages/scikit_learn-0.10-py2.6-linux-x86_64.egg/sklearn/svm/sparse/base.py:23: FutureWarning: SVM: scale_C will be True by default in scikit-learn 0.11
  scale_C)
Classifying...
1个回答

5
你是否检查了get_support()函数的返回值(假设ch2有这个成员函数)?它返回在最佳的k个特征选择中被选中的索引。
我的猜测是,由于你正在进行数据剪辑(或者由于特征向量是分类变量且可能出现重复),存在并列的情况,scikits函数返回所有与前k个位置并列的条目。你设置k = 100的额外示例对这个猜测产生了一些怀疑,但还是值得一看。
看看get_support()返回的内容,并检查在这些索引上X_train的样子,看看剪辑是否导致特征重叠较多,在SelectKBest使用的卡方p值排名中造成并列的情况。
如果是这种情况,你应该向scikits.learn提交错误/问题报告,因为当前他们的文档没有说明在并列时SelectKBest会发生什么。显然,它不能只取其中一些并不取其他的并列索引,但用户至少应该被警告说并列可能会导致意外的特征维数减少。

谢谢您的回复。我尝试过去掉剪切,但仍然不能按预期工作...我已经编辑了我的问题,并提供了完整的输出(包括get_support),您能否请看一下? - D T
决定胜负确实是个问题。我会与其他开发人员讨论,无论是在代码还是文档中是否应该进行更改。 - Fred Foo
@larsmans 我从Github上获取了最新的提交记录(1550-g258f193),现在一切都运行得很完美。感谢您如此快速的支持,真是太棒了。不过,我仍然无法理解问题出在哪里(X和Y之间的“决策”?)... - D T
1
@DT: 当你选择了100个特征,并且第100个和第101个特征在卡方检验中具有相同的p值时,SelectKBest将返回第101个特征,以及可能还会返回第102个等。现在它总是返回确切的100个特征。 - Fred Foo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接