2012-04-30 12 views
7

Estoy tratando de seleccionar las mejores características usando chi-square (scikit-learn 0.10). De un total de 80 documentos de capacitación, primero extraigo 227 características, y de estas 227 funciones, quiero seleccionar las 10 mejores.scikit learn: cantidad deseada de Best Features (k) no seleccionado

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 

Los resultados son los siguientes.

(80, 227) 
(80, 14) 

Ellos son similares si fijo igual a k100.

(80, 227) 
(80, 227) 

¿Por qué sucede esto?

* EDIT: Un ejemplo de salida completa, ahora sin recorte, donde solicito 30 y tengo 32 en su lugar:

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

Otro ejemplo sin recorte, donde solicito 10 y obtener 11 en su lugar:

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

Respuesta

5

¿Ha comprobado qué devuelve la función get_support() (ch2 debería tener esta función miembro)? Esto devuelve los índices seleccionados entre los mejores k.

Mi conjetura es que hay lazos debido al recorte de datos que estás haciendo (o debido a vectores de características repetidas, si tus vectores de características son categóricos y es probable que tengan repeticiones), y que la función scikits devuelve todo entradas que están vinculadas a los mejores k puntos. El ejemplo adicional en el que establece k = 100 arroja algunas dudas sobre esta conjetura, pero vale la pena verlo.

Véase lo get_support() devoluciones, y comprobar lo X_train se parece en esos índices, a ver si de recorte da como resultado una gran cantidad de superposición de caracteres, crear lazos en el chi^2 p-valor que ocupa el SelectKBest está utilizando.

Si este es el caso, debe presentar un error/problema con scikits.learn, porque actualmente su documentación no indica qué hará SelectKBest en caso de empate. Claramente, no se puede simplemente tomar algunos de los índices empatados y no otros, pero los usuarios deberían al menos ser advertidos de que los vínculos podrían resultar en una reducción inesperada de la dimensionalidad de las características.

+0

Gracias por su respuesta. Intenté eliminar el recorte, pero todavía no funciona como esperaba ... He editado mi pregunta con un resultado completo (incluido get_support), ¿podría echar un vistazo? –

+0

Tiebreak es de hecho el problema. Discutiré con los otros desarrolladores si esto debería cambiarse en el código o en la documentación. –

+2

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

Cuestiones relacionadas