2014-11-16 15 views
7

Quando sto cercando di lavorare con LDA da scikit-learn, si continua solo a me dare un componente, anche se io chiedo di più:LDA ignorando n_components?

>>> from sklearn.lda import LDA 
>>> x = np.random.randn(5,5) 
>>> y = [True, False, True, False, True] 
>>> for i in range(1,6): 
...  lda = LDA(n_components=i) 
...  model = lda.fit(x,y) 
...  model.transform(x) 

/Users/orthogonal/virtualenvs/osxml/lib/python2.7/site-packages/sklearn/lda.py:161: UserWarning: Variables are collinear 
    warnings.warn("Variables are collinear") 
array([[-0.12635305], 
     [-1.09293574], 
     [ 1.83978459], 
     [-0.37521856], 
     [-0.24527725]]) 
array([[-0.12635305], 
     [-1.09293574], 
     [ 1.83978459], 
     [-0.37521856], 
     [-0.24527725]]) 
array([[-0.12635305], 
     [-1.09293574], 
     [ 1.83978459], 
     [-0.37521856], 
     [-0.24527725]]) 
array([[-0.12635305], 
     [-1.09293574], 
     [ 1.83978459], 
     [-0.37521856], 
     [-0.24527725]]) 
array([[-0.12635305], 
     [-1.09293574], 
     [ 1.83978459], 
     [-0.37521856], 
     [-0.24527725]]) 

Come si può vedere , stampa solo una dimensione ogni volta. Perchè è questo? Ha qualcosa a che fare con le variabili collineare?

Inoltre, quando faccio questo con Scikit-Learn PCA, mi dà quello che voglio.

>>> from sklearn.decomposition import PCA 
>>> for i in range(1,6): 
...  pca = PCA(n_components=i) 
...  model = pca.fit(x) 
...  model.transform(x) 
... 
array([[ 0.83688322], 
     [ 0.79565477], 
     [-2.4373344 ], 
     [ 0.72500848], 
     [ 0.07978792]]) 
array([[ 0.83688322, -1.56459039], 
     [ 0.79565477, 0.84710518], 
     [-2.4373344 , -0.35548589], 
     [ 0.72500848, -0.49079647], 
     [ 0.07978792, 1.56376757]]) 
array([[ 0.83688322, -1.56459039, -0.3353066 ], 
     [ 0.79565477, 0.84710518, -1.21454498], 
     [-2.4373344 , -0.35548589, -0.16684946], 
     [ 0.72500848, -0.49079647, 1.09006296], 
     [ 0.07978792, 1.56376757, 0.62663807]]) 
array([[ 0.83688322, -1.56459039, -0.3353066 , 0.22196922], 
     [ 0.79565477, 0.84710518, -1.21454498, -0.15961993], 
     [-2.4373344 , -0.35548589, -0.16684946, -0.04114339], 
     [ 0.72500848, -0.49079647, 1.09006296, -0.2438673 ], 
     [ 0.07978792, 1.56376757, 0.62663807, 0.2226614 ]]) 
array([[ 8.36883220e-01, -1.56459039e+00, -3.35306597e-01, 
      2.21969223e-01, -1.66533454e-16], 
     [ 7.95654771e-01, 8.47105182e-01, -1.21454498e+00, 
     -1.59619933e-01, 3.33066907e-16], 
     [ -2.43733440e+00, -3.55485895e-01, -1.66849458e-01, 
     -4.11433949e-02, 0.00000000e+00], 
     [ 7.25008484e-01, -4.90796471e-01, 1.09006296e+00, 
     -2.43867297e-01, -1.38777878e-16], 
     [ 7.97879229e-02, 1.56376757e+00, 6.26638070e-01, 
      2.22661402e-01, 2.22044605e-16]]) 
+0

puoi pubblicare come la tua stampa di tutto? – pyCthon

+1

Questo è solo nell'interprete Python, quindi model.transform (x) genererà ciò che vedi. –

+0

Ah ok non importa quindi – pyCthon

risposta

10

This è pertinente, linea di quota di riduzione di LDA.transform, utilizza scalings_. Come descritto nello docstring, scalings_ ha al massimo n_classes - 1 colonne. Questo è quindi il numero massimo di colonne che puoi sperare di ottenere usando transform. Nel tuo caso, 2 classi (True, False), produce massimo 1 colonna.

+0

Non capisco. Come posso ottenere che LDA riduca i miei dati da 5 a 4 dimensioni? –

+1

Non è possibile (almeno non con normale vanilla lda). Controlla [la voce wikipedia su lda multiclass] (http://en.wikipedia.org/wiki/Linear_discriminant_analysis#Multiclass_LDA). La matrice che è costruita per catturare tra/all'interno delle varianze di classe è di rango al massimo 'n_classes - 1', dando così solo la maggior parte delle direzioni' n_classes - 1' che catturano qualsiasi varianza. Per 2 classi questo si riduce a esattamente 1 vettore discriminante. – eickenberg

+0

Hmmm, ok ... dovunque potrei imparare di più su ciò che stai descrivendo, cioè che lo spiega in modo molto chiaro e con dettagli? –