Search
TEST 05
<latex> \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} </latex>
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ý?
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)
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í.
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 parita.zip (pro bližší popis parity např. Paritní bit - Wikipedie).
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)