{{indexmenu_n>6}} **TEST 05** - (0.5 b) Popište (k-násobnou) křížovou validaci. Jak probíhá tvorba trénovací a testovací množiny při použití této metody? Jak se spočítá výsledný odhad chyby zvoleného modelu? - (0.5 b) Jsou-li k dispozici rozsáhlá data, jak a proč je dělíme na data trénovací, testovací a validační? - (0.5 b) Uvažujte záznamy (řádky) v následující tabulce. Příznaky ve sloucích //Deadline//, //IsThereAParty// a //Lazy// jsou **vstupní** parametry. Příznak //Activity// je parametr **výstupní - třída**. Spočítejte hodnotu entropie atributu //IsThereAParty// vzhledem k výstupnímu parametru //Activity//. Nápověda: $\log_2 0.2 = -2.32$, $\log_2 0.6 = -0.74$, $0 . \log_2 0 \equiv 0$. \begin{table}[] \begin{tabular}{lll|l} \textbf{Deadline} & \textbf{IsThereAParty} & \textbf{Lazy} & \textbf{Activity} \\ \hline Urgent & Yes & Yes & Party \\ Urgent & No & Yes & Study \\ Near & Yes & Yes & Party \\ None & Yes & No & Party \\ None & No & Yes & Pub \\ None & Yes & No & Party \\ Near & No & No & Study \\ Near & No & Yes & TV \\ Near & Yes & Yes & Party \\ Urgent & No & No & Study \\ \hline \end{tabular} \end{table} ====== Cvičení 6 - Výběr a hodnocení modelu ====== /* Test: https://goo.gl/forms/wqaWAoDsnZsnIXK32 */ ===== Opakování ===== === Míry pro hodnocení modelů === * klasifikační přesnost a realtivní chyba * specifita a senzitivita * precision a recall * F1 score === Standardní postup pro validaci modelů === * trénovací množina - učení klasifikátoru * validační množina - optimalizace parametrů klasifikátoru * testovací množina - konečný výpočet hodnotícího kritéria * **přeučení (overfitting) vs nedoučení (underfitting)** === k-NN klasifikátor === * klasifikace podle minima vzdálenosti * výsledná třída se určuje hlasováním (z toho důvodu je vhodné volit k liché) * je možné použít různé typy metrik ===== Testování - klasifikátor k-NN ===== Instalace balíčku s funkcí knn() install.packages("class") library(class) Načtení iris dat. # načtení iris dat data(iris) # rychlá explorace dat dim(iris) summary(iris) Rozdělte instance náhodně na trénovací (50%), validační testovací (30%) a testovací (20%) množinu. # zamíchání dat před rozdělením do množin set.seed(13579) shuffle <- sample(nrow(iris), nrow(iris), replace=F) iris <- iris[shuffle,] # vytvoření trénovací (50%), validační (30%) and testovací (20%) množiny trainIris <- iris[1:(0.5*nrow(iris)),] validIris <- iris[(0.5*nrow(iris) + 1):(0.8*nrow(iris)),] testIris <- iris[(0.8*nrow(iris) + 1):(nrow(iris)),] # ověření velikosti množin dim(trainIris) dim(validIris) dim(testIris) Trénovací, validační a testovací množinu můžeme získat alternativním postupem. Všimněte si, že velikost jednotlivých množin neodpovídá přesně tomu, co jsme požadovali. # alternativní způsob rozdělení dat ind = sample(3,nrow(iris),replace=T,prob=c(0.5,0.3,0.2)) # vytvoření trénovací (50%), validační (30%) a testovací (20%) množiny trainIris <- iris[ind == 1,] validIris <- iris[ind == 2,] testIris <- iris[ind == 3,] # ověření velikosti množin dim(trainIris) dim(validIris) dim(testIris) Na trénovací množině budeme postupně učit klasifikátor k-NN s //k// = 1,3,5 ... 11,13,15. Budeme si zaznamenávat klasifikační přesnost na validační množině. Následně najdeme největší hodnotu klasifikační úspěšnosti a k ní příslušnou hodnotu parametru //k// a prohlásíme jí za optimální. # příprava hodnot parametru k parameter <- seq(from = 1, to = 15, by = 2); # příprava vektoru pro zaznamenávání hodnot klasifikační úspěšnosti acc <- vector(length = length(parameter)) for (i in 1:length(parameter)) { prediction <- knn(trainIris[,-5],validIris[,-5],cl = trainIris[,5],k = parameter[i]) acc[i] <- sum(prediction == validIris[,5])/nrow(validIris) } # nalezení nejlepší hodnoty k podle validační množiny kValidated <- parameter[which.max(acc)] Jaká hodnota parametru k je optimální pro k-NN klasifikátor na iris datech? Nakonec vypočteme úspěšnost klasifikátoru na testovacích datech: # odhad úspěšnosti klasifikace na testovací množině trainFull <- rbind(trainIris, validIris) prediction <- knn(trainFull[,-5],testIris[,-5],cl = trainFull[,5],k = kValidated) testAcc <- sum(prediction == testIris[,5])/nrow(testIris) Při definici přeučení se obvykle porovnává chyba na trénovací a validační množině. Určete klasifikační přesnost na trénovací množině a porovnejte jí s přesností na validační množině. Jakým způsobem se mění klasifikační přesnost s rostoucím k? Jaká je příčina tohoto chování. Co lze soudit o našem výsledném klasifikátoru? Je klasifikátor přeučený, tak akorát, nebo nedoučený? ===== Testování - 10-ti složková křížová validace - rozhodovací stromy ===== Podobným způsobem jako v předchozím úkolu můžeme využít křížovou validaci. Vyzkoušíme si odhad optimální hodnoty maximální hloubky rozhodovacího stromu. Postup je velmi podobný, pouze v každé iteraci parametru provedeme místo jednoho učení a jednoho výpočtu hodnotícího kritéria celou křížovou validaci, to znamená 10x budeme učit klasifikátor a desetkrát určovat hodnotící kritérium, ukládat ale budeme pouze průměrnou hodnotu ze všech iterací křížové validace. Křížovou validaci vyzkoušíme na krabích datech, která jsou v R (package MASS) Potřebné knihovny pro tento příklad install.packages("MASS") library(MASS) library(rpart) library(rpart.plot) **10-složková křížová validace** # načtení krabích dat library(MASS) library(rpart) library(rpart.plot) data(crabs) # nastavit generátor náhodných čísel set.seed(12345) # vytvoření trénovací množiny (80%), která bude rozdělena na 10 složek, a testovací množiny (20%) ind <- sample(1:nrow(crabs),0.8*nrow(crabs)) trainCrabs <- crabs[ind,] testCrabs <- crabs[-ind,] folds <- rep_len(1:10,nrow(trainCrabs)) # ověření velikostí množin # training set dim(trainCrabs) # folds in training set table(folds) # testing set dim(testCrabs) # hodnoty parametru maxdepth, které budeme optimalizovat parameter <- seq(from = 1, to = 10, by = 1); # inicializace vektorů pro klasifikační přesnosti accValid <- matrix(NA,nrow=length(parameter),ncol=10) accTrain <- matrix(NA,nrow=length(parameter),ncol=10) for (i in 1:length(parameter)){ for(j in 1:10){ train <- trainCrabs[folds!=j,] valid <- trainCrabs[folds==j,] tree <- rpart(sp ~ .,data=train,control = rpart.control(minsplit=10,maxdepth=parameter[i])) accTrain[i,j] <- sum(predict(tree,type='class') == train$sp)/nrow(train) accValid[i,j] <- sum(predict(tree,newdata=valid,type='class') == valid$sp)/nrow(valid) } } avgAccTrain <- apply(accTrain,1,mean) avgAccValid <- apply(accValid,1,mean) # závislost trénovací (zelená) a validační (červená) úspěšnosti plot(parameter,avgAccValid,type="b",col=2,xlab='Maximal tree depth',ylab='Accuracy',ylim=c(0.5,1)) lines(parameter,avgAccTrain,type="b",col=3) legend('bottomright',c('Validation set','Training set'),col=c(2,3),pch='---') # nalezení optimální hodnoty parametru z hlediska úspěšnosti klasifikace maxdepthValidated = parameter[which.max(avgAccValid)] # odhad úspěšnosti klasifikace na nezávislých datech finalTree <- rpart(sp ~ .,data=trainCrabs,control = rpart.control(minsplit=10,maxdepth=maxdepthValidated)) testAcc <- sum(predict(finalTree,newdata=testCrabs,type='class') == testCrabs$sp)/nrow(testCrabs) # výsledný rozhodovací strom rpart.plot(finalTree) == Úkol - hodhocení modelu pomocí bootstrapu == Vyzkoušejte odhad úspěšnosti klasifikace pomocí bootstrapu. Upravte odhadování vhodné hodnoty parametru **maxdepth** na krabích datech. Poměr trénovací a validační množiny ve vnitřní smyčce zvolte 60% a 40%. Pro každou hodnotu opakujte trénování a validování klasifikátoru 32 krát. Výsledky porovnejte s 10-složkouvou křížovou validací. ===== Křivka učení ===== * je ukazatelem vhodnosti zvoleného modelu pro daná data. * generujeme ji tak, že data rozdělíme na konstantní množinu testovacích dat a trénovací množinu dat, kde postupně zvyšujeme počet příkladů, na kterých se model může učit, a zjišťujeme chybu na datech testovacích. * v případě, že model je schopen dostatečně dobře generalizovat zpracovávaná data, pak chyba s počtem příkladů stále klesá a blíží se v ideálním případě nule. Nakreslete křivku učení pro učení rozhodovacího stromu na testovacích datech v R - např. //Iris// a dále pak na datech //parita.csv// - uložena v //{{courses:a6m33dvz:cviceni:parita.zip|parita.zip}}// (pro bližší popis parity např. [[http://cs.wikipedia.org/wiki/Paritn%C3%AD_bit|Paritní bit - Wikipedie]]). - data vždy nejprve prozkoumejte - na základě křivky učení rozhodněte, zda je rozhodovací strom pro daná data vhodný drawLearningCurve <- function(x, y, xtest, ytest, nfolds=10) { folds <- rep_len(1:nfolds,nrow(x)) acc <- vector(length=nfolds) for(j in 1:nfolds){ train <- cbind(y[folds <= j],x[folds <= j,]) names(train)[1] <- 'class' tree <- rpart(class ~ .,data=train,control = rpart.control(minsplit = 3)) acc[j] = sum(predict(tree,newdata=xtest,type='class') == ytest)/length(ytest) } plot((1:nfolds)/nfolds,acc,type="b",col=2,xlab='Mohutnost mnoziny',ylab='Uspesnost',ylim=c(0,1)) abline(h=0.5, col="black") } # an example of use drawLearningCurve(trainCrabs[,-1],trainCrabs[,1],testCrabs[,-1],testCrabs[,1],20)