Python scikit学习:未选择所需数量的最佳功能(k)

Python scikit学习:未选择所需数量的最佳功能(k),python,machine-learning,scikit-learn,chi-squared,Python,Machine Learning,Scikit Learn,Chi Squared,我正在尝试使用卡方检验法(scikit learn 0.10)选择最佳功能。从总共80个培训文档中,我首先提取227个特征,并从这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.a

我正在尝试使用卡方检验法(scikit learn 0.10)选择最佳功能。从总共80个培训文档中,我首先提取227个特征,并从这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...

您是否检查了从
get\u support()
函数返回的内容(
ch2
应具有此成员函数)?这将返回在最佳k中选择的索引

我的猜测是,由于您正在进行的数据剪裁(或者由于重复的特征向量,如果您的特征向量是分类的并且可能有重复),因此存在关联,并且scikits函数返回所有与前k个点关联的条目。另外一个例子是设置
k=100
,这让人对这个猜想产生了一些怀疑,但值得一看

查看
get_support()
返回的内容,并检查这些索引上的
X_train
外观,查看剪裁是否会导致大量功能重叠,从而在
SelectKBest
正在使用的chi^2 p值列中创建关联


如果事实证明是这样,您应该向scikits.learn提交一个错误/问题,因为目前他们的文档中没有说明在出现联系时,
SelectKBest
会做什么。显然,它不能只使用一些绑定的索引而不使用其他索引,但至少应该提醒用户,绑定可能会导致意外的功能维度降低。

感谢您的回复。我尝试删除剪辑,但仍然无法按预期工作。。。我已经用完整的输出编辑了我的问题(包括get_support),你能看一下吗?打成平局确实是个问题。我将与其他开发人员讨论是否应该在代码或文档中对此进行更改。@larsmans我从github(1550-g258f193)获得了最后一次提交,现在可以完美地工作。谢谢你这么快的支持,真是太棒了。然而,我仍然无法理解问题是什么(X和Y之间的“平局破裂”)尽管…@DT:当您选择100个特征,并且第100个和第101个特征在chi²测试中具有相同的p值时,
SelectKBest
也会返回第101个特征,可能还会返回第102个特征,等等。它现在总是精确返回100个特征。