2012-04-30 6 views
7

Sto provando a selezionare le migliori caratteristiche usando chi-square (scikit-learn 0.10). Da un totale di 80 documenti di addestramento estraggo innanzitutto la funzionalità 227 e da queste 227 funzionalità voglio selezionare le prime 10.scikit impara: quantità desiderata delle migliori caratteristiche (k) non selezionata

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 

I risultati sono i seguenti.

(80, 227) 
(80, 14) 

Essi sono simili se ho impostato k pari a 100.

(80, 227) 
(80, 227) 

Perché succede?

* EDIT: Un esempio di stampa completo, ora senza clipping, in cui chiedo 30 e ottenuto 32 invece:

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... 

Un altro esempio senza clipping, in cui chiedo 10 ed ottengo 11 invece:

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... 

risposta

5

Hai controllato cosa viene restituito dalla funzione get_support() (ch2 dovrebbe avere questa funzione membro)? Ciò restituisce gli indici selezionati tra i migliori k.

La mia congettura è che ci sono legami dovuti al ritaglio di dati che si sta facendo (o a causa di vettori di caratteristiche ripetute, se i vettori di caratteristiche sono categoriali e sono suscettibili di avere ripetizioni) e che la funzione di scikits restituisce tutti voci che sono legate per i primi punti k. L'esempio in più in cui si imposta k = 100 mette in dubbio questa congettura, ma vale la pena dare un'occhiata.

vedere cosa get_support() rendimenti, e controllare quello che appare come X_train su tali indici, vedere se ritaglio traduce in un sacco di funzionalità di sovrapposizione, la creazione di legami nella chi^2 p-value truppa che SelectKBest sta usando.

Se questo risulta essere il caso, si dovrebbe aprire un bug/problema con scikits.learn perché, al momento la loro documentazione non dice che cosa SelectKBest farà in caso di vincoli. Chiaramente, non è sufficiente prendere alcuni degli indici legati e non altri, ma gli utenti dovrebbero almeno essere avvertiti che i legami potrebbero portare a una riduzione della dimensionalità della funzione inaspettata.

+0

Grazie per la risposta. Ho provato a rimuovere il ritaglio ma ancora non funziona come previsto ... Ho modificato la mia domanda con un output completo (incluso get_support), potresti darci un'occhiata? –

+0

La rottura del legame è davvero il problema. Discuterò con gli altri sviluppatori se questo dovrebbe essere modificato nel codice o nella documentazione. –

+2

https://github.com/scikit-learn/scikit-learn/issues/805 –

Problemi correlati