2014-12-15 11 views
5

Nie widzę, co jest nie tak z moim kodem dla regresywnej regresji liniowej. Unregularized Mam po prostu to, co jestem pewien, rozsądnie jest poprawna:Regresja liniowa numpii z regularyzacją

import numpy as np 

def get_model(features, labels): 
    return np.linalg.pinv(features).dot(labels) 

Oto mój kod na regularyzowanej rozwiązanie, gdzie nie widzę, co jest nie tak:

def get_model(features, labels, lamb=0.0): 
    n_cols = features.shape[1] 
    return linalg.inv(features.transpose().dot(features) + lamb * np.identity(n_cols))\ 
      .dot(features.transpose()).dot(labels) 

Z domyślna wartość 0,0 dla lamb, moim zamiarem jest to, że powinien dać taki sam wynik, jak (poprawna) niezmodyfikowana wersja, ale różnica jest rzeczywiście dość duża.

Czy ktoś widzi, na czym polega problem?

+0

Zaczynam regularyzacji, i uregulowanie liniowy linia regresji produkować krzywą? – duldi

+1

Nie, nadal otrzymasz współczynniki liniowe. Regularyzacja zmieni tylko nachylenie. –

Odpowiedz

6

Problemem jest:

features.transpose().dot(features) nie może być odwracalna. Natomiast numpy.linalg.inv działa tylko dla macierzy pełnowymiarowej zgodnie z dokumentami. Jednakże (niezerowy) termin regularyzacji zawsze czyni równanie niesoumularnym.

Nawiasem mówiąc, masz rację co do wdrożenia. Ale to nie jest wydajne. Skutecznym sposobem rozwiązania tego równania jest metoda najmniejszych kwadratów.

np.linalg.lstsq(features, labels) może wykonać pracę dla np.linalg.pinv(features).dot(labels).

w sposób ogólny, można to zrobić

def get_model(A, y, lamb=0): 
    n_col = A.shape[1] 
    return np.linalg.lstsq(A.T.dot(A) + lamb * np.identity(n_col), A.T.dot(y)) 
+0

Jeśli używasz np.linalg.lstsq(), w jaki sposób pasujesz do terminu regulującego 'lamb'? –

+0

edytuj moją odpowiedź. – nullas

+0

To działa ładnie! Dzięki. Skończyło się na 'np.linalg.lstsq (...) [0]' ponieważ w przeciwnym razie otrzymałem zwrot krotki. Ponadto, czy przypadkiem nie wiesz, dlaczego 'lstsq()' jest bardziej wydajne? –