Classificeren van Palmer penguins

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.

Julia Silge, bewerking Harrie Jonkman true
07-18-2021

Palmer penguins classificatie

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.

Een modelopbouwen

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!

Het model evalueren.

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.