Kas yra sprendimų medžiai?
Sprendimų medžiai yra universalus mašininio mokymosi algoritmas, kuris gali atlikti klasifikavimo ir regresijos užduotis. Tai labai galingi algoritmai, galintys pritaikyti sudėtingus duomenų rinkinius. Be to, sprendimų medžiai yra pagrindiniai atsitiktinių miškų komponentai, kurie yra vieni iš galingiausių šiandien galimų mašininio mokymosi algoritmų.
Mokymas ir vizualizavimas sprendimų medžiuose
Norėdami sukurti savo pirmąjį sprendimų medį „R“ pavyzdyje, veiksime taip, kaip nurodyta šioje sprendimų medžio pamokoje:
- 1 veiksmas: importuokite duomenis
- 2 veiksmas: išvalykite duomenų rinkinį
- 3 žingsnis: sukurkite traukinių / bandymų rinkinį
- 4 žingsnis: Sukurkite modelį
- 5 žingsnis: numatykite
- 6 žingsnis: įvertinkite našumą
- 7 veiksmas: sureguliuokite hiper parametrus
1 žingsnis) Importuokite duomenis
Jei smalsu dėl titaniko likimo, galite žiūrėti šį vaizdo įrašą „Youtube“. Šio duomenų rinkinio tikslas yra numatyti, kurie žmonės labiau išgyvena po susidūrimo su ledkalniu. Duomenų rinkinyje yra 13 kintamųjų ir 1309 stebėjimai. Duomenų rinkinį tvarko kintamasis X.
set.seed(678)path <- 'https://raw.githubusercontent.com/guru99-edu/R-Programming/master/titanic_data.csv'titanic <-read.csv(path)head(titanic)
Išvestis:
## X pclass survived name sex## 1 1 1 1 Allen, Miss. Elisabeth Walton female## 2 2 1 1 Allison, Master. Hudson Trevor male## 3 3 1 0 Allison, Miss. Helen Loraine female## 4 4 1 0 Allison, Mr. Hudson Joshua Creighton male## 5 5 1 0 Allison, Mrs. Hudson J C (Bessie Waldo Daniels) female## 6 6 1 1 Anderson, Mr. Harry male## age sibsp parch ticket fare cabin embarked## 1 29.0000 0 0 24160 211.3375 B5 S## 2 0.9167 1 2 113781 151.5500 C22 C26 S## 3 2.0000 1 2 113781 151.5500 C22 C26 S## 4 30.0000 1 2 113781 151.5500 C22 C26 S## 5 25.0000 1 2 113781 151.5500 C22 C26 S## 6 48.0000 0 0 19952 26.5500 E12 S## home.dest## 1 St Louis, MO## 2 Montreal, PQ / Chesterville, ON## 3 Montreal, PQ / Chesterville, ON## 4 Montreal, PQ / Chesterville, ON## 5 Montreal, PQ / Chesterville, ON## 6 New York, NY
tail(titanic)
Išvestis:
## X pclass survived name sex age sibsp## 1304 1304 3 0 Yousseff, Mr. Gerious male NA 0## 1305 1305 3 0 Zabour, Miss. Hileni female 14.5 1## 1306 1306 3 0 Zabour, Miss. Thamine female NA 1## 1307 1307 3 0 Zakarian, Mr. Mapriededer male 26.5 0## 1308 1308 3 0 Zakarian, Mr. Ortin male 27.0 0## 1309 1309 3 0 Zimmerman, Mr. Leo male 29.0 0## parch ticket fare cabin embarked home.dest## 1304 0 2627 14.4583 C## 1305 0 2665 14.4542 C## 1306 0 2665 14.4542 C## 1307 0 2656 7.2250 C## 1308 0 2670 7.2250 C## 1309 0 315082 7.8750 S
Iš galvos ir uodegos išvesties galite pastebėti, kad duomenys nėra maišomi. Tai didelis klausimas! Kai suskirstysite duomenis tarp traukinių ir bandymų rinkinių, pasirinksite tik 1 ir 2 klasės keleivius (nė vienas iš 3 klasės keleivių nėra 80 procentų stebėjimų), o tai reiškia, kad algoritmas niekada nematys 3 klasės keleivio ypatybės. Dėl šios klaidos bus blogai prognozuojama.
Norėdami išspręsti šią problemą, galite naudoti funkcijos pavyzdį ().
shuffle_index <- sample(1:nrow(titanic))head(shuffle_index)
Sprendimo medžio R kodas Paaiškinimas
- imtis (1: nrow (titanic)): sukurkite atsitiktinį indekso sąrašą nuo 1 iki 1309 (ty didžiausią eilučių skaičių).
Išvestis:
## [1] 288 874 1078 633 887 992
Šį indeksą naudosite maišydami titanišką duomenų rinkinį.
titanic <- titanic[shuffle_index, ]head(titanic)
Išvestis:
## X pclass survived## 288 288 1 0## 874 874 3 0## 1078 1078 3 1## 633 633 3 0## 887 887 3 1## 992 992 3 1## name sex age## 288 Sutton, Mr. Frederick male 61## 874 Humblen, Mr. Adolf Mathias Nicolai Olsen male 42## 1078 O'Driscoll, Miss. Bridget female NA## 633 Andersson, Mrs. Anders Johan (Alfrida Konstantia Brogren) female 39## 887 Jermyn, Miss. Annie female NA## 992 Mamee, Mr. Hanna male NA## sibsp parch ticket fare cabin embarked home.dest## 288 0 0 36963 32.3208 D50 S Haddenfield, NJ## 874 0 0 348121 7.6500 F G63 S## 1078 0 0 14311 7.7500 Q## 633 1 5 347082 31.2750 S Sweden Winnipeg, MN## 887 0 0 14313 7.7500 Q## 992 0 0 2677 7.2292 C
2 žingsnis. Išvalykite duomenų rinkinį
Duomenų struktūra rodo, kad kai kurie kintamieji turi NA. Duomenys išvalomi taip
- Drop kintamieji home.dest, kajutė, vardas, X ir bilietas
- Sukurkite veiksnių kintamuosius pclass ir išgyveno
- Išmeskite NA
library(dplyr)# Drop variablesclean_titanic <- titanic % > %select(-c(home.dest, cabin, name, X, ticket)) % > %#Convert to factor levelmutate(pclass = factor(pclass, levels = c(1, 2, 3), labels = c('Upper', 'Middle', 'Lower')),survived = factor(survived, levels = c(0, 1), labels = c('No', 'Yes'))) % > %na.omit()glimpse(clean_titanic)
Kodo paaiškinimas
- pasirinkite (-c (home.dest, kajutė, vardas, X, bilietas)): numeskite nereikalingus kintamuosius
- pclass = faktorius (pclass, lygiai = c (1,2,3), etiketės = c ('Viršutinė', 'Vidurinė', 'Žemutinė')): pridėkite etiketę prie kintamojo pclass. 1 tampa Viršutine, 2 tampa MIddle ir 3 tampa žemesniu
- faktorius (išgyveno, lygiai = c (0,1), etiketės = c („Ne“, „Taip“)): pridėkite etiketę prie išlikusio kintamojo. 1 tampa Ne, o 2 tampa Taip
- na.omit (): pašalinkite NA pastebėjimus
Išvestis:
## Observations: 1,045## Variables: 8## $ pclassUpper, Lower, Lower, Upper, Middle, Upper, Middle, U… ## $ survived No, No, No, Yes, No, Yes, Yes, No, No, No, No, No, Y… ## $ sex male, male, female, female, male, male, female, male… ## $ age 61.0, 42.0, 39.0, 49.0, 29.0, 37.0, 20.0, 54.0, 2.0,… ## $ sibsp 0, 0, 1, 0, 0, 1, 0, 0, 4, 0, 0, 1, 1, 0, 0, 0, 1, 1,… ## $ parch 0, 0, 5, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 2, 0, 4, 0,… ## $ fare 32.3208, 7.6500, 31.2750, 25.9292, 10.5000, 52.5542,… ## $ embarked S, S, S, S, S, S, S, S, S, C, S, S, S, Q, C, S, S, C…
3 žingsnis) Sukurkite traukinių / bandymų rinkinį
Prieš treniruodami modelį, turite atlikti du veiksmus:
- Sukurkite traukinį ir bandymų rinkinį: treniruojate modelį traukinio rinkinyje ir išbandote bandymo prognozę (ty nematytus duomenis)
- Įdiekite rpart.plot iš konsolės
Įprasta praktika yra padalinti duomenis 80/20, 80 procentų duomenų naudojama modelio mokymui, o 20 procentų - prognozėms. Turite sukurti du atskirus duomenų rėmus. Nenorite liesti bandymo rinkinio, kol baigsite kurti savo modelį. Galite sukurti funkcijos pavadinimą create_train_test (), kuriam reikia trijų argumentų.
create_train_test(df, size = 0.8, train = TRUE)arguments:-df: Dataset used to train the model.-size: Size of the split. By default, 0.8. Numerical value-train: If set to `TRUE`, the function creates the train set, otherwise the test set. Default value sets to `TRUE`. Boolean value.You need to add a Boolean parameter because R does not allow to return two data frames simultaneously.
create_train_test <- function(data, size = 0.8, train = TRUE) {n_row = nrow(data)total_row = size * n_rowtrain_sample < - 1: total_rowif (train == TRUE) {return (data[train_sample, ])} else {return (data[-train_sample, ])}}
Kodo paaiškinimas
- funkcija (duomenys, dydis = 0,8, traukinys = TIESA): įtraukite argumentus į funkciją
- n_row = nrow (duomenys): suskaičiuokite duomenų rinkinio eilučių skaičių
- total_row = dydis * n_row: grąžinkite n-ą eilutę, kad sukonstruotumėte traukinių rinkinį
- train_sample <- 1: total_row: pasirinkite pirmąją eilutę iki n-osios eilutės
- if (traukinys == TIESA) {} dar {}: jei sąlyga nustatyta į „tiesa“, grąžinkite traukinių rinkinį, kitu atveju - bandymo rinkinį.
Galite patikrinti savo funkciją ir patikrinti matmenis.
data_train <- create_train_test(clean_titanic, 0.8, train = TRUE)data_test <- create_train_test(clean_titanic, 0.8, train = FALSE)dim(data_train)
Išvestis:
## [1] 836 8
dim(data_test)
Išvestis:
## [1] 209 8
Traukinio duomenų rinkinyje yra 1046 eilutės, o bandomajame - 262 eilutės.
Norėdami patikrinti, ar atsitiktinių imčių procesas yra teisingas, naudojate funkciją prop.table () kartu su lentele ().
prop.table(table(data_train$survived))
Išvestis:
#### No Yes## 0.5944976 0.4055024
prop.table(table(data_test$survived))
Išvestis:
#### No Yes## 0.5789474 0.4210526
Abiejuose duomenų rinkiniuose išgyvenusiųjų skaičius yra vienodas, apie 40 proc.
Įdiekite rpart.plot
„rpart.plot“ nėra „conda“ bibliotekose. Jį galite įdiegti iš konsolės:
install.packages("rpart.plot")
4 žingsnis) Sukurkite modelį
Jūs esate pasirengęs sukurti modelį. Rpart sprendimų medžio funkcijos sintaksė yra:
rpart(formula, data=, method='')arguments:- formula: The function to predict- data: Specifies the data frame- method:- "class" for a classification tree- "anova" for a regression tree
Jūs naudojate klasės metodą, nes jūs numatote klasę.
library(rpart)library(rpart.plot)fit <- rpart(survived~., data = data_train, method = 'class')rpart.plot(fit, extra = 106
Kodo paaiškinimas
- rpart (): funkcija, tinkanti modeliui. Argumentai yra šie:
- išgyveno ~ .: Sprendimų medžių formulė
- duomenys = duomenų_traukinys: duomenų rinkinys
- method = 'class': pritaikykite dvejetainį modelį
- rpart.plot (fit, extra = 106): Nubraižykite medį. Papildomos funkcijos yra nustatytos į 101, kad būtų rodoma 2 klasės tikimybė (naudinga dvejetainiams atsakams). Norėdami gauti daugiau informacijos apie kitus pasirinkimus, galite kreiptis į vinjetę.
Išvestis:
Pradėsite nuo šaknies mazgo (0 gylis virš 3, grafiko viršus):
- Viršuje tai yra bendra išgyvenimo tikimybė. Tai rodo, kiek keleivių išgyveno per avariją. Išgyveno 41 procentas keleivių.
- Šis mazgas klausia, ar keleivio lytis yra vyriška. Jei taip, tada eikite į kairįjį šaknies vaiko mazgą (gylis 2). 63 proc. Yra vyrai, kurių išgyvenimo tikimybė yra 21 proc.
- Antrame mazge klausiate, ar keleivis vyras yra vyresnis nei 3,5 metų. Jei taip, tada išgyvenimo tikimybė yra 19 proc.
- Jūs taip ir toliau einate, kad suprastumėte, kokios savybės daro įtaką išgyvenimo tikimybei.
Atkreipkite dėmesį, kad viena iš daugelio sprendimų medžių savybių yra ta, kad joms reikia labai mažai paruošti duomenis. Ypač jiems nereikia keisti funkcijų mastelio ar centruoti.
Pagal numatytuosius nustatymus funkcija rpart () naudoja „ Gini“ priemaišų priemonę, kad padalintų natą. Kuo didesnis Gini koeficientas, tuo daugiau skirtingų egzempliorių mazge.
5 žingsnis) Padarykite numatymą
Galite nuspėti bandomąjį duomenų rinkinį. Norėdami numatyti, galite naudoti numatymo () funkciją. Pagrindinė R sprendimo medžio numatymo sintaksė yra:
predict(fitted_model, df, type = 'class')arguments:- fitted_model: This is the object stored after model estimation.- df: Data frame used to make the prediction- type: Type of prediction- 'class': for classification- 'prob': to compute the probability of each class- 'vector': Predict the mean response at the node level
Iš bandymo rinkinio norite numatyti, kurie keleiviai greičiausiai išgyvens po susidūrimo. Tai reiškia, kad tarp tų 209 keleivių žinosite, kuris išgyvens, ar ne.
predict_unseen <-predict(fit, data_test, type = 'class')
Kodo paaiškinimas
- numatyti (tinkamas, duomenų_testas, tipas = 'klasė'): numatyti bandymų rinkinio klasę (0/1)
Tikrinti keleivį, kuris nepateko, ir tuos, kurie tai padarė.
table_mat <- table(data_test$survived, predict_unseen)table_mat
Kodo paaiškinimas
- lentelė (duomenų_testas $ išgyveno, nuspėjamas_nematytas): sukurkite lentelę, kad suskaičiuotumėte, kiek keleivių yra klasifikuojami kaip išgyvenę ir mirę, palyginti su teisingu sprendimų medžio klasifikavimu R
Išvestis:
## predict_unseen## No Yes## No 106 15## Yes 30 58
Modelis teisingai numatė 106 žuvusius keleivius, tačiau 15 išgyvenusiųjų priskyrė mirusiems. Pagal analogiją modelis neteisingai priskyrė 30 keleivių kaip išgyvenusiems, o paaiškėjo, kad jie yra mirę.
6 žingsnis) Išmatuokite našumą
Galite apskaičiuoti klasifikavimo užduoties tikslumo matą su painiavos matrica :
Painiavos matrica yra geresnis pasirinkimas įvertinti klasifikavimo rezultatus. Bendra idėja yra suskaičiuoti, kiek kartų tikrieji atvejai klasifikuojami kaip klaidingi.
Kiekviena painiavos matricos eilutė rodo tikrąjį taikinį, o kiekvienas stulpelis - numatomą tikslą. Pirmoje šios matricos eilutėje laikomi mirę keleiviai (klaidinga klasė): 106 buvo teisingai priskirti mirusiems ( tikras neigiamas ), o likęs klaidingai priskirtas maitintojo netekusiems ( klaidingai teigiamas ). Antroje eilėje laikomi išgyvenusieji, teigiama klasė buvo 58 ( tiesa teigiama ), o tikra neigiama - 30.
Tikslumo testą galite apskaičiuoti iš painiavos matricos:
Tai yra tikro teigiamo ir tikro neigiamo santykis per matricos sumą. Naudodami R galite koduoti taip:
accuracy_Test <- sum(diag(table_mat)) / sum(table_mat)
Kodo paaiškinimas
- suma (diag (table_mat)): įstrižainės suma
- suma (lentelės_matas): Matricos suma.
Galite atspausdinti bandymo rinkinio tikslumą:
print(paste('Accuracy for test', accuracy_Test))
Išvestis:
## [1] "Accuracy for test 0.784688995215311"
Testo rinkinys turi 78 procentų balą. Tą patį pratimą galite pakartoti naudodami mokymo duomenų rinkinį.
7 žingsnis) Sureguliuokite hiper parametrus
R sprendimų medis R turi įvairius parametrus, kurie kontroliuoja tinkamumo aspektus. „Rpart“ sprendimo medžio bibliotekoje parametrus galite valdyti naudodami funkciją rpart.control (). Šiame kode pateikite parametrus, kuriuos sureguliuosite. Dėl kitų parametrų galite kreiptis į vinjetę.
rpart.control(minsplit = 20, minbucket = round(minsplit/3), maxdepth = 30)Arguments:-minsplit: Set the minimum number of observations in the node before the algorithm perform a split-minbucket: Set the minimum number of observations in the final note i.e. the leaf-maxdepth: Set the maximum depth of any node of the final tree. The root node is treated a depth 0
Mes elgsimės taip:
- Sukonstruokite funkciją, kad grąžintumėte tikslumą
- Sureguliuokite maksimalų gylį
- Sureguliuokite mažiausią mėginio skaičių, kurį mazgas turi turėti, kad galėtų padalyti
- Sureguliuokite mažiausią mėginių, kuriuos turi turėti lapų mazgas, skaičių
Norėdami parašyti tikslumą, galite parašyti funkciją. Paprasčiausiai suvyniokite anksčiau naudotą kodą:
- numatyti: numatyti_nepastatytas <- numatyti (tinkamas, duomenų_testas, tipas = 'klasė')
- Gaminti lentelę: table_mat <- table (duomenų_testas $ išgyveno, numatomas_nematytas)
- Apskaičiuokite tikslumą: tikslumo_testas <- suma (diag (lentelės_matas)) / suma (lentelės_matas)
accuracy_tune <- function(fit) {predict_unseen <- predict(fit, data_test, type = 'class')table_mat <- table(data_test$survived, predict_unseen)accuracy_Test <- sum(diag(table_mat)) / sum(table_mat)accuracy_Test}
Galite pabandyti sureguliuoti parametrus ir sužinoti, ar galite patobulinti modelį virš numatytosios vertės. Primename, kad turite gauti didesnį nei 0,78 tikslumą
control <- rpart.control(minsplit = 4,minbucket = round(5 / 3),maxdepth = 3,cp = 0)tune_fit <- rpart(survived~., data = data_train, method = 'class', control = control)accuracy_tune(tune_fit)
Išvestis:
## [1] 0.7990431
Naudojant šį parametrą:
minsplit = 4minbucket= round(5/3)maxdepth = 3cp=0
Jūs gaunate didesnį našumą nei ankstesnis modelis. Sveikiname!
Santrauka
Galime apibendrinti funkcijas, mokančias sprendimų medžio algoritmą R
Biblioteka |
Tikslas |
funkcija |
klasė |
parametrus |
detales |
---|---|---|---|---|---|
rpart |
Traukinių klasifikacijos medis R |
rpart () |
klasė |
formulė, df, metodas | |
rpart |
Traukinio regresijos medis |
rpart () |
anova |
formulė, df, metodas | |
rpart |
Nubraižykite medžius |
rpart.plot () |
pritaikytas modelis | ||
bazė |
numatyti |
numatyti() |
klasė |
pritaikytas modelis, tipas | |
bazė |
numatyti |
numatyti() |
prob |
pritaikytas modelis, tipas | |
bazė |
numatyti |
numatyti() |
vektorius |
pritaikytas modelis, tipas | |
rpart |
Kontrolės parametrai |
rpart.control () |
minsplit |
Nustatykite mažiausią stebėjimų skaičių mazge prieš algoritmui atliekant skaidymą |
|
minbucket |
Paskutinėje pastaboje, ty lape, nustatykite mažiausią stebėjimų skaičių |
||||
didžiausias gylis |
Nustatykite didžiausią bet kurio galutinio medžio mazgo gylį. Šaknies mazgas apdorojamas 0 gyliu |
||||
rpart |
Traukinio modelis su valdymo parametru |
rpart () |
formulė, df, metodas, kontrolė |
Pastaba: mokykite modelį pagal treniruotės duomenis ir išbandykite našumą nematytame duomenų rinkinyje, ty bandymų rinkinyje.