class: center, middle, inverse, title-slide # Fitting ### Applied Machine Learning with R
The R Bootcamp @ AMLD
### January 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"> Applied Machine Learning with R @ AMLD | January 2020 </font> </a> </span> </div> --- .pull-left45[ # Fitting <p style="padding-top:1px"></p> <ul> <li class="m1"><span>Models are actually <high>families of models</high>, with every parameter combination specifying a different model.</span></li> <li class="m2"><span>To fit a model means to <high>identify</high> from the family of models <high>the specific model that fits the data best</high>.</span></li> </ul> ] .pull-right45[ <br><br> <p align = "center"> <img src="image/curvefits.png" height=480px><br> <font style="font-size:10px">adapted from <a href="https://www.explainxkcd.com/wiki/index.php/2048:_Curve-Fitting">explainxkcd.com</a></font> </p> ] --- # Which of these models is better? Why? <img src="Fitting_files/figure-html/unnamed-chunk-2-1.png" width="90%" style="display: block; margin: auto;" /> --- # Which of these models is better? Why? <img src="Fitting_files/figure-html/unnamed-chunk-3-1.png" width="90%" style="display: block; margin: auto;" /> --- # Loss function .pull-left45[ <ul> <li class="m1"><span>Possible <high>the most important concept</high> in statistics and machine learning.</span></li> <li class="m2"><span>The loss function defines some <high>summary of the errors committed by the model</high>.</span></li> </ul> <p style="padding-top:7px"> `$$\Large Loss = f(Error)$$` <p style="padding-top:7px"> <table style="cellspacing:0; cellpadding:0; border:none;"> <tr> <td> <b>Purpose</b> </td> <td> <b>Description</b> </td> </tr> <tr> <td bgcolor="white"> Fitting </td> <td bgcolor="white"> Find parameters that minimize loss function. </td> </tr> <tr> <td> Evaluation </td> <td> Calculate loss function for fitted model. </td> </tr> </table> ] .pull-right45[ <img src="Fitting_files/figure-html/unnamed-chunk-4-1.png" width="90%" style="display: block; margin: auto;" /> ] --- class: center, middle <high><h1>Regression</h1></high> <font color = "gray"><h1>Decision Trees</h1></font> <font color = "gray"><h1>Random Forests</h1></font> --- # Regression .pull-left45[ In [regression](https://en.wikipedia.org/wiki/Regression_analysis), the criterion `\(Y\)` is modeled as the <high>sum</high> of <high>features</high> `\(X_1, X_2, ...\)` <high>times weights</high> `\(\beta_1, \beta_2, ...\)` plus `\(\beta_0\)` the so-called the intercept. <p style="padding-top:10px"></p> `$$\large \hat{Y} = \beta_{0} + \beta_{1} \times X_1 + \beta_{2} \times X2 + ...$$` <p style="padding-top:10px"></p> The weight `\(\beta_{i}\)` indiciates the <high>amount of change</high> in `\(\hat{Y}\)` for a change of 1 in `\(X_{i}\)`. Ceteris paribus, the <high>more extreme</high> `\(\beta_{i}\)`, the <high>more important</high> `\(X_{i}\)` for the prediction of `\(Y\)` <font style="font-size:12px">(Note: the scale of `\(X_{i}\)` matters too!).</font> If `\(\beta_{i} = 0\)`, then `\(X_{i}\)` <high>does not help</high> predicting `\(Y\)` ] .pull-right45[ <img src="Fitting_files/figure-html/unnamed-chunk-5-1.png" width="90%" style="display: block; margin: auto;" /> ] --- # Regression loss .pull-left45[ <p> <ul style="margin-bottom:-20px"> <li class="m1"><span><b>Mean Squared Error (MSE)</b> <br><br> <ul class="level"> <li><span>Average <high>squared distance</high> between predictions and true values.</span></li> </ul> </span></li> </ul> `$$MSE = \frac{1}{n}\sum_{i \in 1,...,n}(Y_{i} - \hat{Y}_{i})^{2}$$` <ul> <li class="m2"><span><b>Mean Absolute Error (MAE)</b> <br><br> <ul class="level"> <li><span>Average <high>absolute distance</high> between predictions and true values.</span></li> </ul> </span></li> </ul> $$ MAE = \frac{1}{n}\sum_{i \in 1,...,n} \lvert Y_{i} - \hat{Y}_{i} \rvert$$ </p> ] .pull-right45[ <img src="Fitting_files/figure-html/unnamed-chunk-6-1.png" width="90%" style="display: block; margin: auto;" /> ] --- .pull-left45[ # Fitting <p style="margin-top:20px"> <ul style="margin-bottom:-20px"> <li class="m1"><span><b>Analytically</b> <br><br> <ul class="level"> <li><span>In rare cases, the parameters can be <high>directly calculated</high>, e.g., using the <i>normal equation</i>.</span></li> </ul> </span></li> </ul> `$$\boldsymbol \beta = (\boldsymbol X^T\boldsymbol X)^{-1}\boldsymbol X^T\boldsymbol y$$` <ul> <li class="m2"><span><b>Numerically</b> <br><br> <ul class="level"> <li><span>In most cases, parameters need to be found using a <high>directed trial and error</high>, e.g., <i>gradient descent</i>.</span></li> </ul> </span></li> </ul> `$$\boldsymbol \beta_{n+1} = \boldsymbol \beta_{n}+\gamma \nabla F(\boldsymbol \beta_{n})$$` </p> ] .pull-right45[ <br><br> <p align = "center"> <img src="image/gradient.png" height=420px><br> <font style="font-size:10px">adapted from <a href="https://me.me/i/machine-learning-gradient-descent-machine-learning-machine-learning-behind-the-ea8fe9fc64054eda89232d7ffc9ba60e">me.me</a></font> </p> ] --- .pull-left45[ # Fitting <p style="margin-top:10px"> <ul style="margin-bottom:-20px"> <li class="m1"><span><b>Analytically</b> <br><br> <ul class="level"> <li><span>In rare cases, the parameters can be <high>directly calculated</high>, e.g., using the <i>normal equation</i>.</span></li> </ul> </span></li> </ul> `$$\boldsymbol \beta = (\boldsymbol X^T\boldsymbol X)^{-1}\boldsymbol X^T\boldsymbol y$$` <ul> <li class="m2"><span><b>Numerically</b> <br><br> <ul class="level"> <li><span>In most cases, parameters need to be found using a <high>directed trial and error</high>, e.g., <i>gradient descent</i>.</span></li> </ul> </span></li> </ul> `$$\boldsymbol \beta_{n+1} = \boldsymbol \beta_{n}+\gamma \nabla F(\boldsymbol \beta_{n})$$` </p> ] .pull-right45[ <br><br2> <p align = "center"> <img src="image/gradient1.gif" height=250px><br> <font style="font-size:10px">adapted from <a href="https://dunglai.github.io/2017/12/21/gradient-descent/ ">dunglai.github.io</a></font><br> <img src="image/gradient2.gif" height=250px><br> <font style="font-size:10px">adapted from <a href="https://dunglai.github.io/2017/12/21/gradient-descent/ ">dunglai.github.io</a></font> </p> ] --- # 2 types of supervised problems .pull-left45[ <ul style="margin-bottom:-20px"> <li class="m1"><span><b>Regression</b> <br><br> <ul class="level"> <li><span>Regression problems involve the <high>prediction of a quantitative feature</high>.</span></li> <li><span>E.g., predicting the cholesterol level as a function of age</high>.</span></li> </ul> </span></li><br> <li class="m2"><span><b>Classification</b> <br><br> <ul class="level"> <li><span>Classification problems involve the <high>prediction of a categorical feature</high>.</span></li> <li><span>E.g., predicting the type of chest pain as a function of age</high>.</span></li> </ul> </span></li> </ul> ] .pull-right4[ <p align = "center"> <img src="image/twotypes.png" height=440px><br> </p> ] --- # Logistic regression .pull-left45[ <ul style="margin-bottom:-20px"> <li class="m1"><span>In <a href="https://en.wikipedia.org/wiki/Logistic_regression">logistic regression</a>, the class criterion <font style="font-size:22px"><mono>Y ∈ (0,1)</mono></font> is modeled also as the <high>sum of feature times weights</high>, but with the prediction being transformed using a <high>logistic link function</high>.</span></li> </ul> <p style="padding-top:10px"></p> `$$\large \hat{Y} = Logistic(\beta_{0} + \beta_{1} \times X_1 + ...)$$` <p style="padding-top:10px"></p> <ul style="margin-bottom:-20px"> <li class="m2"><span>The logistic function <high>maps predictions to the range of 0 and 1</high>, the two class values..</span></li> </ul> <p style="padding-top:10px"></p> $$ Logistic(x) = \frac{1}{1+exp(-x)}$$ ] .pull-right45[ <img src="Fitting_files/figure-html/unnamed-chunk-7-1.png" width="90%" style="display: block; margin: auto;" /> ] --- # Logistic regression .pull-left45[ <ul style="margin-bottom:-20px"> <li class="m1"><span>In <a href="https://en.wikipedia.org/wiki/Logistic_regression">logistic regression</a>, the class criterion <font style="font-size:22px"><mono>Y ∈ (0,1)</mono></font> is modeled also as the <high>sum of feature times weights</high>, but with the prediction being transformed using a <high>logistic link function</high>.</span></li> </ul> <p style="padding-top:10px"></p> `$$\large \hat{Y} = Logistic(\beta_{0} + \beta_{1} \times X_1 + ...)$$` <p style="padding-top:10px"></p> <ul style="margin-bottom:-20px"> <li class="m2"><span>The logistic function <high>maps predictions to the range of 0 and 1</high>, the two class values..</span></li> </ul> <p style="padding-top:10px"></p> $$ Logistic(x) = \frac{1}{1+exp(-x)}$$ ] .pull-right45[ <img src="Fitting_files/figure-html/unnamed-chunk-8-1.png" width="90%" style="display: block; margin: auto;" /> ] --- # Classification loss .pull-left45[ <ul style="margin-bottom:-20px"> <li class="m1"><span><b>Distance</b> <br><br> <ul class="level"> <li><span>Logloss is <high>used to fit the parameters</high>, alternative distance measures are MSE and MAE.</span></li> </ul> </span></li> </ul> `$$\small LogLoss = -\frac{1}{n}\sum_{i}^{n}(log(\hat{y})y+log(1-\hat{y})(1-y))$$` `$$\small MSE = \frac{1}{n}\sum_{i}^{n}(y-\hat{y})^2, \: MAE = \frac{1}{n}\sum_{i}^{n} \lvert y-\hat{y} \rvert$$` <ul> <li class="m2"><span><b>Overlap</b> <br><br> <ul class="level"> <li><span>Does the <high>predicted class match the actual class</high>. Often preferred for <high>ease of interpretation</high>..</span></li> </ul> </span></li> </ul> `$$\small Loss_{01}=\frac{1}{n}\sum_i^n I(y \neq \lfloor \hat{y} \rceil)$$` ] .pull-right45[ <img src="Fitting_files/figure-html/unnamed-chunk-9-1.png" width="90%" style="display: block; margin: auto;" /> ] --- # Confusion matrix .pull-left45[ <ul style="margin-bottom:-20px"> <li class="m1"><span>The confusion matrix <high>tabulates prediction matches and mismatches</high> as a function of the true class.</span></li> <li class="m2"><span>The confusion matrix permits specification of a number of <high>helpful performance metrics</high>.</span></li> </ul> <br> <b> Confusion matrix </b> <font style="font-size:22px"> <br> <table style="cellspacing:0; cellpadding:0; border:none;"> <col width=20%> <col width=40%> <col width=40%> <tr> <td> </td> <td> <eq><b>y = 1</b></eq> </td> <td> <eq><b>y = 0</b></eq> </td> </tr> <tr> <td bgcolor="white"> <eq><b>ŷ = 1</b></eq> </td> <td bgcolor="white"> <font color="#6ABA9A"> True positive (TP)</font> </td> <td bgcolor="white"> <font color="#EA4B68"> False positive (FP)</font> </td> </tr> <tr> <td> <eq><b>ŷ = 0</b></eq> </td> <td> <font color="#EA4B68"> False negative (FN)</font> </td> <td> <font color="#6ABA9A"> True negative (TN)</font> </td> </tr> </table> </font> ] .pull-right45[ <b>Accuracy</b>: Of all cases</i>, what percent of predictions are correct? `$$\small Acc. = \frac{TP + TN}{ TP + TN + FN + FP} = 1-Loss_{01}$$` <p style="padding-top:10px"></p> <b>Sensitivity</b>: Of the truly Positive cases</i>, what percent of predictions are correct? `$$\small Sensitivity = \frac{TP}{ TP +FN }$$` <b>Specificity</b>: Of the truly Negative cases</i>, what percent of predictions are correct? <p style="padding-top:10px"></p> `$$\small Specificity = \frac{TN}{ TN + FP }$$` ] --- # Confusion matrix .pull-left45[ <ul style="margin-bottom:-20px"> <li class="m1"><span>The confusion matrix <high>tabulates prediction matches and mismatches</high> as a function of the true class.</span></li> <li class="m2"><span>The confusion matrix permits specification of a number of <high>helpful performance metrics</high>.</span></li> </ul> <br> <b> Confusion matrix </b> <font style="font-size:22px"> <br> <table style="cellspacing:0; cellpadding:0; border:none;"> <col width=20%> <col width=40%> <col width=40%> <tr> <td> </td> <td> <eq><b>Default</b></eq> </td> <td> <eq><b>Repay</b></eq> </td> </tr> <tr> <td bgcolor="white"> <eq><b>"Default"</b></eq> </td> <td bgcolor="white"> <font color="#6ABA9A"> TP = 3</font> </td> <td bgcolor="white"> <font color="#EA4B68"> FP = 1</font> </td> </tr> <tr> <td> <eq><b>"Repay"</b></eq> </td> <td> <font color="#EA4B68"> FN = 1</font> </td> <td> <font color="#6ABA9A"> TN = 2</font> </td> </tr> </table> </font> ] .pull-right45[ <b>Accuracy</b>: Of all cases</i>, what percent of predictions are correct? `$$\small Acc. = \frac{TP + TN}{ TP + TN + FN + FP} = 1-Loss_{01}$$` <p style="padding-top:10px"></p> <b>Sensitivity</b>: Of the truly Positive cases</i>, what percent of predictions are correct? `$$\small Sensitivity = \frac{TP}{ TP +FN }$$` <b>Specificity</b>: Of the truly Negative cases</i>, what percent of predictions are correct? <p style="padding-top:10px"></p> `$$\small Specificity = \frac{TN}{ TN + FP }$$` ] --- class: center, middle <br><br> # Fitting regression models with `caret` <img src="https://3qeqpr26caki16dnhd19sv6by6v-wpengine.netdna-ssl.com/wp-content/uploads/2014/09/Caret-package-in-R.png" width="70%" style="display: block; margin: auto;" /> --- # `caret`s fitting functions .pull-left45[ <table style="cellspacing:0; cellpadding:0; border:none;"> <tr> <td> <b>Function</b> </td> <td> <b>Description</b> </td> </tr> <tr> <td bgcolor="white"> <mono>trainControl()</mono> </td> <td bgcolor="white"> Choose <high>settings</high> for how fitting should be carried out. </td> </tr> <tr> <td> <mono>train()</mono> </td> <td> Specify the model and <high>find 'best' parameters</high>. </td> </tr> <tr> <td bgcolor="white"> <mono>postResample()</mono> </td> <td bgcolor="white"> <high>Evaluate</high> model performance (fitting or prediction) for regression. </td> </tr> <tr> <td> <mono>confusionMatrix()</mono> </td> <td bgcolor="white"> <high>Evaluate</high> model performance (fitting or prediction) for classification. </td> </tr> </table> ] .pull-right45[ ```r # Step 1: Define control parameters # trainControl() ctrl <- trainControl(...) # Step 2: Train and explore model # train() mod <- train(...) summary(mod) mod$finalModel # see final model # Step 3: Assess fit # predict(), postResample(), fon fit <- predict(mod) postResample(fit, truth) confusionMatrix(fit, truth) ``` <!-- Caret documentation: [http://topepo.github.io/caret/](http://topepo.github.io/caret/) --> <!-- <iframe src="http://topepo.github.io/caret/" height="480px" width = "500px"></iframe> --> ] --- # `trainControl()` .pull-left45[ <ul> <li class="m1"><span><mono>trainControl()</mono> controls <high>how <mono>caret</mono> fits an ML model</high>.</span></li> <li class="m2"><span>For now, we set <mono>method = "none"</mono> to keep things simple. More in the session on <b>optimization</b>.</span></li> </ul> <br> ```r # Fit the model without any # advanced parameter tuning methods ctrl <- trainControl(method = "none") # show help file ?trainControl ``` ] .pull-right45[ <img src="image/traincontrol_help.jpg" width="100%" style="display: block; margin: auto;" /> ] --- # `train()` .pull-left4[ <ul> <li class="m1"><span><mono>train()</mono> is the <high>fitting workhorse</high> of <mono>caret</mono>, offering you <high>200+ models</high> by merely changing the <high>method</high> argument!.</span></li> </ul> <br> <table style="cellspacing:0; cellpadding:0; border:none;"> <tr> <td> <b>Argument</b> </td> <td> <b>Description</b> </td> </tr> <tr> <td bgcolor="white"> <mono>form</mono> </td> <td bgcolor="white"> Formula specifying features and criterion. </td> </tr> <tr> <td> <mono>data</mono> </td> <td> Training data. </td> </tr> <tr> <td bgcolor="white"> <mono>method</mono> </td> <td bgcolor="white"> The model (algorithm). </td> </tr> <tr> <td> <mono>trControl</mono> </td> <td bgcolor="white"> Control parameters for fitting. </td> </tr> <tr> <td bgcolor="white"> <mono>tuneGrid</mono>, <mono>preProcess</mono> </td> <td bgcolor="white"> Cool stuff for later. </td> </tr> </table> ] .pull-right5[ ```r # Fit a regression model predicting Price income_mod <- train(form = income ~ ., # Formula data = baselers, # Training data method = "glm", # Regression trControl = ctrl) # Control Param's income_mod ``` ``` Generalized Linear Model 1000 samples 19 predictor No pre-processing Resampling: None ``` ] --- # `train()` .pull-left4[ <ul> <li class="m1"><span><mono>train()</mono> is the <high>fitting workhorse</high> of <mono>caret</mono>, offering you <high>200+ models</high> by merely changing the <high>method</high> argument!.</span></li> </ul> <br> <table style="cellspacing:0; cellpadding:0; border:none;"> <tr> <td> <b>Argument</b> </td> <td> <b>Description</b> </td> </tr> <tr> <td bgcolor="white"> <mono>form</mono> </td> <td bgcolor="white"> Formula specifying features and criterion. </td> </tr> <tr> <td> <mono>data</mono> </td> <td> Training data. </td> </tr> <tr> <td bgcolor="white"> <mono>method</mono> </td> <td bgcolor="white"> The model (algorithm). </td> </tr> <tr> <td> <mono>trControl</mono> </td> <td bgcolor="white"> Control parameters for fitting. </td> </tr> <tr> <td bgcolor="white"> <mono>tuneGrid</mono>, <mono>preProcess</mono> </td> <td bgcolor="white"> Cool stuff for later. </td> </tr> </table> ] .pull-right5[ ```r # Fit a random forest predicting Price income_mod <- train(form = income ~ .,# Formula data = baselers, # Training data method = "rf", # Random Forest trControl = ctrl) # Control Param's income_mod ``` ``` Random Forest 1000 samples 19 predictor No pre-processing Resampling: None ``` ] --- .pull-left4[ # `train()` <ul> <li class="m1"><span><mono>train()</mono> is the <high>fitting workhorse</high> of <mono>caret</mono>, offering you <high>200+ models</high> by merely changing the <high>method</high> argument!.</span></li> <li class="m2"><span>Find all 200+ models <a href="http://topepo.github.io/caret/available-models.html">here</a>.</span></li> </ul> ] .pull-right5[ <br><br> <iframe width="600" height="480" src="https://topepo.github.io/caret/available-models.html" frameborder="0"></iframe> ] --- # `train()` .pull-left4[ <ul style="margin-bottom:-20px"> <li class="m1"><span>The criterion must be the right type: <br><br> <ul class="level"> <li><span><high><mono>numeric</mono></high> criterion → <high>Regression</high><br></span></li> <li><span><high><mono>factor</mono></high> criterion → <high>Classification</high><br></span></li> </ul> </span></li> </ul> <br> ``` # A tibble: 5 x 5 Default Age Gender Cards Education <dbl> <dbl> <chr> <dbl> <dbl> 1 0 45 M 3 11 2 1 36 F 2 14 3 0 76 F 5 12 4 1 25 M 2 17 5 1 36 F 3 12 ``` ] .pull-right5[ ```r # Will be a regression task loan_mod <- train(form = Default ~ ., data = Loans, method = "glm", trControl = ctrl) # Will be a classification task load_mod <- train(form = factor(Default) ~ ., data = Loans, method = "glm", trControl = ctrl) ``` ] --- # <mono>mod$finalModel</mono> .pull-left4[ <ul> <li class="m1"><span>The <mono>train()</mono> function returns a <mono>list</mono> with an object called <mono>finalModel</mono> - this is your <high>fitted machine learning model</high>!</span></li> <li class="m2"><span><high>Access</high> the model with <mono>mod$finalModel<mono> and <high>explore</high> the object with generic functions.</span></li> </ul> <br> <table style="cellspacing:0; cellpadding:0; border:none;"> <tr> <td> <b>Function</b> </td> <td> <b>Description</b> </td> </tr> <tr> <td bgcolor="white"> <mono>summary()</mono> </td> <td bgcolor="white"> <high>Overview</high> of the most important results. </td> </tr> <tr> <td bgcolor="white"> <mono>names()</mono> </td> <td bgcolor="white"> See all <high>named elements</high> you can access with $. </td> </tr> </table> ] .pull-right5[ ```r # Create a regression object income_mod <- train(form = income ~ age + height, data = baselers) # Training data # Look at all named outputs names(income_mod$finalModel) ``` ``` [1] "coefficients" "residuals" "fitted.values" [4] "effects" "R" "rank" [ reached getOption("max.print") -- omitted 28 entries ] ``` ```r # Access specific outputs income_mod$finalModel$coefficients ``` ``` (Intercept) age height 177.084 151.786 3.466 ``` ] --- # `predict()` .pull-left45[ <ul> <li class="m1"><span>The <mono>predict()</mono> function <high>produces predictions</high> from a model. Simply put model object as the first argument.</span></li> </ul> <br> ```r # Get fitted values glm_fits <- predict(object = income_mod) glm_fits[1:8] ``` ``` 1 2 3 4 5 6 7 8 5508 6960 6982 8645 5325 10648 8663 4592 ``` ] .pull-right45[ <img src="Fitting_files/figure-html/unnamed-chunk-25-1.png" width="90%" style="display: block; margin: auto;" /> ] --- # `postResample()` .pull-left45[ <ul> <li class="m1"><span>The <nono>postResample()</nono> function <high>gives a simple summary</high> of a models' performance in a <high>regression task</high>. Simply put the predicted values and the true values inside the function.</span></li> </ul> <br> ```r # evaluate postResample(glm_fits, baselers$income) ``` ``` RMSE Rsquared MAE 1173.079 0.821 937.113 ``` ] .pull-right45[ <img src="Fitting_files/figure-html/unnamed-chunk-27-1.png" width="90%" style="display: block; margin: auto;" /> ] --- .pull-left5[ <p style="padding-top:10px"></p> ## `confusionMatrix()` <p style="padding-top:10px"></p> <ul> <li class="m1"><span>The <nono>confusionMatrix()</nono> does the same for a models' performance in a <high>classification task</high>. Simply put the predicted values and the true values inside the function..</span></li> </ul> ```r # eyecor to factor baselers$eyecor <- factor(baselers$eyecor) # run glm model for classification eyecor_mod <- train(form = eyecor ~ age + height, data = baselers, method = "glm", trControl = ctrl) # evaluate confusionMatrix(predict(eyecor_mod), baselers$eyecor) ``` ] .pull-right4[ <br> ``` Confusion Matrix and Statistics Reference Prediction no yes no 0 0 yes 353 647 Accuracy : 0.647 95% CI : (0.616, 0.677) No Information Rate : 0.647 P-Value [Acc > NIR] : 0.514 Kappa : 0 Mcnemar's Test P-Value : <2e-16 Sensitivity : 0.000 Specificity : 1.000 Pos Pred Value : NaN Neg Pred Value : 0.647 Prevalence : 0.353 Detection Rate : 0.000 Detection Prevalence : 0.000 Balanced Accuracy : 0.500 'Positive' Class : no ``` ] --- class: middle, center <h1><a href=https://therbootcamp.github.io/AML_2020AMLD/_sessions/Fitting/Fitting_practical.html>Practical</a></h1>