Sissejuhatus

Käesoleva kirjatüki eesmärk on anda väga põgus ülevaade järgnevatest masinõppe meetodidest:

Tegemist on väga põgusa sissejuhatusega ning kellel on asja vastu rohkem huvi, võib seda lugeda raamatust The Elements of Statistical Learning. Üritan aja jooksul seda artiklit ka täiendada. Hetkel saad siit aimu, kuidas masinõppe meetodeid kasutada (mis paketid ja kuidas koodiga mässata) ning tulemusi omavahel võrrelda.

Logistic regression

Logistilise regressiooni korral on sõltuvaks muutjaks (y-ks) üldjuhul binaarne muutuja (väärtused 0 ja 1 näiteks jah ja ei). Võib olla ka rohkem väärtusi, kuid üldjuhul kasutatakse logistilist regressiooni 2-väärtuse korral. Miks mitte kasutada lineaarset regressiooni meetodit? Lineaarse regressiooni korral võivad tulemused olla tõenäosusvahemikust [0, 1] väljaspool, mis muudab tulemuste tõlgendamise väga keeruliseks (näiteks mida tähendab tõenäosus -1.5?).

Mudeli kasutamsie näitamiseks kasutan reaalseid andmeid. Meil on andmed S&P 500 1250 päeva aktsiaindeksid vahemikus 2001-2005. Iga päeva kohta on tootlus (%) eelnevate kauplemispäeva kohta (Lag1 kuni Lag5). Samuti on aktsiate arv (Volume), millega kaubeldi eelneval päeval (miljardites), käesoleva päeva tootlus %-na (Today) ja suund (Direction), kas turg oli üleval või all sellel päeval.

library(ISLR)
attach(Smarket)
names(Smarket)
## [1] "Year"      "Lag1"      "Lag2"      "Lag3"      "Lag4"      "Lag5"     
## [7] "Volume"    "Today"     "Direction"

Järgneval joonisel on näha koge vaadeldava perioodi päevased müügimahud:

plot(Volume)

Valmistame andmed ette analüüsiks. Eraldame training ja test andmed.

library(caret)
inTrain <- createDataPartition(y=Smarket$Direction,
                              p=0.7, list=FALSE)
training <- Smarket[inTrain,]
testing <- Smarket[-inTrain,]

Nüüd loome mudeli:

log.fit=glm(Direction ~Lag1 + Lag2 ,data=training ,
            family=binomial(link="logit")) 
summary(log.fit)
## 
## Call:
## glm(formula = Direction ~ Lag1 + Lag2, family = binomial(link = "logit"), 
##     data = training)
## 
## Deviance Residuals: 
##    Min      1Q  Median      3Q     Max  
## -1.336  -1.206   1.098   1.146   1.280  
## 
## Coefficients:
##             Estimate Std. Error z value Pr(>|z|)
## (Intercept)  0.07602    0.06774   1.122    0.262
## Lag1        -0.01928    0.05867  -0.329    0.742
## Lag2        -0.05675    0.06058  -0.937    0.349
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 1213.2  on 875  degrees of freedom
## Residual deviance: 1212.3  on 873  degrees of freedom
## AIC: 1218.3
## 
## Number of Fisher Scoring iterations: 3

Kõige väiksem p-väärtus on Lag2-l, mis on suurem, kui 0.05. See viitab tõsiasjale, et muutujate Lag1 ja Direction vahel ei pruugi statistiliselt olulist seost olla. Ükski sõltumatu muutja ei ole statistiliselt oluline 5% olulise nivool.

Testime mudelit test andmete peal, et näha, kui paljudel juhtudel suudab mudel klassifitseerida muutuja Direction väärtuse õigesti.

