# Training models

    library(LSTbook)

To “train a model” involves three components:

1. A data frame with training data
2. A model specification naming the response variable and the explanatory variables. This is formatted in the same tilde-expression manner as for `lm()` and `glm()`.
3. A model-fitting function that puts (1) and (2) together into a model object. Examples of model-fitting functions are `lm()` and `glm()`. In Lessons in Statistical Thinking and the corresponding `{LSTbook}` package, we almost always use `model_train()`

Once the model object has been constructed, you can plot the model, create summaries such as regression reports or ANOVA reports, and evaluate the model for new inputs, etc.

## Using `model_train()`

`model_train()` is a wrapper around some commonly used model-fitting functions from the `{stats}` package, particularly `lm()` and `glm()`. It’s worth explaining motivation for introducing a new model-fitting function.

1. `model_train()` is pipeline ready. Example: `Galton |> model_train(height ~ mother)`
2. `model_train()` has internal logic to figure out automatically which type of model (e.g. linear, binomial, poisson) to fit. (You can also specify this with the `family=` argument.) The automatic nature of `model_train()` means, e.g., you can use it with neophyte students for logistic regression without having to introduce a new function.
3. `model_train()` saves a copy of the training data as an attribute of the model object being produced. This is helpful in plotting the model, cross-validation, etc., particularly when the model specification involves nonlinear explanatory terms (e.g., `splines::ns(mother, 3)`)

## Using a model object

As examples, consider these two models:

- modeling `height` of a (fully grown) child with the `sex` of the child, and the `mother`’s and `father`’s height. Linear regression is an appropriate technique here.

    height_model <- mosaicData::Galton |> model_train(height ~ sex + mother + father)

- modeling the probability that a voter will vote in an election (`primary2006`) given the household size (`hhsize`), `yearofbirth` and whether the voter voted in a previous primary election (`primary2004`). Since having voted is a yes or no proposition, logistic regression is an appropriate technique.

    vote_model <-
      Go_vote |>
      model_train(zero_one(primary2006, one = "voted") ~ yearofbirth * primary2004 * hhsize * yearofbirth )

Note that the `zero_one()` marks the response variable as a candidate for logistic regression.

The output of `model_train()` is in the format of whichever `{stats}` package function has been used, e.g. `lm()` or `glm()`. (The training data is stored as an “attribute,” meaning that it is invisible.) Consequently, you can use the model object as an input to whatever model-plotting or summarizing function you like.

In Lessons in Statistical Thinking we use `{LSTbook}` functions for plotting and summarizing:

- `model_plot()`
- `R2()`
- `conf_interval()`
- Late in Lessons, `regression_summary()` and `anova_summary()`

Let’s apply some of these to the modeling examples introduced above.

    height_model |> model_plot()

    height_model |> conf_interval()
    #> # A tibble: 4 × 4
    #>   term         .lwr  .coef   .upr
    #>   <chr>       <dbl>  <dbl>  <dbl>
    #> 1 (Intercept) 9.95  15.3   20.7
    #> 2 sexM        4.94   5.23   5.51
    #> 3 mother      0.260  0.321  0.383
    #> 4 father      0.349  0.406  0.463
    vote_model |> model_plot()

    vote_model |> R2()
    #>        n k   Rsquared       F      adjR2 p df.num df.denom
    #> 1 305866 7 0.03799898 1725.91 0.03797696 0      7   305858

The `model_eval()` function from this package allows you to provide inputs and receive the model output, with a prediction interval by default. (For logistic regression, only a confidence interval is available.)

    vote_model |> model_eval(yearofbirth=c(1960, 1980), primary2004="voted", hhsize=4)
    #> Warning in model_eval(vote_model, yearofbirth = c(1960, 1980), primary2004 =
    #> "voted", : No prediction interval available, since the response variable is
    #> effectively categorical, not quantitative.
    #>   yearofbirth primary2004 hhsize   .output
    #> 1        1960       voted      4 0.4418285
    #> 2        1980       voted      4 0.3128150