torstai 1. marraskuuta 2012

Oppivat järjestelmät

Tänään jatkettiin oppivien järjestelmien opiskelua. Ensimmäisen tunnin aluksi kuitenkin käytiin läpi ensimmäisen välikokeen kysymykset ja hahmoteltiin vastauksia niihin.

Tämän jälkeen muisteltiin edellisen viikon asioita lyhyesti, ja vilkaistiin mm. Matlab-demoa, jolla voidaan piirtää hiirellä projektiosuora kaksiulotteisen datan koordinaatistoon. Kun kaksi pistettä suoralta on merkitty, Matlab-skripti projisoi datan tälle suoralle ja piirtää tuloksena saatavien yksiulotteisten näytteiden jakauman sekä luokitteluprosentin. Hyvillä projektiosuorilla data oli täydellisesti luokiteltavissa, mutta huonoilla joukot menivät päällekkäin projisoinnin jälkeen. Fisherin lineaarinen erottelija laskee tämän suoran automaattisesti niin että erottelu on optimaalinen.

Seuraavaksi palautettiin mieleen tukivektorikone, ja tarkasteltiin lähemmin kernelitemppua. Kernelitemppu kuvaa näytteet korkeampiulotteiseen avaruuteen, jossa ne toivottavasti ovat paremmin eroteltavissa. Itse kuvausta ei kuitenkaan tarvitse käytännössä tehdä, vaan riittää korvata menetelmässä jokainen vektorien välinen sisätulo <x,y> jollain muulla funktiolla k(x,y). Tiettyjen reunaehtojen vallitessa voidaan osoittaa tämän olevan sama asia kuin kuvaus tíettyyn korkeampiulotteiseen avaruuteen ennen luokittelua. Periaatteessa tämä kyseinen kuvaus voidaan laskeakin, mutta yleensä se ei sinänsä ole kovin kiinnostavaa. Sen sijaan voidaan kokeilla erilaisia kerneleitä, ja katsoa millä niistä luokittelutulos on paras. Yleisesti käytettyjä kerneleitä ovat mm. polynomikernelit k(x,y) = (<x,y>)^n ja k(x,y) = (1 + <x,y>)^n sekä ns. RBF-kerneli k(x,y) = exp(-||x-y||).

Tukivektorikoneita vertailtiin lineaariseen luokittelijaan vaihteeksi Python-kielellä ja seuraavalla skriptillä. Jos haluat tutustua Pythoniin, kätevä Windows-asennuspaketti löytyy täältä.

 # Diagnosis of ovarian cancer with several classifiers  
   
 import numpy as np  
 from sklearn import svm  
 from sklearn import cross_validation  
   
 # Read the data  
   
 filename = "ovariancancer.csv"  
   
 X = np.genfromtxt(filename, delimiter=',', skip_header = 0, dtype = np.float)  
 y = X[:,0]  
 X = X[:,1:]  
   
 # Set a range for the parameters of the classifier  
   
 pars = 10.0**(np.arange(-1,7))  
 res = np.empty(np.shape(pars))  
 kernel = 'rbf'  
   
 # Select regularization parameter  
 for i, C in enumerate(pars):  
     
   print "C = " + str(C)  
     
   classifier = svm.SVC(degree=2,C=C,kernel=kernel)  
   scores = cross_validation.cross_val_score(classifier, X, y, cv=5)     
       
   print "Accuracy: %0.2f %% (+/- %0.5f)" % (100*scores.mean(), scores.std() / 2)  
   print ""  
   
   res[i] = scores.mean()  
     
 minidx = res.argmax()  
 C = pars[minidx]  
   
 classifier = svm.SVC(C=C, kernel=kernel)  
       
 model = classifier.fit(X,y)  
   
 print "Score with param %f for all data: %f." % (C, model.score(X,y))  
   

Tämän jälkeen paneuduttiin hermoverkkojen opetukseen, ja mainittiin lyhyesti opetusalgoritmin perustuvan derivaattaan ja ketjusääntöön. Näiden avulla voidaan päätellä suunta, jossa luokitteluvirhe pienenee jyrkimmin, ja kyseiset kaavat löytyvät esim. täältä. Perus- backpropagationin lisäksi on olemassa kehittyneempiä ja nopeampia opetusalgoritmeja, ja esim. Matlabissa niitä on lähes parikymmentä. Olennaisin ero algoritmien välillä on niiden nopeudessa ja muistin tarpeessa.

Luennolla ei otettu kantaa siihen miten järjestelmä löytää verkolle syötettävät merkit, mutta joitain yleisimpiä ratkaisuja kuvaillaan wikipedian feature detection -artikkelissa. Luennon lopuksi demottiin tamperelaisen Visy Oy:n kehittämää rekisterikilven tunnistusohjelmistoa, joka on käytössä mm. raja-asemilla, satamissa ja tehtaissa ympäri maailmaa.


Ei kommentteja:

Lähetä kommentti