log.pred=predict(log.fit, testing, type="response")
log.Direction=rep("Down", nrow(testing)) #teeme algse vektori
log.Direction[log.pred >0.5]="Up" #kui tõenäosus üle 50% ennustame kasvu
library(e1071)
confusionMatrix(log.Direction,testing$Direction) 
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction Down  Up
##       Down   24  14
##       Up    156 180
##                                           
##                Accuracy : 0.5455          
##                  95% CI : (0.4935, 0.5967)
##     No Information Rate : 0.5187          
##     P-Value [Acc > NIR] : 0.1628          
##                                           
##                   Kappa : 0.063           
##  Mcnemar's Test P-Value : <2e-16          
##                                           
##             Sensitivity : 0.13333         
##             Specificity : 0.92784         
##          Pos Pred Value : 0.63158         
##          Neg Pred Value : 0.53571         
##              Prevalence : 0.48128         
##          Detection Rate : 0.06417         
##    Detection Prevalence : 0.10160         
##       Balanced Accuracy : 0.53058         
##                                           
##        'Positive' Class : Down            
## 

Tabelist on näha, et kui 24 juhul ennustas mudel õigesti kahanemist ning 180 juhul kasvamist. Valesti klassifitseeris mudel kasvamist kahanemiseks 14 juhul ning kahanemist klassifitseeris kasvamiseks 156 juhul. Mudeli täpsus on 54.5%. Mudeli sensitiivsus on 13.33%, mis tähendab, et kui turg liigub alla, siis meie mudel suudab seda leida 13.33% juhtudest. Mudeli spetsiifilisus on 92.8%, mis tähendab, et kui turg liigub üles, siis 92.8% juhtudest suudab meie mudel seda näidata. Mudeli headus oleneb nüüd, mille jaoks seda vaja on (kui on vaja kindlasti mitte mööda lasta ühtegi kasvu võimalust, siis võib mudel isegi sobida, kuid kui otsitakse mudelit, mis enustaks täpselt langust, siis pole mudelist suuremat kasu). Muidugi praegu on andmekogu suhteliselt väike ning uuemate andmetega võib mudel oluliselt ebatäpsem olla!

Linear Discriminant Analysis

Nüüd võtame ette järgmise meetodi, nimelt Linear Discriminant Analysis. Seda kasutatakse samuti klassifiteermiseks 2-ks või enamaks klassiks. Hetkel pikemalt sellest ei kirjuta, lugege eelmainitud raamatust. Loome mudeli:

library(MASS)
lda.fit=lda(Direction ~Lag1 + Lag2 ,data=training) 
lda.fit
## Call:
## lda(Direction ~ Lag1 + Lag2, data = training)
## 
## Prior probabilities of groups:
##      Down        Up 
## 0.4817352 0.5182648 
## 
## Group means:
##              Lag1       Lag2
## Down  0.005886256 0.08819905
## Up   -0.015473568 0.01848458
## 
## Coefficients of linear discriminants:
##             LD1
## Lag1 -0.2912476
## Lag2 -0.8573985

Mudelist on näha, et training andmetes 48% juhtudel läks aktsiaturg alla ning 51% üles.

Testime mudelit test andmete peal.

lda.pred=predict(lda.fit , testing, type="prob")
confusionMatrix(lda.pred$class,testing$Direction) 
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction Down  Up
##       Down   24  14
##       Up    156 180
##                                           
##                Accuracy : 0.5455          
##                  95% CI : (0.4935, 0.5967)
##     No Information Rate : 0.5187          
##     P-Value [Acc > NIR] : 0.1628          
##                                           
##                   Kappa : 0.063           
##  Mcnemar's Test P-Value : <2e-16          
##                                           
##             Sensitivity : 0.13333         
##             Specificity : 0.92784         
##          Pos Pred Value : 0.63158         
##          Neg Pred Value : 0.53571         
##              Prevalence : 0.48128         
##          Detection Rate : 0.06417         
##    Detection Prevalence : 0.10160         
##       Balanced Accuracy : 0.53058         
##                                           
##        'Positive' Class : Down            
## 

