Sveučilište u Zagrebu
Fakultet elektrotehnike i računarstva
http://www.fer.unizg.hr/predmet/su
Ak. god. 2014./2015.
(c) 2014 Jan Šnajder
Verzija 1.1
Objavljeno: 29. prosinca 2014.
Rok za predaju: 11. siječnja 2015.
Druga se laboratorijska vježba bavi modelom linearne regresije i linearnim diskriminativnim modelima. Vježba dakle pokriva sljedeće teme obrađene na predavanjima: 1. Regresija, 2. Linearni diskriminativni modeli, 3. Logistička regresija. Općenita svrha vježbe jest bolje razumijevanja rada algoritama i njihove matematičke podloge te stjecanje iskustva rada s podatcima.
Podsjetite se rada u SciPy ekosustavu. Poveznice na relevantne resurse navedene su u uvodnome dijelu prve laboratorijske vježbe.
Pročitajte relevante materijale s predavanja i po potrebi konzultirajte dodatnu literaturu:
Vježba se sastoji od više zadataka grupiranih u tri teme. U nastavku slijedite upute navedene u ćelijama s tekstom. Rješavanje vježbe svodi se na dopunjavanje ove bilježnice: umetanja ćelije ili više njih ispod teksta zadatka, pisanja odgovarajućeg koda te evaluiranja ćelija.
Molim Vas, osigurajte se da u potpunosti razumijete kod koji ste napisali. Kod predaje vježbe, morate biti u stanju na zahtjev asistenta preinačiti i ponovno evaluirati Vaš kod. Nadalje, morate razumjeti teorijske osnove onoga što radite, u okvirima onoga što smo obradili na predavanju. Stoga se nemojte ograničiti samo na to da riješite zadatak, već slobodno eksperimentirajte. To upravo i jest svrha ovih vježbi.
Vježbe trebate raditi samostalno. Možete se konzultirati s drugima o načelnom načinu rješavanja, ali u konačnici morate sami odraditi vježbu. U protivnome vježba nema smisla.
# Učitaj osnovne biblioteke...
import scipy as sp
import sklearn
%pylab inline
Zadan je skup primjera $\mathcal{D}=\{(x^{(i)},y^{(i)})\}_{i=1}^4 = \{(0,4),(1,1),(2,2),(4,5)\}$. Primjere predstavite matricom $\mathbf{X}$ dimenzija $N\times n$ (u ovom slučaju $4\times 1$) i vektorom oznaka $\textbf{y}$, dimenzija $N\times 1$ (u ovom slučaju $4\times 1$), na sljedeći način:
X = sp.array([[0],[1],[2],[4]])
y = sp.array([4,1,2,5])
Proučite funkciju PolynomialFeatures
i upotrijebite je za generiranje dizajn-matrice $\mathbf{\Phi}$ sa $m=n$. Drugim riječima, generirajte dizajn-matricu bez preslikavanja u prostor više dimenzije (samo će svakom primjeru biti dodane dummy jedinice).
from sklearn.preprocessing import PolynomialFeatures
Upoznajte se s modulom linalg
. Izračunajte težine $\tilde{\mathbf{w}}$ modela linearne regresije kao $\tilde{\mathbf{w}}=(\mathbf{\Phi}^\intercal\mathbf{\Phi})^{-1}\mathbf{\Phi}^\intercal\mathbf{y}$. Zatim se uvjerite da isti rezultat možete dobiti izračunom pseudoinverza $\mathbf{\Phi}^+$ dizajn-matrice, tj. $\tilde{\mathbf{w}}=\mathbf{\Phi}^+\mathbf{y}$, korištenjem funkcije pinv
.
from scipy import linalg
Prikažite u ravnini (funkcija plot
) primjere iz $\mathcal{D}$ i funkciju $h(x)=\mathbf{\tilde{w}}^\intercal\tilde{\mathbf{x}}$. Izračunajte empirijsku pogrešku kao $E(h|\mathcal{D})=\frac{1}{2}\sum_{i=1}^N((y^{(i)} - h(x^{(i)}))^2$. Možete koristiti funkciju srednje kvadratne pogreške mean_squared_error
iz modula sklearn.metrics
.
from sklearn.metrics import mean_squared_error
Q: Gore definirana funkcija pogreške $E(h|\mathcal{D})$ i funkcija srednje kvadrante pogreške nisu posve identične. U čemu je razlika? Koja je funkcija korisnija u praksi? Zašto?
Uvjerite se da za primjere iz $\mathcal{D}$ težine $\tilde{\mathbf{w}}$ ne možemo naći rješavanjem sustava $\tilde{\mathbf{w}}=\mathbf{\Phi}^{-1}\mathbf{y}$, već da nam doista treba pseudoinverz.
Q: Zašto je to slučaj? Bi li se problem mogao riješiti preslikavanjem primjera u višu dimenziju? Ako da, bi li to uvijek funkcioniralo, neovisno o skupu primjera $\mathcal{D}$? Pokažite na primjeru.
Proučite klasu LinearRegression
iz modula sklearn.linear_model
. Uvjerite se da su težine koje izračunava ta funkcija (dostupne pomoću članova klase coef_
i intercept_
) jednake onima koje ste izračunali gore. Izračunajte predikcije modela (metoda predict
) i uvjerite se da je empirijska pogreška identična kao i ona koju ste ranije izračunali.
from sklearn.linear_model import LinearRegression
Razmotrimo sada regresiju na većem broju primjera. Definirajte funkciju make_labels(X,f,noise=0)
koja uzima matricu neoznačenih primjera $\mathbf{X}_{N\times n}$ te generira vektor njihovih oznaka $\mathbf{y}_{N\times 1}$. Oznake se generiraju kao $y^{(i)} = f(x^{(i)})+\mathcal{N}(0,\sigma^2)$, gdje je $f:\mathbb{R}^n\to\mathbb{R}$ stvarna funkcija koja je generirala podatke (koja nam je u stvarnosti nepoznata), a $\sigma$ je standardna devijacija Gaussovog šuma, definirana parametrom noise
. Za generiranje šuma možete koristiti funkciju numpy.random.normal
.
U nastavku ćemo se i dalje usredotočiti na jednodimenzijske primjere ($n=1$). Generirajte skup za učenje od $N=50$ jednodimenzijskih primjera uniformno distribuiranih u intervalu $[-5,5]$ pomoću funkcije $f(x) = 5 + x -2 x^2 -5 x^3$ uz šum $\sigma=200$:
#generira N jednodimenzijskih primjera uniformno u intervalu [x1,x2]
def make_instances(x1,x2,N) :
return sp.array([sp.array([x]) for x in linspace(x1,x2,N)])
Prikažite taj skup funkcijom scatter
.
Trenirajte model polinomijalne regresije stupnja $d=3$. Na istom grafikonu prikažite naučeni model $h(\mathbf{x})=\tilde{\mathbf{w}}^\intercal\tilde{\mathbf{x}}$ i primjere za učenje. Izračunajte empirijsku pogrešku modela.
Na skupu iz prethodnog zadatka trenirajte pet modela linearne regresije $\mathcal{H}_d$ različite složenosti, gdje je $d$ stupanj polinoma, $d\in\{1,3,5,10,20\}$. Prikažite na istome grafikonu skup za učenje i funkcije $h_d(\mathbf{x})$ za svih pet modela (preporučujemo koristiti plot
unutar for
petlje). Po potrebi, raspon grafa možete regulirati funkcijom ylim
. Izračunajte empirijsku pogrešku svakog od modela.
Q: Koji model ima najmanju empirijsku pogrešku i zašto?
Razdvojite skup primjera iz prethodnog zadatka pomoću funkcije cross_validation.train_test_split
na skup za učenja i skup za ispitivanje u omjeru 1:1.
from sklearn import cross_validation
Prikažite na jednom grafikonu funkciju empirijske pogreške i pogreške generalizacije za modele polinomijalne regresije $\mathcal{H}_d$, sa stupnjem polinoma $d$ u rasponu $d\in\{1,2,\dots,20\}$. Budući da kvadratna pogreška brzo raste za veće stupnjeve polinoma, umjesto da plotate izravno empirijsku pogrešku i pogrešku generazacije, plotajte logaritam tih pogrešaka.
NB: Podjela na skupa za učenje i skup za ispitivanje mora za svih dvadeset modela biti identična.
Q: Je li rezultat u skladu s očekivanjima? Koji biste model odabrali i zašto?
Q: Pokrenite iscrtavanje više puta. U čemu je problem? Kako biste riješili taj problem? Bi li problem bio jednako izražen kad bismo imali više primjera? Zašto?
Točnost modela ovisi o (1) njegovoj složenosti (stupanj $d$ polinoma), (2) broju primjera $N$, i (3) količini šuma. Kako biste to analizirali, nacrtajte grafikone pogrešaka kao u A.8, ali za sve kombinacija broja primjera $N\in\{100,200,1000\}$ i količine šuma $\sigma\in\{100,200,500\}$ (ukupno 9 grafikona). Upotrijebite funkciju subplots
kako biste pregledno posložili grafikone u tablicu $3\times 3$. Podatci se generiraju na isti način kao u zadatku A.5.
NB: Pobrinite se da svi grafikoni budu generirani nad usporedivim skupovima podataka, na sljedeći način: generirajte najprije svih 1000 primjera, zatim ih podijelite na skupove za učenje i skupove za ispitivanje (dva skupa od po 500 primjera), zatim generirajte tri parova skupova s različitom količinom šuma te naposlijetku generirajte dodatne podskupove od $N=200$ (dva puta po $100$) primjera i $N=100$ (dva puta po $50$) primjera.
Q: Jesu li rezultati očekivani? Obrazložite.
U gornjim eksperimentima nismo koristili regularizaciju. Vratite se na primjer iz A.1. Na primjerima iz tog zadatka izračunajte težine $\tilde{\mathbf{w}}$ za polinomijalni regresijski model stupnja $d=3$ uz L2-regularizaciju (ili ridge regularization), prema izrazu $\tilde{\mathbf{w}}=(\mathbf{\Phi}^\intercal\mathbf{\Phi}+\lambda\mathbf{I})^{-1}\mathbf{\Phi}^\intercal\mathbf{y}$. Jediničnu matricu možete generirati funkcijom identity
. Napravite izračun težina za regularizacijske faktore $\lambda=0$, $\lambda=1$ i $\lambda=10$ te usporedite dobivene težine.
Q: Kojih je dimenzija matrica koju treba invertirati?
Q: Po čemu se razlikuju dobivene težine i je li ta razlika očekivana? Obrazložite.
Proučite klasu Ridge
iz modula sklearn.linear_model
, koja implementira L2-regularizirani linearni regresijski model. Parametar $\alpha$ klase Ridge
predstavlja regularizacijski faktor $\lambda$. Primijenite model na istim primjerima kao u zadatku A.10 i ispišite težine $\tilde{\mathbf{w}}$ (članovi klase coef_
i intercept_
).
from sklearn.linear_model import Ridge
Q: Jesu li težine identične onima iz zadatka A.10? Ako težine nisu identične, razlika bi mogla biti uzrokovana time što ste u zadatku A.10 regularizaciju primijenili i na težinu $w_0$. Kako biste to ispravili?
Vratimo se na slučaj $N=50$ slučajno generiranih primjera iz zadatka A5. Trenirajte modele polinomijalne regresije $\mathcal{H}_{\lambda,d}$ za $\lambda\in\{0,100\}$ i $d\in\{2,10\}$ (četiri modela). Skicirajte pripadne funkcije $h(\mathbf{x})$ i primjere (na jednom grafikonu; preporučujemo koristiti plot
unutar for
petlje).
Q: Jesu li rezultati očekivani? Obrazložite.
Q: Za koji od ova četiri modela biste očekivali da će najbolje generalizirati? Zašto?
Kao u zadataku A.8, razdvojite primjere na skup za učenje i skup za ispitivanje u omjeru 1:1. Prikažite krivulje logaritama empirijske pogreške i pogreške generalizacije u ovisnosti za model $\mathcal{H}_{d=20,\lambda}$, podešavajući faktor regularizacije $\lambda$ u rasponu $\lambda\in\{0,1,\dots,50\}$.
Q: Kojoj strani na grafikonu odgovara područje prenaučenosti a kojoj podnaučenosti. Zašto?
Q: Koju biste vrijednosti za $\lambda$ izabrali na temelju ovih grafikona i zašto?
Q: Jesu li rezultati stabilni? Zašto?
Svrha regularizacije jest potiskivanje težina modela $\mathbf{w}$ prema nuli, kako bi model bio što jednostavniji. Složenost modela može se okarakterizirati kao duljina vektora $\mathbf{w}$ (L2-norma vektora, tj. $\|\mathbf{w}\|_2$) ili kao broj ne-nul elemenata u vektoru $\mathbf{w}$ (funkcija nonzeroes
; v. dolje). Prikažite te dvije veličine kao funkcije od faktora regularizacije $\lambda$, gdje $\lambda\in\{1,100\}$, za model polinomijalne regresije stupnja $d=20$.
def nonzeroes(coef) : return size(coef[coef!=0])
Q: Objasnite oblik obiju krivulja. Hoće li krivulja za $\|\mathbf{w}\|_2$ doseći nulu? Zašto? Je li to problem? Zašto?
Q: Za $\lambda=100$, koliki je postotak težina modela jednak nuli, odnosno koliko je model rijedak?
Glavna prednost L1-regularizirane regresije (ili Lasso regression) nad L2-regulariziranom regresijom jest u tome što L1-regularizirana regresija rezultira rijetkim modelima (engl. sparse models), odnosno modelima kod kojih su mnoge težine pritegnute na nulu. Pokažite da je to doista tako, ponovivši gornji eksperiment s L1-regulariziranom regresijom, implementiranom u klasi Lasso
u modulu sklearn.linear_model
.
from sklearn.linear_model import Lasso
Q: Kojem biste modelu (Ridge ili Lasso) u praksi dali prednost, i zašto? U kojim situacijama je ta prednost osobito izražena?
Do sada smo razmatrali isključivo univarijatnu regresiju, tj. imali smo samo jednu značajku ($n=1$). U većini stvarnih problema baratamo s većim brojem značajki. Razmotrimo sada jedan nešto realniji problem, kod kojega postoji više značajki, pa je potrebno napraviti multivarijatnu regresiju.
Učitajte skup podataka Boston House Prices:
from sklearn.datasets import load_boston
boston = load_boston()
print boston.data.shape
print boston.target.shape
Skup sadrži 506 primjera sa 13 numeričkih značajki. Opis skupa možete dobiti na sljedeći način:
print boston.DESCR
Vaš je zadatak da izgradite regresijski model za predviđanje cijene nekretnine (y=boston.target
) na temelju 13 raspoloživih značajki za svaku nekretninu (X=boston.data
). Cilj je pronaći najbolji mogući linearan model regresije na ovom skupu podataka i provjeriti njegovu točnost u smislu pogreške kvadratnog odstupanja (mean_squared_error
). Hiperparametri modela koje treba isprobati su:
LinearRegression
), L2-regularizacija (Ridge
) i L1-regularizacija (Lasso
);interaction_only
u klasi PolynomialFeatures
);preprocessing.scale
.Kao i inače, za odabir i ispitivanje modela koristit ćemo unakrsnu provjeru (engl. cross-validation). Skup primjera za učenje podijelit ćemo na skup za učenje, skup za provjeru i skup za ispitivanje u omjeru (otprilike) 3:1:1. Kao i uvijek, model trebate trenirati na skupu za učenje, odabir modela (odnosno optimizaciju hiperparametra) trebate provesti na skupu za provjeru, a konačno vrednovanje modela trebate načiniti na skupu za ispitivanje. Konačno vrednovanje radite samo jednom, za model koji ste odabrali kao optimalan.
NB: Nakon što odaberete optimalan model na skupu za provjeru, prije konačnog ispitivanje odabrani model ponovno trenirajte na uniji skupova za učenje i ispitivanje. Na taj način maksimalno iskorištavate dostupne podatke i model će u pravilu biti bolji.
Podjela na skup za učenje, provjeru i ispitivanje u ovom je slučaju fiksna kako bi svi imali identične skupove i kako bi rezultati bili usporedivi. (U stvarnosti biste ovakav eksperiment radili malo drugačije: koristili biste višestruku unakrsnu provjeru ili ugnježđenu unakrsnu provjeru. Više o tome u idućoj laboratorijskoj vježbi.) Koristite ove skupove:
from sklearn import cross_validation
X_train, X_rest, y_train, y_rest = cross_validation.train_test_split(boston.data,boston.target,train_size=0.6,random_state=42)
X_validate, X_test, y_validate, y_test = cross_validation.train_test_split(X_rest,y_rest,test_size=0.5,random_state=42)
print X_train.shape, X_validate.shape ,X_test.shape
Q: Koliko značajki ima svaki od modela koji ste isprobali?
Q: Koliko je zapravo dobar model koji ste trenirali? Bi li model bio dovoljno dobar za stvarnu uporabu? Možete li to odlučiti na temelju mjere srednjeg kvadratnog odstupanja, ili bi neki drugi pokazatelj bio korisniji?
Q: Provjerite točnost odabranog modela na (1) skupu za učenje, (2) skupu za provjeru, (3) uniji ta dva skupa i (4) skupu za ispitivanje. Jesu li odnosi između točnosti modela na ova četiri skupa očekivana? Obrazložite.
Q: Kod treniranja regresijskog modela moguće je postaviti fit_intercept=False
, čime se izbjegava optimiranje težine $w_0$. Trenirajte odabrani model s tom postavkom. Usporedite s točnošću optimalnog modela. Je li rezultat očekivan? Obrazložite. Ima li predobrada značajki ikakvog utjecaja na ovu razliku?
Magnitude težina $w_i$ upućuju na važnost odgovarajućih značajki $x_i$ u modelu. Načinite jednostavnu analizu značajki tako da ispišete rang-liste značajki s obzirom na težine (značajke veće apsolutne težine imaju viši rang). Analizu provedite nad modelom koji se u prethodnome zadatku pokazao optimalnim, tj. nad modelom koji ste u konačnici ispitivali.
Q: Koje su top-3 značajke modela? Je li to očekivano? Obrazložite.
Q: Kakve rezultate očekujete da biste dobili kada biste model trenirali samo s tih prvih tri značajki?
Klasifikacijske algoritme analizirat ćemo na skupu podataka seven
, linearno odvojivom skupu podataka od $N=7$ primjera u $n=2$ dimenzije:
seven_X = sp.array([[2,1],[2,3],[1,2],[3,2],[5,2],[5,4],[6,3]])
seven_y = sp.array([1,1,1,1,-1,-1,-1])
Funkcija za vizualizaciju skupa podataka i granice između klasa (ako je zadana funkcija predikcije h
):
def plot_problem(X, y, h=None, surfaces=True) :
'''
Plots a two-dimensional labeled dataset (X,y) and, if function h(x) is given,
the decision boundaries (surfaces=False) or decision surfaces (surfaces=True)
'''
assert X.shape[1] == 2, "Dataset is not two-dimensional"
if h!=None :
# Create a mesh to plot in
r = 0.02 # mesh resolution
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, r),
np.arange(y_min, y_max, r))
XX=np.c_[xx.ravel(), yy.ravel()]
try:
Z_test = h(XX)
if shape(Z_test) == () :
# h returns a scalar when applied to a matrix; map explicitly
Z = sp.array(map(h,XX))
else :
Z = Z_test
except ValueError:
# can't apply to a matrix; map explicitly
Z = sp.array(map(h,XX))
# Put the result into a color plot
Z = Z.reshape(xx.shape)
if surfaces :
plt.contourf(xx, yy, Z, cmap=plt.cm.Pastel1)
else :
plt.contour(xx, yy, Z)
# Plot the dataset
scatter(X[:,0],X[:,1],c=y, cmap=plt.cm.Paired,marker='o',s=50);
plot_problem(seven_X,seven_y)
Linearna regresija može se upotrijebiti za klasifikaciju tako da se nauči funkcija $f(\mathbf{x})=+1$ za pozitivne primjere i $f(\mathbf{x})=-1$ za negativne primjere. Granica između klasa u tom slučaju bit će funkcija $h(\mathbf{x})=0$, tj. primjeri za koje $h(\mathbf{x})\geq 0$ klasificiraju se kao pozitivni, a ostali kao negativni. Trenirajte model LinearRegression
na skupu seven
, ispišite težine modela te prikažite primjere i granicu između klasa. Funkciju za predikciju, koju predajete kao treći argument funkcije plot_problem
, možete definirati lambda-izrazom: lambda x : model.predict(x) >= 0
.
Q: Ako bismo kao oznake umjesto $\{+1,-1\}$ koristili $\{1,0\}$, kako biste izračunali granicu između klasa?
Klasifikacija pomoću linearne regresije implementirana je u klasi RidgeClassifier
. Pokažite da ta implementacija daje iste rezultate na skupu seven
(pritom isključite regularizaciju, tj. postavite alpha=0
).
from sklearn.linear_model import RidgeClassifier
Trenirajte klasifikacijski model RidgeClassifier
na sljedećem skupu podataka (skup seven
proširen jednim primjerom):
X2 = sp.append(seven_X,[[2,2]],axis=0)
y2 = sp.append(seven_y,-1)
Prikažite granicu između klasa te izračunajte točnost modela (možete koristiti funkciju metrics.accuracy_score
).
from sklearn.metrics import accuracy_score
Q: Koliko iznosi točnost modela? Objasnite zašto model ne ostvaruje potpunu točnost. Je li problem u skupu podataka ili u modelu?
Trenirajte klasifikacijski model RidgeClassifier
na sljedećem skupu podataka (skup seven
proširen jednim primjerom):
X3 = sp.append(seven_X,[[12,8]],axis=0)
y3 = sp.append(seven_y,-1)
Prikažite granicu između klasa te izračunajte točnost modela.
Q: Koliko iznosi točnost modela? Objasnite zašto model ne ostvaruje potpunu točnost. Je li problem u skupu podataka ili u modelu?
Više je načina kako se binarni klasifikatori mogu upotrijebiti za višeklasnu klasifikaciju. Najčešće se koristi tzv. shema jedan-naspram-ostali (engl. one-vs-rest, OVR), u kojoj se trenira po jedan klasifikator $h_j$ za svaku od $K$ klasa. Svaki klasifikator $h_j$ trenira se da razdvaja primjere klase $j$ od primjera svih drugih klasa, a primjer se klasificira u klasu $j$ za koju je $h_j(\mathbf{x})$ maksimalan.
Pomoću funkcije datasets.make_classification
generirajte slučajan skup podataka od tri klase:
from sklearn.datasets import make_classification
Trenirajte tri binarna klasifikatora, $h_1$, $h_2$ i $h_3$ te prikažite granice između klasa (tri grafikona). Zatim definirajte $h(\mathbf{x})=\mathrm{argmax}_j h_j(\mathbf{x})$ i prikažite granice između klasa za taj model. Konačno, uvjerite se da biste identičan rezultat dobili izravno primjenom modela RidgeClassifier
, budući da taj model za višeklasan problem zapravo interno implementira shemu jedan-naspram-ostali.
Q: Alternativna shema je one-vs-one (OVO). Koja je prednost sheme OVR nad shemom OVO?
Perceptron je implementiran klasom linear_model.Perceptron
.
from sklearn.linear_model import Perceptron
Trenirajte perceptron na skupu seven
i prikažite granicu između klasa. Uvjerite se da rezultat ovisi o redoslijedu primjera u skupu za učenje (postavite shuffle=True
i mijenjajte parametar random_state
). Zatim trenirajte perceptron na dvama varijantima skupa seven
iz zadataka B.2 i prikažite opet granice između klasa.
Q: Komentirajte razlike u rezultatima dobivenima na skupu seven
i na dvije njegove varijante.
Definirajte logističku (sigmoidalnu) funkciju $\mathrm{sigm}(x)=\frac{1}{1+\exp(-\alpha x)}$ i prikažite je za $\alpha\in\{1,2,4\}$.
Q: Kakav utjecaj ima faktor $\alpha$ na oblik sigmoide? Što to znači za model logističke regresije (tj. kako aposteriorna vjerojatnost $P(\mathcal{C}_j|\mathbf{x})$ ovisi o magnitudi vektora težina $\tilde{\mathbf{w}}$)?
Implementirajte funkciju lr_train(X,y,eta=0.01,max_iter=2000,alpha=0,epsilon=0.0001,trace=False)
za treniranje modela logističke regresije gradijentim spustom (batch izvedba). Funkcija uzima označeni skup primjera za učenje (matrica primjera X
i vektor oznaka y
) te vraća $(n+1)$-dimenzijski vektor težina tipa ndarray
. Ako je trace=True
, funkcija dodatno vraća listu (ili matricu) vektora težina $\tilde{\mathbf{w}}^0,\tilde{\mathbf{w}}^1,\dots,\tilde{\mathbf{w}}^k$ generiranih kroz sve iteracije optimizacije. Optimizaciju treba provoditi dok se ne dosegne max_iter
iteracija, ili kada razlika u pogrešci unakrsne entropije između dviju iteracija padne ispod vrijednosti epsilon
. Parametar alpha
određuje regularizacijski faktor.
NB: Obratite pozornost na to da je način kako su definirane oznake ($\{+1,-1\}$ ili $\{1,0\}$) kompatibilan s izračunom funkcije gubitka u optimizacijskome algoritmu. Prilagodite algoritam ili jednostavno redefinirajte oznake u skupu seven
.
Definirajte pomoćnu funkciju lr_h(x,w)
koja daje predikciju (aposteriornu vjerojatnost) za primjer x
za zadane težine w
te funkciju cross_entropy_error(X,y,w)
koja izračunava pogrešku unakrsne entropije na modela na označenom skupu (X,y)
(možete upotrijebiti funkciju metrics.log_loss
).
from sklearn.metrics import log_loss
Koristeći funkciju lr_train
, trenirajte model logističke regresije na skupu seven
, prikažite dobivenu granicu između klasa te izračunajte pogrešku unakrsne entropije.
Q: Jeste li dobili granicu između klasa kakvu ste očekivali dobiti pomoću logističke regresije? Obrazložite.
Q: Koji kriterij zaustavljanja je aktiviran?
Q: Zašto dobivena pogreška unakrsne entropije nije jednaka nuli?
Q: Kako biste utvrdili da je optimizacijski postupak doista pronašao hipotezu koja minimizira pogrešku učenja? O čemu (o kojim parametrima) to ovisi?
Q: Na koji način biste preinačili kod ako biste htjeli da se optimizacija izvodi stohastičkim gradijentnim spustom (online learning)?
Prikažite na jednom grafikonu pogrešku unakrsne entropije (očekivanje logističkog gubitka) i pogrešku klasifikacije (očekivanje gubitka 0-1) na skupu seven
kroz iteracije optimizacijskog postupka. Koristite trag težina funkcije lr_train
iz zadatka C.2 (opcija trace=True
). Za izračun empirijske pogreške možete koristiti funkciju metrics.zero_one_loss
. Na drugom grafikonu prikažite pogrešku unakrsne entropije kao funkciju broja iteracija za različite stope učenja, $\eta\in\{0.005,0.01,0.05,0.1\}$.
from sklearn.metrics import zero_one_loss
Q: Zašto je pogreška unakrsne entropije veća od pogreške klasifikacije? Je li to uvijek slučaj kod logističke regresije i zašto?
Q: Koju stopu učenja $\eta$ biste odabrali i zašto?
Model logističke regresije odgovara binarnome generativnom modelu kod kojega su klase modelirane multivarijatnom normalnom razdiobom s dijeljenjom kovarijacijskom matricom. Za neregulariziranu logističku regresiju, težine modela $\tilde{\mathbf{w}}$ mogu se izvesti na temelju ML-procjena parametara $\mathbf{\mu}_1$, $\mathbf{\mu}_2$, $\mathbf{\Sigma}$, $P(\mathcal{C}_1)$ i $P(\mathcal{C}_2)$. Izračunajte parametre generativnog modela na skupu seven
te pomoću njih odredite vektor težina $\tilde{\mathbf{w}}$. Prikažite dobivenu granicu između klasa. Izračunajte pogrešku unakrsne entropije i usporedite je s onom dobivenom u zadataku C.2.
from scipy.stats import multivariate_normal
Q: Odgovaraju li težine izvedene pomoću generativnog modela onima koje ste dobili logističkom regresijom? Ako ne, pokušajte obrazložiti zašto.
Koristeći varijantu skupa podataka seven
iz zadatka B.3, provjerite koliko je model logističke regresije robustan na vrijednosti koje odskaču. Prikažite granicu između klasa.
Q: Usporedite rezultat s onime za model linearne regresije iz zadatka B.3. Obrazložite zašto se rezultat razlikuje.
Trenirajte model logističke regresije na skupu seven
te na dva odvojena grafikona prikažite (1) aposteriornu vjerojatnost $h(\mathbf{x})$ za svih sedam primjera te (2) vrijednosti težina $w_0$, $w_1$, $w_2$ kroz iteracije optimizacijskoga algoritma. Zatim ponovite treniranje na linearno neodvojivoj varijanti skupa seven
iz zadatka B.3. te prikažite ponovo oba grafikona.
Q: Usporedite grafikone za slučaj linearno odvojivih i linearno neodvojivih primjera te komentirajte razliku.
Trenirajte model logističke regresije na skupu seven
s različitim faktorima L2-regularizacije, $\alpha\in\{0,1,10,100\}$. Prikažite (1) pogrešku unakrsne entropije te (2) L2-normu vektora $\mathbf{w}$ kroz iteracije optimizacijskog algoritma.
Q: Jesu li izgledi krivulja očekivani i zašto?
Q: Koju biste vrijednost za $\alpha$ odabrali i zašto?
Upoznajte se s klasom linear_model.LogisticRegression
koja implementira logističku regresiju. Usporedite rezultat modela na skupu seven
s rezultatom koji dobivate pomoću vlastite implementacije algoritma.
Q: Ako se rezultat razlikuje, pokušajte obrazložiti zašto je to tako.
from sklearn.linear_model import LogisticRegression
Proučite funkciju datasets.make_classification
. Generirajte i prikažite dvoklasan skup podataka s ukupno $N=200$ dvodimenzijskih ($n=2)$ primjera.
from sklearn.datasets import make_classification
Malo je izgledno da će tako generirani skup biti linearno odvojiv, međutim to nije problem jer primjere možemo preslikati u višedimenzijski prostor značajki pomoću klase preprocessing.PolynomialFeatures
, kao što smo to učinili kod regresije (v. zadatak A.6). Trenirajte model logističke regresije koristeći za preslikavanje u prostor značajki polinomijalnu funkciju stupnja $d=2$ i stupnja $d=3$. Prikažite dobivene granice između klasa. Možete koristiti svoju implementaciju, ali se radi brzine preporuča koristiti linear_model.LogisticRegression
. Regularizacijski faktor odaberite po želji.
NB: Kao i ranije, za prikaz granice između klasa koristite funkciju plot_problem
. Funkciji kao argumente predajte izvorni skup podataka, a preslikavanje u prostor značajki napravite unutar poziva funkcije h
koja čini predikciju, na sljedeći način:
from sklearn.preprocessing import PolynomialFeatures
#poly=PolynomialFeatures(2)
#...
#plot_problem(X,y,lambda x : model.predict(poly.transform(x))
Q: Koji biste stupanj polinoma upotrijebili i zašto? Je li taj odabir povezan s odabirom regularizacijskog faktora $\alpha$ i zašto?
Podijelite skup podataka iz prethodnog zadatka na skup za treniranje i skup za ispitivanje u omjeru 7:3 (možete koristiti funkciju cross_validation.train_test_split
.
from sklearn.cross_validation import train_test_split
Na skupu za učenje trenirajte model logističke regresije s polinomom čevrtog stupnja ($d=4$) kao funkcijom preslikavanja. Prikažite empirijsku pogrešku i pogrešku generalizacije u ovisnosti o faktoru regularizacije, i to kao funkciju parametra $C$ (inverz faktora regularizacije) za $C=2^\alpha$, gdje $\alpha\in\{-8,-7,\dots,7,8\}$.
Q: Kojem dijelu u grafikonu odgovara prenaučenost a kojem podnaučenost. Zašto?
Q: Koji biste faktor $\alpha$ odabrali i zašto?
Q: Koliko su ovi rezultati stabilni? Ako mislite da nisu, objasnite što je mogući uzrok. Predložite kako bismo mogli dobiti stabilnije rezultate.
Preuzmite Glass Identification Data Set
, koji opisuje rezultate kemijske analize 214 stakala. Riječ je o klasifikacijskom problemu sa šest klasa: na temelju 9 kemijskih značajki stakla potrebno je, u svrhu forenzičke analize, odrediti o kojoj se od šest vrsta stakla radi. Skup podataka možete učitati na sljedeći način:
data = sp.loadtxt("/path/to/glass.data", delimiter=",")
glass_X, glass_y = data[:,1:10], data[:,10]
Skup zatim podijelite na skup za učenje i skup za ispitivanje u omjeru 2:1, kako slijedi:
from sklearn import cross_validation
X_train, X_test, y_train, y_test = cross_validation.train_test_split(glass_X,glass_y,train_size=2.0/3,random_state=42)
print X_train.shape, X_test.shape
Na skupu za učenje trenirajte model logističke regresije i ispitajte njegovu točnost na skupu za ispitivanje. Optimizaciju hiperparametara načinite na skupu za provjeru, koji ćete dobiti dodatnom podjelom skupa za učenje. Skup za ispitivanje ne smijete koristiti ni za što osim za konačno i jednokratno vrednovanje točnosti modela!
U ovom skupu podataka značajke dolaze iz različitih distribucija, što može dovesti do toga da značajke s većim numeričkim vrijednostima dominiraju nad značajkama s manjim numeričkim vrijednostima, što u konačnici može narušiti kvalitetu modela. Problem se može ublažiti standardizacijom značajki, kao u zadatku A.15. Proučite klasu za skaliranje značajki preprocessing.StandardScaled
i primijenite skaliranje značajki.
from sklearn.preprocessing import StandardScaler
Q: Koliko značajki ima vaš najbolji model?
Q: Smatrate li da je točnost modela zadovoljavajuća? Je li model točniji od nasumičnog pogađanja?
Q: Usporedite točnost modela na skupu za učenje i na skupu za ispitivanje. Što možete zaključiti temeljem te usporedbe?
Q: Usporedite broj značajki $n$ i broj primjera $N$. Što mislite, je li ovaj omjer prikladan? Bi li bilo bolje povećati $N$ ili pak povećati $n$?
Q: Kako biste odredili je li broj primjera $N$ dovoljan?
Q: Pri učitavanju iz datoteke zanemarili smo prvu značajku. Zašto je to nužno?