diff --git a/parts/estimating-models/estimating-models.pdf b/parts/estimating-models/estimating-models.pdf deleted file mode 100644 index df92aeb..0000000 Binary files a/parts/estimating-models/estimating-models.pdf and /dev/null differ diff --git a/parts/estimating-models/index.Rmd b/parts/estimating-models/index.Rmd index 7f49a00..e20cba7 100755 --- a/parts/estimating-models/index.Rmd +++ b/parts/estimating-models/index.Rmd @@ -104,6 +104,127 @@ class: middle, inverse --- +# Many FOSS options model estimation + +R packages: + +- [{logitr}](https://github.com/jhelvy/logitr): Fastest, mixed logit, WTP space. +- [{apollo}](http://www.apollochoicemodelling.com/): Most flexible, great documentation. +- [{mlogit}](https://www.jstatsoft.org/article/view/v095i11): The OG R package. +- [{gmnl}](https://www.jstatsoft.org/article/view/v079i02): Generalized logit model (though slow). +- [{mixl}](https://github.com/joemolloy/fast-mixed-mnl): Good for big datasets (uses C for speed). + +Python packages: + +- [{xlogit}](https://xlogit.readthedocs.io/en/latest/): Basically Python version of {logitr}. + +[Stan](https://www.inwt-statistics.com/blog/understand-customer-decision-making-discrete-choice-models-with-rstan): For the Bayesians. + +--- + +# Many FOSS options model estimation + +R packages: + +- [{logitr}](https://github.com/jhelvy/logitr): Fastest, mixed logit, WTP space. .red[<- I wrote this one, so I'm showcasing it!] +- [{apollo}](http://www.apollochoicemodelling.com/): Most flexible, great documentation. +- [{mlogit}](https://www.jstatsoft.org/article/view/v095i11): The OG R package. +- [{gmnl}](https://www.jstatsoft.org/article/view/v079i02): Generalized logit model (though slow). +- [{mixl}](https://github.com/joemolloy/fast-mixed-mnl): Good for big datasets (uses C for speed). + +Python packages: + +- [{xlogit}](https://xlogit.readthedocs.io/en/latest/): Basically Python version of {logitr}. + +[Stan](https://www.inwt-statistics.com/blog/understand-customer-decision-making-discrete-choice-models-with-rstan): For the Bayesians. + +--- + +class: center +background-color: #fff + +## {logitr} is fast! + +
+ +
+ +--- + +class: center + +## {logitr} supports two common forms of utility models + +.leftcol[ + +## Preference Space + +
+ +
+ +] + +.rightcol[ + +## WTP Space + +
+ +
+ +] + +--- + +## .center[{logitr} has a similar UI with {cbcTools}] + +.center[({cbcTools} uses {logitr} to simulate choices and assess power)] + +.leftcol[ + +## .center[{cbcTools}] + +```{r} +#| eval: false + +power <- cbc_power( + nbreaks = 10, + n_q = 6, + data = data, + obsID = "obsID", + outcome = "choice", + pars = c("price", "type", "freshness") +) +``` + +] + +.rightcol[ + +## .center[{logitr}] + +```{r} +#| eval: false + +model <- logitr( + data = data, + obsID = "obsID", + outcome = "choice", + pars = c("price", "type", "freshness") +) +``` + +] + +--- + +class: inverse, middle, center + +# Utility model refresher + +--- + class: center # Which would you choose? @@ -155,7 +276,7 @@ class: center
- +
-- @@ -713,42 +834,6 @@ class: center, middle, inverse --- -## .center[`wtp()`: Compute WTP from Preference Space model] - -
- -.leftcol30[ - -
- -
- -] - -.rightcol65[ - -```{r} -wtp(mnl_pref, scalePar = "price") -``` - -] - ---- - -### .center[`wtpCompare()`: Compare WTP from Preference & WTP space models] - -
- -.leftcol70[ - -```{r} -wtpCompare(mnl_pref, mnl_wtp, scalePar = "price") -``` - -] - ---- - ### .center[`predict()`: Expected shares for a set of alternatives]
@@ -788,7 +873,7 @@ data .rightcol[ -Compute expected shares +Predict probabilities ```{r} predict( @@ -805,6 +890,17 @@ predict( class: inverse +# Your turn + +- Download the practice zip file for this section. +- Open the `estimating-models.Rproj` file to open RStudio. +- In RStudio, open the `practice.R` file. +- Experiment with estimating different models (use either one of the example datasets included in the package, or simulate your own data!) + +--- + +class: inverse +
## .center[{logitr} documentation:
https://jhelvy.github.io/logitr/] diff --git a/parts/estimating-models/index.html b/parts/estimating-models/index.html index 065e0b9..d35ca01 100644 --- a/parts/estimating-models/index.html +++ b/parts/estimating-models/index.html @@ -56,14 +56,133 @@ .rightcol60[ -### John Paul Helveston -### The George Washington University | Dept. of Engineering Management and Systems Engineering -### June 15, 2023 +### John Paul Helveston +### The George Washington University | Dept. of Engineering Management and Systems Engineering +### June 15, 2023 ] --- +# Many FOSS options model estimation + +R packages: + +- [{logitr}](https://github.com/jhelvy/logitr): Fastest, mixed logit, WTP space. +- [{apollo}](http://www.apollochoicemodelling.com/): Most flexible, great documentation. +- [{mlogit}](https://www.jstatsoft.org/article/view/v095i11): The OG R package. +- [{gmnl}](https://www.jstatsoft.org/article/view/v079i02): Generalized logit model (though slow). +- [{mixl}](https://github.com/joemolloy/fast-mixed-mnl): Good for big datasets (uses C for speed). + +Python packages: + +- [{xlogit}](https://xlogit.readthedocs.io/en/latest/): Basically Python version of {logitr}. + +[Stan](https://www.inwt-statistics.com/blog/understand-customer-decision-making-discrete-choice-models-with-rstan): For the Bayesians. + +--- + +# Many FOSS options model estimation + +R packages: + +- [{logitr}](https://github.com/jhelvy/logitr): Fastest, mixed logit, WTP space. .red[<- I wrote this one, so I'm showcasing it!] +- [{apollo}](http://www.apollochoicemodelling.com/): Most flexible, great documentation. +- [{mlogit}](https://www.jstatsoft.org/article/view/v095i11): The OG R package. +- [{gmnl}](https://www.jstatsoft.org/article/view/v079i02): Generalized logit model (though slow). +- [{mixl}](https://github.com/joemolloy/fast-mixed-mnl): Good for big datasets (uses C for speed). + +Python packages: + +- [{xlogit}](https://xlogit.readthedocs.io/en/latest/): Basically Python version of {logitr}. + +[Stan](https://www.inwt-statistics.com/blog/understand-customer-decision-making-discrete-choice-models-with-rstan): For the Bayesians. + +--- + +class: center +background-color: #fff + +## {logitr} is fast! + +<center> +<img src="https://jhelvy.github.io/logitr/articles/benchmark.png" width=750> +</center> + +--- + +class: center + +## {logitr} supports two common forms of utility models + +.leftcol[ + +## Preference Space + +<center> +<img src="images/utilityPreference2.png" width=500> +</center> + +] + +.rightcol[ + +## WTP Space + +<center> +<img src="images/utilityWtp2.png" width=520> +</center> + +] + +--- + +## .center[{logitr} has a similar UI with {cbcTools}] + +.center[({cbcTools} uses {logitr} to simulate choices and assess power)] + +.leftcol[ + +## .center[{cbcTools}] + + +```r +power <- cbc_power( + nbreaks = 10, + n_q = 6, + data = data, + obsID = "obsID", + outcome = "choice", + pars = c("price", "type", "freshness") +) +``` + +] + +.rightcol[ + +## .center[{logitr}] + + +```r +model <- logitr( + data = data, + obsID = "obsID", + outcome = "choice", + pars = c("price", "type", "freshness") +) +``` + +] + +--- + +class: inverse, middle, center + +# Utility model refresher + +--- + class: center # Which would you choose? @@ -115,7 +234,7 @@ </br> <center> -<img src="images/utilityPreference.png" width="800"> +<img src="images/utilityPreference.png" width="1000"> </center> -- @@ -150,9 +269,9 @@ ``` #> Estimate Std. Error z-value Pr(>|z|) -#> brandhiland -8.01982 0.46157 -17.3750 < 2.2e-16 *** -#> brandyoplait 3.72173 0.15890 23.4217 < 2.2e-16 *** -#> branddannon 1.65734 0.16721 9.9119 < 2.2e-16 *** +#> brandhiland -8.01982 0.46019 -17.4271 < 2.2e-16 *** +#> brandyoplait 3.72173 0.15871 23.4505 < 2.2e-16 *** +#> branddannon 1.65734 0.16746 9.8972 < 2.2e-16 *** #> --- #> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ``` @@ -346,10 +465,10 @@ ``` #> Estimate Std. Error z-value Pr(>|z|) -#> scalePar 0.388626 0.024231 16.0382 < 2.2e-16 *** -#> brandhiland -8.019815 0.461572 -17.3750 < 2.2e-16 *** -#> brandyoplait 3.721731 0.158901 23.4217 < 2.2e-16 *** -#> branddannon 1.657345 0.167208 9.9119 < 2.2e-16 *** +#> scalePar 0.388626 0.024364 15.9509 < 2.2e-16 *** +#> brandhiland -8.019815 0.460193 -17.4271 < 2.2e-16 *** +#> brandyoplait 3.721731 0.158706 23.4505 < 2.2e-16 *** +#> branddannon 1.657345 0.167455 9.8972 < 2.2e-16 *** #> --- #> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ``` @@ -819,63 +938,6 @@ --- -## .center[`wtp()`: Compute WTP from Preference Space model] - -</br> - -.leftcol30[ - -<center> -<img src="images/wtpHatComputed.png" width=300> -</center> - -] - -.rightcol65[ - - -```r -wtp(mnl_pref, scalePar = "price") -``` - -``` -#> Estimate Std. Error z-value Pr(>|z|) -#> scalePar 0.388626 0.024291 15.9990 < 2.2e-16 *** -#> brandhiland -8.019815 0.460540 -17.4140 < 2.2e-16 *** -#> brandyoplait 3.721731 0.158789 23.4381 < 2.2e-16 *** -#> branddannon 1.657345 0.166991 9.9247 < 2.2e-16 *** -#> --- -#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 -``` - -] - ---- - -### .center[`wtpCompare()`: Compare WTP from Preference & WTP space models] - -</br> - -.leftcol70[ - - -```r -wtpCompare(mnl_pref, mnl_wtp, scalePar = "price") -``` - -``` -#> pref wtp difference -#> scalePar 0.3886257 0.3886334 0.00000768 -#> brandhiland -8.0198153 -8.0197171 0.00009827 -#> brandyoplait 3.7217309 3.7217106 -0.00002022 -#> branddannon 1.6573449 1.6572896 -0.00005538 -#> logLik -2665.1101915 -2665.1101915 0.00000000 -``` - -] - ---- - ### .center[`predict()`: Expected shares for a set of alternatives] </br> @@ -908,7 +970,7 @@ .rightcol[ -Compute expected shares +Predict probabilities ```r @@ -934,6 +996,17 @@ class: inverse +# Your turn + +- Download the practice zip file for this section. +- Open the `estimating-models.Rproj` file to open RStudio. +- In RStudio, open the `practice.R` file. +- Experiment with estimating different models (use either one of the example datasets included in the package, or simulate your own data!) + +--- + +class: inverse + <br> ## .center[{logitr} documentation:<br>https://jhelvy.github.io/logitr/] diff --git a/parts/estimating-models/practice.R b/parts/estimating-models/practice.R new file mode 100755 index 0000000..e62a23b --- /dev/null +++ b/parts/estimating-models/practice.R @@ -0,0 +1,110 @@ +# Estimate logit models with the logitr package + +# Install packages +# install.packages("cbcTools") +# install.packages("logitr") + +# Load libraries +library(cbcTools) +library(logitr) + +# Data ---- + +# Get familiar with the data format required to estimate a model with logitr + +# The package comes with several datasets: + +# cars_china Stated car choice observations by Chinese car buyers +# cars_us Stated car choice observations by US car buyers +# electricity Stated preference data for the choice of +# electricity suppliers (from mlogit package) +# yogurt Choice observations of yogurt purchases by 100 households + +# You can also simulate a dataset using cbcTools! + +data <- cbc_profiles( + price = c(1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5), + type = c("Fuji", "Gala", "Honeycrisp"), + freshness = c('Poor', 'Average', 'Excellent') + ) |> cbc_design( + n_resp = 1000, # Number of respondents + n_alts = 3, # Number of alternatives per question + n_q = 6 # Number of questions per respondent + ) |> + cbc_choices( + obsID = "obsID", + priors = list( + price = -0.1, + type = c(0.1, 0.2), + freshness = c(0.1, 0.2) + ) + ) + + + +# Models ---- + +data <- yogurt + +# Multinomial logit, preference space + +mnl_pref <- logitr( + data = yogurt, + outcome = 'choice', + obsID = 'obsID', + pars = c('price', 'feat', 'brand') +) + +summary(mnl_pref) + +# Multinomial logit, WTP space + +mnl_wtp <- logitr( + data = yogurt, + outcome = 'choice', + obsID = 'obsID', + pars = c('feat', 'brand'), + scalePar = 'price', + # Since WTP space models are non-convex, run a multistart + numMultiStarts = 10 +) + +# Compare WTP from both models + +wtpCompare(mnl_pref, mnl_wtp, scalePar = 'price') + + + +# Mixed logit, preference space + +mxl_pref <- logitr( + data = yogurt, + outcome = 'choice', + obsID = 'obsID', + panelID = 'id', + pars = c('price', 'feat', 'brand'), + randPars = c(feat = 'n', brand = 'n'), + numMultiStarts = 10 +) + +summary(mxl_pref) + +# Mixed logit, WTP space + +mxl_wtp <- logitr( + data = yogurt, + outcome = 'choice', + obsID = 'obsID', + panelID = 'id', + pars = c('feat', 'brand'), + scalePar = 'price', + randPars = c(feat = 'n', brand = 'n'), + numMultiStarts = 10 +) + +summary(mxl_wtp) + +# Compare WTP from both models + +wtpCompare(mxl_pref, mxl_wtp, scalePar = 'price') +