class: center, middle, inverse, title-slide # Prediction ### Machine Learning with R
The R Bootcamp @ DHLab
### November 2020 --- layout: true <div class="my-footer"> <span style="text-align:center"> <span> <img src="https://raw.githubusercontent.com/therbootcamp/therbootcamp.github.io/master/_sessions/_image/by-sa.png" height=14 style="vertical-align: middle"/> </span> <a href="https://therbootcamp.github.io/"> <span style="padding-left:82px"> <font color="#7E7E7E"> www.therbootcamp.com </font> </span> </a> <a href="https://therbootcamp.github.io/"> <font color="#7E7E7E"> Machine Learning with R | November 2020 </font> </a> </span> </div> --- # Prediction is... .pull-left45[ <p> <font style="font-size:32px"><i>Prediction is very difficult, especially if it's about the future.</i></font> <br><br> Nils Bohr, Nobel Laureate in Physics <br><br> <font style="font-size:32px"><i>An economist is an expert who will know tomorrow why the things he predicted yesterday didn't happen today.</i></font> <br><br> Evan Esar, Humorist </p> ] .pull-right45[ <p align = "center"> <img src="image/bohr.jpg"><br> <font style="font-size:10px">from <a href="https://futurism.com/know-your-scientist-niels-bohr-the-father-of-the-atom">futurism.com</a></font> </p> ] --- # Hold-out data .pull-left45[ <ul> <li class="m1"><span>Model performance must be evaluated as true prediction on an <high>unseen data set</high>.</span></li><br> <li class="m2"><span>The unseen data set can be <high>naturally</high> occurring.</span></li> <ul class="level"> <li><span>e.g. using 2019 stock prizes to evaluate a model fit using 2018 stock prizes</span></li> </ul><br> <li class="m3"><span>More commonly unseen data is created by <high>splitting the available data</high> into a training set and a test set..</span></li> </ul> ] .pull-right45[ <p align = "center"> <img src="image/testdata.png" height=430px> </p> ] --- # Training <p align = "center" style="padding-top:30px;padding-left:40px"> <img src="image/training_flow.png" height=400px> </p> --- # Test <p align = "center" style="padding-top:30px;padding-left:40px"> <img src="image/testing_flow.png" height=400px> </p> --- .pull-left4[ <br><br> # Overfitting <ul> <li class="m1"><span>Occurs when a model <high>fits data too closely</high> and therefore fails to reliably predict future observations.</span></li><br> <li class="m2"><span>Overfitting occurs when a model 'mistakes' random <high>noise</high> for a predictable <high>signal</high>.</span></li><br> <li class="m3"><span>More <high>complex models</high> are more prone to overfitting.</span></li> </ul> ] .pull-right5[ <br><br><br> <p align = "center" style="padding-top:0px"> <img src="image/overfitting.png"> </p> ] --- # Overfitting <img src="Prediction_files/figure-html/unnamed-chunk-2-1.png" style="display: block; margin: auto;" /> --- class: center, middle <font color = "gray"><h1>Regression</h1></font> <high><h1>Decision Trees</h1></high> <font color = "gray"><h1>Random Forests</h1></font> --- # CART .pull-left45[ <ul> <li class="m1"><span>CART is short for <high>Classification and Regression Trees</high>, which are often simply called Decision trees.</span></li><br> <li class="m2"><span>Models criterion is modeled as a sequence of <high>logical TRUE or FALSE questions</high>.</span></li> </ul> ] .pull-right45[ <p align = "center" style="padding-top:0px"> <img src="image/tree.png"> </p> ] --- # Classificiation trees .pull-left45[ <ul> <li class="m1"><span>Classification trees (and regression trees) are created using a relatively simple <high>three-step algorithm</high>:</span></li><br> <ul> <li><span>1 - <high>Split</high> nodes to maximize <b>purity gain</b> (e.g., Gini gain).</span></li><br> <li><span>2 - <high>Repeat</high> until splits are no longer possible.</span></li><br> <li><span>3 - <high>Prune</high> tree to reasonable size.</mono></span></li> </ul> </ul> ] .pull-right45[ <p align = "center" style="padding-top:0px"> <img src="image/tree.png"> </p> ] --- # Node splitting .pull-left45[ <ul> <li class="m1"><span>Classification trees attempt to <high>minize node impurity</high> using, e.g., the <high>Gini coefficient</high>.</span></li> </ul> `$$\large Gini(S) = 1 - \sum_j^kp_j^2$$` <ul> <li class="m2"><span>Nodes are <high>split</high> using the variable and split value that <high>maximizes Gini gain</high>.</span></li> </ul> `$$Gini \; gain = Gini(S) - Gini(A,S)$$` with `$$Gini(A, S) = \sum \frac{n_i}{n}Gini(S_i)$$` ] .pull-right45[ <p align = "center" style="padding-top:0px"> <img src="image/splitting.png"> </p> ] --- # Pruning trees .pull-left45[ <ul> <li class="m1"><span>CClassification trees are <high>pruned</high> back such that every split has a purity gain of at least <high><mono>cp</mono></high>.</span></li> </ul> <br> $$ \large `\begin{split} Loss = & Impurity\,+\\ &cp*(n\:terminal\:nodes)\\ \end{split}` $$ ] .pull-right45[ <p align = "center" style="padding-top:0px"> <img src="image/splitting.png"> </p> ] --- # Regression trees .pull-left45[ <ul> <li class="m1"><span>Trees can also be used to perform regression tasks. Instead of impurity, regression trees attempt to <high>minimize within-node variance</high> (or maximize node homogeneity):</span></li> </ul> `$$\large SSE = \sum_{i \in S_1}(y_i - \bar{y}_1)^2+\sum_{i \in S_2}(y_i - \bar{y}_2)^2$$` <ul> <li class="m2"><span>Algorithm:</span></li> <ul> <li><span>1 - <high>Split</high> nodes to maximize <b>homogeneity gain</b>.</li></span><br> <li><span>2 - <high>Repeat</high> until splits are no longe possible.</span></li><br> <li><span>3 - <high>Prune</high> tree to reasonable size.</span></li> <ul> </ul> ] .pull-right45[ <p align = "center" style="padding-top:0px"> <img src="image/splitting_regr.png"> </p> ] --- # CART in <mono>caret</mono> .pull-left4[ <ul> <li class="m1"><span>Fit <high>decision trees</high> in <mono>caret</mono> using <mono>method = "rpart"</mono>.</span></li> <li class="m2"><span><mono>caret</mono> will <high>choose automatically</high> whether to use classification or regression trees depending on whether the criterion is a <mono>factor</mono> or not.</span></li> </ul> ] .pull-right45[ ```r # Fit a decision tree predicting default train(form = default ~ ., # factor data = Loans, method = "rpart", # Decision Tree trControl = ctrl) # Fit a decision tree predicting income train(form = income ~ ., # continuous data = basel, method = "rpart", # Decision Tree trControl = ctrl) ``` ] --- class: center, middle <font color = "gray"><h1>Regression</h1></font> <font color = "gray"><h1>Decision Trees</h1></font> <high><h1>Random Forests</h1></high> --- .pull-left45[ # Random Forest <ul> <li class="m1"><span>In Random Forests the criterion is modeled as the <high>aggregate prediction of <high>many decision trees</high> each based on different features.</span></li><br> <li class="m2"><span>Algorithmus:</span></li> <ul> <li><span>1 - <high>Repeat</high> <mono>n</mono> times.</li></span><br> <ul> <li><span>1 - <high>Resample</high> data.</span></li><br> <li><span>2 - Each split <high>consider <i>m</i> features</high>.</span></li><br> </ul> <li><span>2 - <high>Average</high> predictions.</li></span><br> </ul> </ul> ] .pull-right45[ <br> <p align = "center" style="padding-top:0px"> <img src="image/rf.png"> </p> ] --- # Random Forest .pull-left45[ <p style="padding-top:1px"></p> <ul> <li class="m1"><span>Random forests make use of <high>bagging</high>, which consists of <high>resampling</high> and <high>averaging</high>.</span></li> </ul> <table style="cellspacing:0; cellpadding:0; border:none;"> <col width="30%"> <col width="70%"> <tr> <td bgcolor="white"> <b>Element</b> </td> <td bgcolor="white"> <b>Description</b> </td> </tr> <tr> <td bgcolor="white"> <i>Resampling</i> </td> <td bgcolor="white"> Creates new data sets that vary in their composition thereby <high>deemphasizing idiosyncracies</high> of the available data. </td> </tr> <tr> <td bgcolor="white"> <i>Averaging</i> </td> <td bgcolor="white"> Combining predictions typically <high>evens out idiosyncracies</high> of the models created from single data sets. </td> </tr> </table> ] .pull-right45[ <p align = "center" style="padding-top:0px"> <img src="image/tree_crowd.png"> </p> ] --- # Random forests in <mono>caret</mono> .pull-left4[ <ul> <li class="m1"><span>Fit a Random Forest in <mono>caret</mono> with <highm>method = "rf"</highm>.</span></li> <li class="m2"><span><mono>caret</mono> will <high>choose automatically</high> whether to use classification or regression trees for the Random Forest depending on whether the criterion is a <mono>factor</mono> or not.</span></li> </ul> ] .pull-right45[ ```r # Fit a decision tree predicting default train(form = default ~ ., data = Loans, method = "rf", # Decision Tree trControl = ctrl) # Fit a decision tree predicting income train(form = income ~ ., data = basel, method = "rf", # Decision Tree trControl = ctrl) ``` ] --- class: center, middle <h1><a>Evaluating model predictions with <mono>caret</mono></h1> <!--- # <mono>createDataPartition()</mono> .pull-left4[ Use `createDataPartition()` to <high>split a dataset</high> into separate training and test datasets. <table style="cellspacing:0; cellpadding:0; border:none;"> <col width="30%"> <col width="70%"> <tr> <td bgcolor="white"> <b>Argument</b> </td> <td bgcolor="white"> <b>Description</b> </td> </tr> <tr> <td bgcolor="white"> <mono>y</mono> </td> <td bgcolor="white"> The criterion. Used to create a <high>balanced split</high>. </td> </tr> <tr> <td bgcolor="white"> <mono>p</mono> </td> <td bgcolor="white"> The <high>proportion of data</high> going into the training set. Often <mono>.8</mono> or <mono>.5</mono>. </td> </tr> </table> ] .pull-right5[ ```r # Set the randomisation seed to get the # same results each time set.seed(100) # Get indices for training index <- createDataPartition(y = basel$income, p = .8, list = FALSE) # Create training data basel_train <- basel %>% slice(index) # Create test data basel_test <- basel %>% slice(-index) ``` ] ---> --- # <mono>predict(, newdata)</mono> .pull-left4[ <ul> <li class="m1"><span>To <high>test model predictions</high>, you nee to compute a vector of predictions from a the test data (<mono>newdata</mono> using the <mono>predict()</mono> function:</span></li> </ul> <table style="cellspacing:0; cellpadding:0; border:none;"> <col width="30%"> <col width="70%"> <tr> <td bgcolor="white"> <b>Argument</b> </td> <td bgcolor="white"> <b>Description</b> </td> </tr> <tr> <td bgcolor="white"> <mono>object</mono> </td> <td bgcolor="white"> <mono>caret</mono> fit object. </td> </tr> <tr> <td bgcolor="white"> <mono>newdata</mono> </td> <td bgcolor="white"> Test data sest. Must contain same features as provided in <mono>object</mono>. </td> </tr> </table> ] .pull-right5[ ```r # Fit model to training data mod <- train(form = income ~ ., method = "glm", data = basel_train) # Get fitted values (for training data) mod_fit <- predict(mod) # Predictions for NEW data_test data! mod_pred <- predict(mod, newdata = basel_test) # Evaluate prediction results postResample(pred = mod_pred, obs = basel_test$income) ``` ] --- class: middle, center <h1><a href=https://therbootcamp.github.io/ML-DHLab/_sessions/Prediction/Prediction_practical.html>Practical</a></h1>