library(mlr)
library(tidyverse)
library(ggplot2)
library(fastDummies)
library(e1071)
library(corrplot)
setwd("D:/Studies/5 II/Duomenu gavyba/mine/BIG HOMEWORK")
Prieš pradėdamas darbą su duomenų rinkiniu, iš originalaus failo padariau du: pirmasis (kurį naudosiu šiame namų darbe) yra be praleistų reikšmių, o antrojo kiekvienoje eilutėje yra bent po vieną praleistą reikšmę.
Adult duomenų rinkinys yra skirtas klasifikavimo užduočiai spręsti, t.y. nustatyti, ar žmogus uždirba daugiau ar mažiau nei 50 tūkst. dolerių per metus.
https://archive.ics.uci.edu/ml/datasets/Adult
data1 <- read.csv("adult_be.csv", sep = ",")[,-1]
names(data1) <- c("age","workclass","fnlwgt","education","education_num","marital_status","occupation","relationship","race","sex","capital_gain","capital_loss","hours_per_week","native_country","income")
head(data1)
## age workclass fnlwgt education education_num marital_status
## 1 50 Self_emp_not_inc 83311 Bachelors 13 Married_civ_spouse
## 2 38 Private 215646 HS_grad 9 Divorced
## 3 53 Private 234721 11th 7 Married_civ_spouse
## 4 28 Private 338409 Bachelors 13 Married_civ_spouse
## 5 37 Private 284582 Masters 14 Married_civ_spouse
## 6 49 Private 160187 9th 5 Married_spouse_absent
## occupation relationship race sex capital_gain capital_loss
## 1 Exec_managerial Husband White Male 0 0
## 2 Handlers_cleaners Not_in_family White Male 0 0
## 3 Handlers_cleaners Husband Black Male 0 0
## 4 Prof_specialty Wife Black Female 0 0
## 5 Exec_managerial Wife White Female 0 0
## 6 Other_service Not_in_family Black Female 0 0
## hours_per_week native_country income
## 1 13 United_States <=50K
## 2 40 United_States <=50K
## 3 40 United_States <=50K
## 4 40 Cuba <=50K
## 5 40 United_States <=50K
## 6 16 Jamaica <=50K
Šiame duomenų rinkinyje yra 15 atributų: 6-ių iš jų yra tolydžios reikšmės, o likę yra kategoriniai kintamieji. Atributai aprašo šias reikšmes:
Kiek metų praleista mokantis (education_num) pakankamai gerai gali atvaizduoti aukščiausią išsilavinimo lygį. Be to, fnlwgt nesusijęs su income kintamuoju. Dėl šių priežasčių pašalinsime education ir fnlwgt kintamuosius prieš kuriant modelį.
data1 <- data1[,-c(3:4)]
data1$income <- as.factor(data1$income)
Primiausia normalizavome visus skaitinius kintamuosius pasinaudodami min-max normalizavimo metodu:
\[\begin{align*} x_{ij_{norm}} = \displaystyle \frac{x_{ij}-x_{j_{min}}}{x_{ij_{max}}-x_{ij_{min}}}. \end{align*}\]
min.max.norm <- function(x, x.max, x.min)
{
return((x-x.min)/(x.max-x.min))
}
for(i in c(1,9,10,11))
{
max <- max(data1[,i])
min <- min(data1[,i])
for(ii in 1:nrow(data1))
{
data1[ii,i] <- min.max.norm(data1[ii,i], max, min)
}
}
Toliau vizualiai tikriname kintamųjų reikšmes.
ggplot(data1, aes(x=workclass, fill=income)) +
geom_bar()
temp <- NULL
for(i in 1:nrow(data1))
{
ifelse(data1[i,2] == "Private", temp <- c(temp,1), temp <- c(temp,0))
}
data1$workclass <- temp
table(data1$workclass)
##
## 0 1
## 7875 22286
Kadangi grafike matome labai didelį vienos klasės kiekį kintamojame Private, nusprendžiau šį kintamąjį pakeisti į fiktyvų binarinį kintamąjį, kuris nusakys ar objekto workclass reikšmė yra Private, ar ne.
ggplot(data1, aes(x=marital_status, fill=income)) +
geom_bar()
temp <- NULL
for(i in 1:nrow(data1))
{
ifelse(data1[i,4] == "Married_civ_spouse", temp <- c(temp,0), temp <- c(temp,1))
}
data1$marital_status <- temp
table(data1$marital_status)
##
## 0 1
## 14065 16096
marital_status kintamąjį keisiu į fiktyvų binarinį kintamąjį, kuris nusakys ar marital_status reikšmė yra Married_civ_spouse. Taip darome, nes likusiuose kintamuosiuose vos ne išskirtinai tik vienos klasės kintamieji.
par(mfrow = c(1,2))
hist(data1$education_num)
hist(data1$hours_per_week)
Iš pateiktų education_num ir hours_per_week histogramų, matome, kad yra labai dažnai pasikartojančių reikšmių, bet su jomis nieko papildomai daryti nereikia.
ggplot(data1, aes(x=occupation, fill=income)) +
geom_bar()
temp <- NULL
for(i in 1:nrow(data1))
{
ifelse(data1[i,5] == "Craft_repair" |
data1[i,5] == "Exec_managerial" |
data1[i,5] == "Prof_specialty" |
data1[i,5] == "Sales"
, temp <- c(temp,1), temp <- c(temp,0))
}
data1$occupation <- temp
table(data1$occupation)
##
## 0 1
## 14517 15644
Iš occupation reikšmių dažnių stulpelinės diagramos matome, kad šios kokybinės reikšmės yra ganėtinai tolygiai pasiskirsčiusios. Todėl pamėginsime sugrupuoti šiuos kintamuosius tokia tvarka: keturis kintamuosius, kurių priklausymas mėlynai (>50K) grupei yra didžiausias sujungsime į vieną grupę, o likusius į kitą. Tuomet occupation binarinis kintamasis nusakys ar priklauso pirmąjai grupei ar antrajai.
ggplot(data1, aes(x=relationship, fill=income)) +
geom_bar()
temp <- NULL
for(i in 1:nrow(data1))
{
ifelse(data1$relationship[i] == "Husband", temp <- c(temp,0), temp <- c(temp,1))
}
data1$relationship <- temp
relationship kintamojo reikšmių dažnių stulpelinėje diagramoje, taip pat, matome, kad pasiskirstymas yra pakankamai tolygus. Visgi Husband kintamasis vos ne išimtinai turi visas >50K klasei priklausančias reikšmes, todėl relationship kintamąjį pakeisime į binarinį fiktyvų kintamąjį, kuris nusakys ar relationship reikšmė yra Husband.
ggplot(data1, aes(x=race, fill=income)) +
geom_bar()
for(i in 1:nrow(data1))
{
if(data1[i,7] != "White" & data1[i,7] != "Black") {data1[i,7] <- "Other"}
}
data1 <- dummy_columns(data1, select_columns = "race")
data1 <- data1[,-ncol(data1)]
Analizuojant race kintamojo reikšmes, nuspręsta palikti tris grupes (White,Black,Other). Tuomet sudarysime \(n-1\) fiktyvių binarinių kintamųjų, kai \(n\) yra skirtingų race kintamojo reikšmių kiekis, t.y. šiuo atveju \(n = 3\).
ggplot(data1, aes(x=sex, fill=sex)) +
geom_bar()
data1 <- dummy_columns(data1, select_columns = "sex")
data1 <- data1[,-ncol(data1)]
Kintamasis sex gerai pasiskirstęs ir turi tik dvi reikšmes, todėl lengvai pakeičiamas į fiktyvų binarinį kintamąjį.
par(mfrow = c(1,2))
hist(data1$capital_gain)
hist(data1$capital_loss)
Kintamieji captial_gain ir capital_loss yra labai prastai pasiskirstę todėl neša labai mažai informacijos. Dėl to šiuos kintamuosius pašalinsime.
ggplot(data1, aes(x=native_country, fill=income)) +
geom_bar()
Ne išimtis ir native_country kintamasis, kurio nešama informacija yra praktiškai beprasmė šiame tyrime. Jis taip pat pašalinamas iš duomenų rinkinio.
str(data1)
## 'data.frame': 30161 obs. of 11 variables:
## $ age : num 0.452 0.288 0.493 0.151 0.274 ...
## $ workclass : num 0 1 1 1 1 1 0 1 1 1 ...
## $ education_num : Ord.factor w/ 16 levels "1"<"2"<"3"<"4"<..: 13 9 7 13 14 5 9 14 13 10 ...
## $ marital_status: num 0 1 0 0 0 1 0 1 0 0 ...
## $ occupation : num 1 0 0 1 1 0 1 1 1 1 ...
## $ relationship : num 0 1 0 1 1 1 0 1 0 0 ...
## $ hours_per_week: num 0.122 0.398 0.398 0.398 0.398 ...
## $ income : Factor w/ 2 levels "<=50K",">50K": 1 1 1 1 1 1 2 2 2 2 ...
## $ race_Black : int 0 0 1 1 0 1 0 0 0 1 ...
## $ race_Other : int 0 0 0 0 0 0 0 0 0 0 ...
## $ sex_Female : int 0 0 0 1 1 1 0 1 0 0 ...
corrplot::corrplot(cor(data1[,-c(3,8)]), type = "upper")
Kaip galima pastebėti iš kintamųjų koreliacijų diagramos, stipresnė koreliacija galima pastebėti tarp marital_status ir relationship kintamųjų, bet kadangi nekilo problemų dėl kolinearumo, kol kas jo nei vieno nešalinsime.
data1_Task <- makeClassifTask(data = data1[,-3], target = "income")
lda <- makeLearner("classif.lda")
ldaModel <- train(lda, data1_Task)
ldaModelData <- getLearnerModel(ldaModel)
ldaPreds <- predict(ldaModelData)$x
head(ldaPreds)
df <- cbind(data1, ldaPreds)
ggplot(df, aes(x=LD1, fill=income, color=income)) +
geom_histogram()
qda <- makeLearner("classif.qda")
qdaModel <- train(qda, data1_Task)
kFold <- makeResampleDesc(method = "RepCV", folds = 2, reps = 5,
stratify = TRUE)
set.seed(123)
ldaCV <- resample(learner = lda, task = data1_Task, resampling = kFold,
measures = list(mmce, acc))
qdaCV <- resample(learner = qda, task = data1_Task, resampling = kFold,
measures = list(mmce, acc))
ldaCV$aggr
qdaCV$aggr
calculateConfusionMatrix(ldaCV$pred, relative = TRUE)
calculateConfusionMatrix(qdaCV$pred, relative = TRUE)
## LD1
## 1 0.9223140
## 2 -1.1575162
## 3 0.5133259
## 4 1.1576762
## 5 1.4416336
## 6 -1.7045853
## mmce.test.mean acc.test.mean
## 0.2052571 0.7947429
## mmce.test.mean acc.test.mean
## 0.2475993 0.7524007
## Relative confusion matrix (normalized by row/column):
## predicted
## true <=50K >50K -err.-
## <=50K 0.87/0.86 0.13/0.41 0.13
## >50K 0.42/0.14 0.58/0.59 0.42
## -err.- 0.14 0.41 0.21
##
##
## Absolute confusion matrix:
## predicted
## true <=50K >50K -err.-
## <=50K 982345 150305 150305
## >50K 159233 216167 159233
## -err.- 159233 150305 309538
## Relative confusion matrix (normalized by row/column):
## predicted
## true <=50K >50K -err.-
## <=50K 0.75/0.90 0.25/0.50 0.25
## >50K 0.25/0.10 0.75/0.50 0.25
## -err.- 0.10 0.50 0.25
##
##
## Absolute confusion matrix:
## predicted
## true <=50K >50K -err.-
## <=50K 852536 280114 280114
## >50K 93278 282122 93278
## -err.- 93278 280114 373392
Kaip matome iš rezultatų, po 500 iteracijų LDA metodo tikslumas \(\sim 79\%\), o QDA \(\sim 75\%\). Nors tie keturi procentai atrodo nedaug, iš confusion matrix matome, kad per tuos 500 iteracijų QDA metodas \(\sim 64\) tūkstančiais daugiau kartų neteisingai suklasifikavo nematytus objektus.
data1_Task <- makeClassifTask(data = data1[,-3], target = "income")
lda <- makeLearner("classif.lda")
holdout <- makeResampleDesc(method = "Holdout", split = 4/5, stratify = TRUE)
set.seed(123)
holdoutCV_lda <- resample(learner = lda, task = data1_Task, resampling = holdout, measures = list(mmce, acc))
## Resampling: holdout
## Measures: mmce acc
## [Resample] iter 1: 0.2181336 0.7818664
##
## Aggregated Result: mmce.test.mean=0.2181336,acc.test.mean=0.7818664
##
calculateConfusionMatrix(holdoutCV_lda$pred, relative = TRUE)
## Relative confusion matrix (normalized by row/column):
## predicted
## true <=50K >50K -err.-
## <=50K 0.86/0.85 0.14/0.44 0.14
## >50K 0.45/0.15 0.55/0.56 0.45
## -err.- 0.15 0.44 0.22
##
##
## Absolute confusion matrix:
## predicted
## true <=50K >50K -err.-
## <=50K 3897 634 634
## >50K 682 820 682
## -err.- 682 634 1316
Holdout metodui padalinome mokymo imtį į penkias dalis ir keturias iš jų naudojome mokymui bei vieną testavimui.
Gauname, kad LDA modelio tikslumas \(\sim 78\%\), kai naudojame \(4/5\) duomenų mokymui. \(1316\) iš \(6033\) objektų klasifikuota neteisingai. Visgi pastebime, kad mažas skirtumas tarp klaidų nustatant klases skaičiaus, t.y. spėja vienodai klaidingai.
Automobiles duomenų rinkinys buyo naudojamas regresijos užduočiai spręsti, t.y. prognozuoti automobilio kainą pagal skaitines ir binarines reikšmes. Kadangi šiame uždavinyje yra nemažai kategorinių reikšmių, galima jų pagalba sudaryti ir klasifikavimo uždavinį.
https://archive.ics.uci.edu/ml/datasets/Automobile
data2 <- read.csv("auto_be.csv", sep = ",")[,-1]
head(data2)
## symboling normalized_losses make fuel_type aspiration num_of_doors body_style
## 1 2 164 audi gas std four sedan
## 2 2 164 audi gas std four sedan
## 3 1 158 audi gas std four sedan
## 4 1 158 audi gas turbo four sedan
## 5 2 192 bmw gas std two sedan
## 6 0 192 bmw gas std four sedan
## drive_wheels engine_location wheel_base length width height curb_weight
## 1 fwd front 99.8 176.6 66.2 54.3 2337
## 2 4wd front 99.4 176.6 66.4 54.3 2824
## 3 fwd front 105.8 192.7 71.4 55.7 2844
## 4 fwd front 105.8 192.7 71.4 55.9 3086
## 5 rwd front 101.2 176.8 64.8 54.3 2395
## 6 rwd front 101.2 176.8 64.8 54.3 2395
## engine_type num_of_cylinders engine_size fuel_system bore stroke
## 1 ohc four 109 mpfi 3.19 3.4
## 2 ohc five 136 mpfi 3.19 3.4
## 3 ohc five 136 mpfi 3.19 3.4
## 4 ohc five 131 mpfi 3.13 3.4
## 5 ohc four 108 mpfi 3.50 2.8
## 6 ohc four 108 mpfi 3.50 2.8
## compression_ratio horsepower peak_rpm city_mpg highway_mpg price
## 1 10.0 102 5500 24 30 13950
## 2 8.0 115 5500 18 22 17450
## 3 8.5 110 5500 19 25 17710
## 4 8.3 140 5500 17 20 23875
## 5 8.8 101 5800 23 29 16430
## 6 8.8 101 5800 23 29 16925
Šiame duomenų rinkinyje yra 159 objektai su 26 atributai: 15 iš jų yra tolydžios reikšmės, 1 sveikojo skaičiaus ir likę 10 yra kategoriniai kintamieji.
apply(data2[,c(4,5,6,7,8,9,15,16,18)], 2, table)
## $fuel_type
##
## diesel gas
## 15 144
##
## $aspiration
##
## std turbo
## 132 27
##
## $num_of_doors
##
## four two
## 95 64
##
## $body_style
##
## convertible hardtop hatchback sedan wagon
## 2 5 56 79 17
##
## $drive_wheels
##
## 4wd fwd rwd
## 8 105 46
##
## $engine_location
##
## front
## 159
##
## $engine_type
##
## dohc l ohc ohcf ohcv
## 8 8 123 12 8
##
## $num_of_cylinders
##
## eight five four six three
## 1 7 136 14 1
##
## $fuel_system
##
## 1bbl 2bbl idi mfi mpfi spdi
## 11 63 15 1 64 5
data2$num_of_doors <- as.factor(data2$num_of_doors)
data2 <- data2[,-c(1,9)]
Iš kokybinių kintamųjų dažnių lentelės matome, kad geriausiai pasiskirstęs kintamasis yra num_of_doors, todėl siekdami sukurti kokybišką ML modelį, klasifikuosime šį kintamąjį. Be to, iš karto galime pastebėti, kad kintamasis engine_location turi tik vieną reikšmę (neneša informacijos), todėl jau šiame etape jį pašalinsime. Pašalinsime ir symboling kintamąjį, kuris netinka LDA ir QDA metodams, nes yra ranguotas kokybinis kintamasis.
Tuomet atlikome skaitinių kintamųjų normalizavimą, kad išvengti skirtingose skalėse esančių kintamųjų persvaros. Normalizavome pasinaudodami min-max normalizavimo metodu:
\[\begin{align*} x_{ij_{norm}} = \displaystyle \frac{x_{ij}-x_{j_{min}}}{x_{ij_{max}}-x_{ij_{min}}}. \end{align*}\]
par(mfrow = c(2,4))
hist(data2$normalized_losses, main = "normalized_losses")
hist(data2$wheel_base, main = "wheel_base")
hist(data2$length, main = "length")
hist(data2$width, main = "width")
hist(data2$height, main = "height")
hist(data2$curb_weight, main = "curb_weight")
hist(data2$engine_size, main = "engine_size")
hist(data2$bore, main = "bore")
hist(data2$stroke, main = "stroke")
hist(data2$compression_ratio, main = "compression_ratio")
hist(data2$horsepower, main = "horsepower")
hist(data2$peak_rpm, main = "peak_rpm")
hist(data2$city_mpg, main = "city_mpg")
hist(data2$highway_mpg, main = "highway_mpg")
hist(data2$price, main = "price")
Iš historgramų matyti, kad tik compression_ratio kintamasis neneša informacijos, todėl jį pašaliname.
Tiesinei priklausomybei tarp kiekybinių kintamųjų patikrinti naudosime Pirsono koreliacijos koeficientą (angl. Pearson corelation coefficient):
\[\begin{align*} \rho_{X,Y} = \frac{cov(X,Y)}{\sigma_X \sigma_Y}; \end{align*}\]
kur \(cov\) yra kovariacija, \(\sigma_X\) yra \(X\)-o standartinis nuokrypis ir \(\sigma_Y\) - \(Y\) standartinis nuokrypis.
corrplot(cor(data2[,c(1,8:12,15,18,20:24)]), method = "pie", type = "upper")
data2 <- data2[,-c(9,10,12,15,19,20,22)]
corrplot(cor(data2[,c(1,8:9,13:17)]), method = "number", type = "upper")
Siekiant sumažinti tą pačią informaciją nešančių kintamųjų kiekį (tuo pačiu sumažinant modelio šališkumą), iš modelio pašalinome labai aukštą koreliaciją \((\rho_{X,Y} > 0.8)\) turinčius kintamuosius, t.y. pašalinome length, width, curb_weight, engine_size, compression_ratio, horsepower ir city_mpg.
Toliau vizualiai tikriname kokybinius kintamuosius.
Autoriaus pastaba: tik padarius visus kokybinius kintamuosius į fiktyvius binarinius (grupavimo pagalba) pavyko padaryti kad QDA nemestų “rank defficiency” error’o.
ggplot(data = data2, aes(x=make, fill=num_of_doors)) +
geom_bar()
data2 <- data2[,-2]
Kadangi automobilių markių yra labai daug, o klasių pasiskirstymas per jas yra labai išsibarstęs - negalime protingai jų sugrupuoti.
ggplot(data = data2, aes(x=fuel_type, fill=num_of_doors)) +
geom_bar()
temp <- NULL
for(i in 1:nrow(data2))
{
ifelse(data2$fuel_type[i] == "gas",
temp <- c(temp,1),
temp <- c(temp,0))
}
data2$fuel_type <- temp
Kadangi kintamasis fuel_type turi tik dvi reikšmes pakeitėme jas į fiktyvų binarinį kintamąjį, kuris nurodo ar kuro tipas yra gas, ar ne.
ggplot(data = data2, aes(x=aspiration, fill=num_of_doors)) +
geom_bar()
temp <- NULL
for(i in 1:nrow(data2))
{
ifelse(data2$aspiration[i] == "std",
temp <- c(temp,1),
temp <- c(temp,0))
}
data2$aspiration <- temp
Kaip ir ankstesniam kintamąjam, aspiration kintamąjį pakeitėm į fiktyvų binarinį kintamąjį, kuris nurodo, ar oro tiekimas automobiliui yra std tipo, ar ne.
ggplot(data = data2, aes(x=num_of_cylinders, fill=num_of_doors)) +
geom_bar()
for(i in 1:nrow(data2))
{
if(data2$num_of_cylinders[i] == "three"){data2$num_of_cylinders[i] <- 3}
if(data2$num_of_cylinders[i] == "four"){data2$num_of_cylinders[i] <- 4}
if(data2$num_of_cylinders[i] == "five"){data2$num_of_cylinders[i] <- 5}
if(data2$num_of_cylinders[i] == "six"){data2$num_of_cylinders[i] <- 6}
if(data2$num_of_cylinders[i] == "eight"){data2$num_of_cylinders[i] <- 8}
}
data2$num_of_cylinders <- as.numeric(data2$num_of_cylinders)
Pastebėjau, kad kintamojo num_of_cylinders reikšmės yra paprasčiausiai skaičiai užrašyti žodžiais, tad atkeičiau atgal į skaičius.
ggplot(data = data2, aes(x=body_style, fill=num_of_doors)) +
geom_bar()
for(i in 1:nrow(data2))
{
ifelse(data2$body_style[i] == "sedan",
data2$body_style[i] <- 1,
data2$body_style[i] <- 0)
}
data2$body_style <- as.numeric(data2$body_style)
body_style kintamąjam nusprendžiau grupuoti, pagal tai ar priklauso ar nepriklauso populiariausiam variantui, t.y. ar reikšmė lygi sedan, ar ne.
ggplot(data = data2, aes(x=drive_wheels, fill=num_of_doors)) +
geom_bar()
for(i in 1:nrow(data2))
{
ifelse(data2$drive_wheels[i] == "fwd",
data2$drive_wheels[i] <- 1,
data2$drive_wheels[i] <- 0)
}
data2$drive_wheels <- as.numeric(data2$drive_wheels)
Analogiškai ankstesnio kintamojo atvejui, drive_wheels kintamasis pakeistas į fiktyvų binarinį kintamąjį kuris nurodo ar reikšmė yra fwd, ar ne.
ggplot(data = data2, aes(x=engine_type, fill=num_of_doors)) +
geom_bar()
for(i in 1:nrow(data2))
{
ifelse(data2$engine_type[i] != "ohc",
data2$engine_type[i] <- 0,
data2$engine_type[i] <- 1)
}
data2$engine_type <- as.numeric(data2$engine_type)
Kaip ir ankstesniem dviem kintamiesiams, engine_type grupuoju pagal dažniausią reikšmę ohc. Taigi fiktyvus binarinis kintamasis nurodo ar reikšmė yra ohc, ar ne.
ggplot(data = data2, aes(x=fuel_system, fill=num_of_doors)) +
geom_bar()
for(i in 1:nrow(data2))
{
ifelse(data2$fuel_system[i] == "2bbl",
data2$fuel_system[i] <- 1,
data2$fuel_system[i] <- 0)
}
data2$fuel_system <- as.numeric(data2$fuel_system)
Dėl problemų su QDA, išbandžiau įvairius grupavimo variantus, ir galiausiai suveikė fuel_system kintamojo reikšmes sugrupavus į dvi grupęs: arba reikšmė lygi 2bbl, arba ne.
data2_Task <- makeClassifTask(data = data2, target = "num_of_doors")
lda <- makeLearner("classif.lda")
ldaModel <- train(lda, data2_Task)
ldaModelData <- getLearnerModel(ldaModel)
ldaPreds <- predict(ldaModelData)$x
head(ldaPreds)
df <- cbind(data2, ldaPreds)
ggplot(df, aes(x=LD1, fill=num_of_doors, color=num_of_doors)) +
geom_histogram()
qda <- makeLearner("classif.qda")
qdaModel <- train(qda, data2_Task)
kFold <- makeResampleDesc(method = "RepCV", folds = 10, reps = 50,
stratify = TRUE)
ldaCV <- resample(learner = lda, task = data2_Task, resampling = kFold,
measures = list(mmce, acc))
set.seed(1232131231)
qdaCV <- resample(learner = qda, task = data2_Task, resampling = kFold,
measures = list(mmce, acc))
ldaCV$aggr
qdaCV$aggr
calculateConfusionMatrix(ldaCV$pred, relative = TRUE)
calculateConfusionMatrix(qdaCV$pred, relative = TRUE)
## LD1
## 1 -0.31267527
## 2 -0.03460106
## 3 -1.26614105
## 4 -1.38193057
## 5 0.40131860
## 6 0.40493861
## mmce.test.mean acc.test.mean
## 0.1874495 0.8125505
## mmce.test.mean acc.test.mean
## 0.2270441 0.7729559
## Relative confusion matrix (normalized by row/column):
## predicted
## true four two -err.-
## four 0.88/0.82 0.12/0.20 0.12
## two 0.29/0.18 0.71/0.80 0.29
## -err.- 0.18 0.20 0.19
##
##
## Absolute confusion matrix:
## predicted
## true four two -err.-
## four 4180 570 570
## two 921 2279 921
## -err.- 921 570 1491
## Relative confusion matrix (normalized by row/column):
## predicted
## true four two -err.-
## four 0.84/0.79 0.16/0.26 0.16
## two 0.32/0.21 0.68/0.74 0.32
## -err.- 0.21 0.26 0.23
##
##
## Absolute confusion matrix:
## predicted
## true four two -err.-
## four 3970 780 780
## two 1025 2175 1025
## -err.- 1025 780 1805
Kaip matome iš rezultatų, po 500 iteracijų LDA metodo tikslumas \(\sim 81\%\), o QDA \(\sim 77\%\). Iš confusion matrix matome, kad QDA metodas \(\sim 300\)-ais objektų daugiau suklasifikavo neteisingai, nei LDA metodas.
data2_Task <- makeClassifTask(data = data2, target = "num_of_doors")
lda <- makeLearner("classif.lda")
holdout <- makeResampleDesc(method = "Holdout", split = 4/5, stratify = TRUE)
set.seed(123)
holdoutCV_lda <- resample(learner = lda,
task = data2_Task,
resampling = holdout,
measures = list(mmce, acc))
## Resampling: holdout
## Measures: mmce acc
## [Resample] iter 1: 0.1875000 0.8125000
##
## Aggregated Result: mmce.test.mean=0.1875000,acc.test.mean=0.8125000
##
calculateConfusionMatrix(holdoutCV_lda$pred, relative = TRUE)
## Relative confusion matrix (normalized by row/column):
## predicted
## true four two -err.-
## four 0.95/0.78 0.05/0.11 0.05
## two 0.38/0.22 0.62/0.89 0.38
## -err.- 0.22 0.11 0.19
##
##
## Absolute confusion matrix:
## predicted
## true four two -err.-
## four 18 1 1
## two 5 8 5
## -err.- 5 1 6
Holdout metodui padalinome mokymo imtį į penkias dalis ir keturias iš jų naudojome mokymui bei vieną testavimui.
Gauname, kad LDA modelio tikslumas \(\sim 81\%\), kai naudojame \(4/5\) duomenų mokymui. \(6\) iš \(32\) objektų klasifikuota neteisingai.