Hetkel on näha, et see mudel on sama täpsusega kui logistilise regressiooni mudel.

Quadratic Discriminant Analysis

Võtame ette kolmanda mudel, milleks on Quadratic Discriminant Analysis. Hetkel mudelist pikemalt ei räägi, kui siis ainult seda, et jällegi aitab mudel ennustada binaarset näitajat. Teeme kohe näite.

qda.fit=qda(Direction~Lag1+Lag2 ,data=training)
qda.fit
## Call:
## qda(Direction ~ Lag1 + Lag2, data = training)
## 
## Prior probabilities of groups:
##      Down        Up 
## 0.4817352 0.5182648 
## 
## Group means:
##              Lag1       Lag2
## Down  0.005886256 0.08819905
## Up   -0.015473568 0.01848458

Testime mudelit test andmete peal.

qda.pred=predict(qda.fit,testing) 
confusionMatrix(qda.pred$class,testing$Direction) 
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction Down  Up
##       Down   18  17
##       Up    162 177
##                                          
##                Accuracy : 0.5214         
##                  95% CI : (0.4694, 0.573)
##     No Information Rate : 0.5187         
##     P-Value [Acc > NIR] : 0.4796         
##                                          
##                   Kappa : 0.0127         
##  Mcnemar's Test P-Value : <2e-16         
##                                          
##             Sensitivity : 0.10000        
##             Specificity : 0.91237        
##          Pos Pred Value : 0.51429        
##          Neg Pred Value : 0.52212        
##              Prevalence : 0.48128        
##          Detection Rate : 0.04813        
##    Detection Prevalence : 0.09358        
##       Balanced Accuracy : 0.50619        
##                                          
##        'Positive' Class : Down           
## 

See mudel on natukene väiksema täpsusega, sensitiivsuse ja spetsiifilisusega, kui eelnevad kaks mudelit.

Naive Bayes Classificator

Viimaseks võtan vaatluse alal Naive Bayes Classificator mudeli. Selle kohta võid lugeda Wikipeidast. Loome mudeli:

library(klaR)
nb=NaiveBayes(Direction~Lag1+Lag2, data = training)

Testime test andmete peal.

nb.pred <- predict(nb, newdata = testing, type = "prob")
confusionMatrix(nb.pred$class,testing$Direction) 
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction Down  Up
##       Down   21  16
##       Up    159 178
##                                           
##                Accuracy : 0.5321          
##                  95% CI : (0.4801, 0.5836)
##     No Information Rate : 0.5187          
##     P-Value [Acc > NIR] : 0.3209          
##                                           
##                   Kappa : 0.0352          
##  Mcnemar's Test P-Value : <2e-16          
##                                           
##             Sensitivity : 0.11667         
##             Specificity : 0.91753         
##          Pos Pred Value : 0.56757         
##          Neg Pred Value : 0.52819         
##              Prevalence : 0.48128         
##          Detection Rate : 0.05615         
##    Detection Prevalence : 0.09893         
##       Balanced Accuracy : 0.51710         
##                                           
##        'Positive' Class : Down            
## 

Natukene ebatäpsem mudel, kui logistiline regressioon ja Quadratic Discriminant Analysis.

ROC

Võrdleme eelnevaid mudeleid omavahel. Selleks kasutan ROC (Receiver operating characteristic) graafikut.

#ennustused algsete andmete juurde
testing["log_pred"]=log.pred
testing["nb_pred"]=nb.pred$posterior[,2]
testing["lda_pred"]=lda.pred$posterior[,2]
testing["qda_pred"]=qda.pred$posterior[,2]

library("pROC")
log_test_roc <- roc(Direction ~ log_pred, 
                    data = testing, ci = TRUE)
lda_test_roc <- roc(Direction ~ lda_pred, 
                    data = testing, ci = TRUE)
