De laatste tijd heeft Julia Silge een aantal videoopnamen gemaakt die laten zien hoe het tidymodels
raamwerk is te gebruiken.Het zijn opnamen over de eerste stappen in het modelleren tot hoe complexe modellen zijn te evalueren. Deze videoopname is goed voor mensen die net beginnen met tidymodels
. Ze maakt daarbij gebruik van een #TidyTuesday dataset over pinguïns. Hier gaat het om classificeren.
Hier kun je overigen haar opnmame vinden. Julia Silge on youtube
De laatste tijd heeft Julia Silge een aantal videoopnamen gemaakt die laten zien hoe het tidymodels
raamwerk is te gebruiken.Het zijn opnamen over de eerste stappen in het modelleren tot hoe complexe modellen zijn te evalueren. Deze videoopname is goed voor mensen die net beginnen met tidymodels
. Ze maakt daarbij gebruik van een #TidyTuesday dataset over pinguïns. Hier gaat het om classificeren.
Hier kun je haar opnmame vinden. Julia Silge on youtube
Eerst maar eens enkele pakketten laden en het databestand openen.
# A tibble: 344 x 8
species island bill_length_mm bill_depth_mm flipper_length_mm
<fct> <fct> <dbl> <dbl> <int>
1 Adelie Torgersen 39.1 18.7 181
2 Adelie Torgersen 39.5 17.4 186
3 Adelie Torgersen 40.3 18 195
4 Adelie Torgersen NA NA NA
5 Adelie Torgersen 36.7 19.3 193
6 Adelie Torgersen 39.3 20.6 190
7 Adelie Torgersen 38.9 17.8 181
8 Adelie Torgersen 39.2 19.6 195
9 Adelie Torgersen 34.1 18.1 193
10 Adelie Torgersen 42 20.2 190
# … with 334 more rows, and 3 more variables: body_mass_g <int>,
# sex <fct>, year <int>
Als je een classificatiemodel voor soorten pinquins probeert op te stellen, zul je waarschijnlijk een bijna perfecte pasvorm vinden, omdat dit soort waarnemingen in feite de verschillende soorten onderscheiden. sex
(geslacht) daarentegen geeft een wat rommeliger beeld, vandaar dat hier deze uitkomstvariabelen op basis van predictoren wordt voorspeld.
Het ziet er naar uit dat de vrouwelijke pinguïnflippers kleiner zijn met kleinere snavels, maar laten we ons klaarmaken voor het modelleren om meer te weten te komen! De informatie over het eiland of het jaar zullen we niet gebruiken in ons model. Die halen we eruit.
We zullen ook het tidymodels
metapakket laden en vervolgens onze gegevens splitsen in een trainings- en testingssets.
Omdat het een relatieve kleine dataset betreft (zeker de testset), maken we vervolgens hier gebruik van bootstrap-resamples van de trainingsgegevens, om onze modellen te evalueren.
# Bootstrap sampling
# A tibble: 25 x 2
splits id
<list> <chr>
1 <rsplit [250/93]> Bootstrap01
2 <rsplit [250/92]> Bootstrap02
3 <rsplit [250/90]> Bootstrap03
4 <rsplit [250/92]> Bootstrap04
5 <rsplit [250/86]> Bootstrap05
6 <rsplit [250/88]> Bootstrap06
7 <rsplit [250/96]> Bootstrap07
8 <rsplit [250/89]> Bootstrap08
9 <rsplit [250/96]> Bootstrap09
10 <rsplit [250/90]> Bootstrap10
# … with 15 more rows
Laten we eens twee verschillende modellen vergelijken, een logistisch regressiemodel en een random forest model. We beginnen met het maken van de modelspecificaties voor beide modellen.
Logistic Regression Model Specification (classification)
Computational engine: glm
Random Forest Model Specification (classification)
Computational engine: ranger
Laten we nu beginnen met het samenstellen van een tidymodels workflow()
, een object dat helpt om modelleer-pijplijnen te beheren met stukjes die in elkaar passen als Lego-blokjes. Merk op dat er nog geen model is:
══ Workflow ══════════════════════════════════════════════════════════
Preprocessor: Formula
Model: None
── Preprocessor ──────────────────────────────────────────────────────
sex ~ .
Nu kunnen we een model toevoegen, en de fit voor elk van de resamples. Eerst kunnen we het logistische regressiemodel passen.
# Resampling results
# Bootstrap sampling
# A tibble: 25 x 5
splits id .metrics .notes .predictions
<list> <chr> <list> <list> <list>
1 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [93 × …
2 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [92 × …
3 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [90 × …
4 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [92 × …
5 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [86 × …
6 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [88 × …
7 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [96 × …
8 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [89 × …
9 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [96 × …
10 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [90 × …
# … with 15 more rows
Ten tweede kunnen we het random forest model toepassen.
# Resampling results
# Bootstrap sampling
# A tibble: 25 x 5
splits id .metrics .notes .predictions
<list> <chr> <list> <list> <list>
1 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [93 × …
2 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [92 × …
3 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [90 × …
4 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [92 × …
5 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [86 × …
6 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [88 × …
7 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [96 × …
8 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [89 × …
9 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [96 × …
10 <rsplit [250/… Bootstra… <tibble [2 ×… <tibble [0 … <tibble [90 × …
# … with 15 more rows
Wij hebben elk van onze kandidaat-modellen aangepast aan onze opnieuw bemonsterde trainingsreeks!
Laten we nu eens kijken hoe we het gedaan hebben. Eerst het logistisch regressiemodel.
# A tibble: 2 x 6
.metric .estimator mean n std_err .config
<chr> <chr> <dbl> <int> <dbl> <chr>
1 accuracy binary 0.897 25 0.00631 Preprocessor1_Model1
2 roc_auc binary 0.964 25 0.00368 Preprocessor1_Model1
Goed zo! De functie collect_metrics()
extraheert en formatteert de .metrics kolom van resampling resultaten zoals hierboven voor het glm-model. Nu het random-forest model.
# A tibble: 2 x 6
.metric .estimator mean n std_err .config
<chr> <chr> <dbl> <int> <dbl> <chr>
1 accuracy binary 0.890 25 0.00595 Preprocessor1_Model1
2 roc_auc binary 0.959 25 0.00342 Preprocessor1_Model1
Dus… ook geweldig! Als ik in een situatie zit waarin een complexer model (zoals een random forest) hetzelfde presteert als een eenvoudiger model (zoals logistische regressie), dan kies ik het eenvoudiger model. Laten we eens dieper ingaan op hoe het het doet. Bijvoorbeeld, hoe voorspelt het glm-model de twee klassen?
# A tibble: 4 x 3
Prediction Truth Freq
<fct> <fct> <dbl>
1 female female 40.6
2 female male 4.48
3 male female 4.92
4 male male 41.4
Ongeveer hetzelfde, wat goed is. We kunnen ook een ROC curve maken.
Deze ROC-curve is grilliger dan andere die u wellicht hebt gezien omdat de dataset klein is.
Het is eindelijk tijd om terug te keren naar de testset. Merk op dat we de testset tijdens deze hele analyse nog niet hebben gebruikt; de testset is kostbaar en kan alleen worden gebruikt om de prestaties op nieuwe gegevens in te schatten. Laten we nog een keer passen op de trainingsgegevens en evalueren op de testgegevens met behulp van de functie last_fit()
.
# Resampling results
# Manual resampling
# A tibble: 1 x 6
splits id .metrics .notes .predictions .workflow
<list> <chr> <list> <list> <list> <list>
1 <rsplit [2… train/tes… <tibble [2… <tibble … <tibble [83 … <workflo…
De metriek en voorspellingen hier zijn op de testgegevens.
# A tibble: 2 x 4
.metric .estimator .estimate .config
<chr> <chr> <dbl> <chr>
1 accuracy binary 0.940 Preprocessor1_Model1
2 roc_auc binary 0.991 Preprocessor1_Model1
Truth
Prediction female male
female 39 3
male 2 39
De coëfficiënten (die we eruit kunnen halen met tidy()
) zijn geschat met behulp van de trainingsdata. Als we exponentiate = TRUE
gebruiken, hebben we odds ratio’s.
# A tibble: 7 x 5
term estimate std.error statistic p.value
<chr> <dbl> <dbl> <dbl> <dbl>
1 (Intercept) 3.12e-35 13.5 -5.90 0.00000000369
2 speciesChinstrap 1.34e- 3 1.70 -3.89 0.000101
3 speciesGentoo 1.08e- 4 2.89 -3.16 0.00159
4 bill_length_mm 1.78e+ 0 0.137 4.20 0.0000268
5 bill_depth_mm 3.89e+ 0 0.373 3.64 0.000273
6 flipper_length_mm 1.07e+ 0 0.0538 1.31 0.189
7 body_mass_g 1.01e+ 0 0.00108 4.70 0.00000260
Ja, de mannetjes- en vrouwtjespinguïns zijn nu veel meer gescheiden.