2014-11-16 14 views
7

Kiedy staram się pracować z LDA z scikit-learn, to wciąż daje tylko ja jeden składnik, chociaż jestem z prośbą o więcej:LDA ignorując 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) 

Daje

/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]]) 

Jak widać , za każdym razem drukuje tylko jeden wymiar. Dlaczego to? Czy ma to coś wspólnego ze współliniowymi zmiennymi?

Dodatkowo, gdy robię to z PCA Scikit-Learn, daje mi to, czego chcę.

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

Czy możesz opublikować, jak wszystko drukować? – pyCthon

+1

To jest tylko w interpreterze Pythona, więc model.transform (x) wyświetli to, co widzisz. –

+0

Ah ok nevermind następnie – pyCthon

Odpowiedz

10

This jest istotne, linia wymiarowa redukujący od LDA.transform, używa scalings_. Jak opisano w docstring, scalings_ ma maksymalnie n_classes - 1 kolumn. Jest to wtedy maksymalna liczba kolumn, które można uzyskać przy użyciu transform. W twoim przypadku 2 klasy (True, False), dają maksymalnie 1 kolumnę.

+0

Nie rozumiem. Jak mogę zmusić LDA do zmniejszenia moich danych z 5 do 4 wymiarów? –

+1

Nie możesz (przynajmniej nie z normalnym vaną lda). Sprawdź [wpis wikipedia na multiclass lda] (http://en.wikipedia.org/wiki/Linear_discriminant_analysis#Multiclass_LDA). Macierz skonstruowana do przechwytywania pomiędzy/w obrębie wariancji klasy ma najwyżej rangi 'n_klasses - 1', co daje tylko najwyżej' n_klasses - 1' kierunki wychwytujące jakąkolwiek wariancję. Dla 2 klas zmniejsza się to dokładnie do 1 wektora dyskryminacyjnego. – eickenberg

+0

Hmmm, ok ... wszędzie, gdzie mogę dowiedzieć się więcej o tym, co konkretnie opisujesz, tj. Czy wyjaśnia to naprawdę jasno i szczegółowo? –