nb_test_roc <- roc(Direction ~ nb_pred, 
                   data = testing, ci = TRUE)
qda_test_roc <- roc(Direction ~ qda_pred, 
                   data = testing, ci = TRUE)

par(mfrow = c(1, 1))
plot(lda_test_roc, las = 1, main = "Test andmete põhjal ROCi kõver")
## 
## Call:
## roc.formula(formula = Direction ~ lda_pred, data = testing, ci = TRUE)
## 
## Data: lda_pred in 180 controls (Direction Down) < 194 cases (Direction Up).
## Area under the curve: 0.5234
## 95% CI: 0.4644-0.5824 (DeLong)
plot(log_test_roc, add = TRUE,las = 1, col="green")
## 
## Call:
## roc.formula(formula = Direction ~ log_pred, data = testing, ci = TRUE)
## 
## Data: log_pred in 180 controls (Direction Down) < 194 cases (Direction Up).
## Area under the curve: 0.5234
## 95% CI: 0.4644-0.5824 (DeLong)
plot(nb_test_roc, add = TRUE,las = 1, col="red")
## 
## Call:
## roc.formula(formula = Direction ~ nb_pred, data = testing, ci = TRUE)
## 
## Data: nb_pred in 180 controls (Direction Down) > 194 cases (Direction Up).
## Area under the curve: 0.481
## 95% CI: 0.4221-0.5399 (DeLong)
plot(qda_test_roc,add = TRUE, las = 1, col="blue")
## 
## Call:
## roc.formula(formula = Direction ~ qda_pred, data = testing, ci = TRUE)
## 
## Data: qda_pred in 180 controls (Direction Down) < 194 cases (Direction Up).
## Area under the curve: 0.5296
## 95% CI: 0.4709-0.5882 (DeLong)
legend(0, 0.6, legend = c("lda", "log", "nb", "qda"), 
       lty = c(1,1,1), col =     c("black", "green", "red", "blue"))

Sisuliselt aitab graafik omavahel võrrelda erinevaid meetodeid ning meetodi sensitiivsust erinevate spetsiifilisuse väärtuste korral. Ideaalis peaks joon algama vasakust alumisest nurgast ning kohe võimalikult otsejoones minema vasakusse ülemisse nurka (ning sealt siis paralleelselt horisondiga liikuma paremale). Praegusel juhul on tulemus risti vastupidine, jooned liiguvad diagonaalis üles paremale. See tähendab, et spetsiifilisuse kasvades kasvab ka sensitiivsus enam-vähem samas suurusjärgus. Maakeeli öeldes, kui õigete positiivsete leidmise määr on kõrge (parem ülemine nurk), on valepositiivsete leidmise määr madal. Ja vastupidi. Ideaalis oleks nad mõlemad üheaegselt kõrged (praegu on tegu nokk kinni ja saba lahti olukorraga). Lisaks näitab hallikas vertikaaljoon, millised oleks need näitajad täielikult juhusliku mudeli korral (kus viskame münti ning selle põhjal määrame kas turg kasvab vüi kahaneb). Kõik, mis on konstantselt alla halli joone süstemaatiliselt annavad vale tulemusi, mistõttu võib neid ümber “pöörates” saada head mudelid (antud juhul asendame mudeli ennustuses “Up” sõnaga “Down” ning “Down” sõnaga “Up”). Praegusel juhul võiks _Naive Bayes Classificator_i puhul selle peale mõelda, kuna see on suures osas allapoole halli joont. Joonise põhjal tundub, et parima tulemuse annab Quadratic Discriminant Analysis. Siiski pole tegemist väga erilise täpsusega (vasaku nurga puudutamisest on asi kaugel). Kuid olenevalt, mis küsimusele vastamiseks mudelit vaja on, võib sellest ka reaalset kasu olla.

Mudelite täpsuse võrdlemiseks on veel võimalusi, kuid sellest lähemalt teistes postitustes.