Reflection on Trees with Group Project Data

Analytics Objective: Predict Retail Sales Revenue

Author

Mickyas Shawel

Published

August 16, 2026

Overview

This report applies the decision-tree workflow from the Week 9 Trees and Ensembles module to our Group 1 retail-sales project. The analysis reframes the project as a supervised machine-learning problem and evaluates whether tree-based methods can predict transaction-level sales revenue from promotional, marketing, product, store, and calendar characteristics.

NoteImportant metric note

The assignment’s pruning prompt refers to AUC, which is a classification metric. Because this report uses a regression tree with continuous sales revenue as the outcome, pruning is evaluated with RMSE and (R^2) instead. This preserves the statistical meaning of the selected analytics objective.

1 Setup

1.1 Required packages

Code
library(tidyverse)
library(tidymodels)
library(readxl)
library(janitor)
library(lubridate)
library(rpart)
library(rpart.plot)
library(vip)
library(ranger)
library(xgboost)

tidymodels_prefer()
set.seed(617)

1.2 Import the Group Project data

Prompt: Set up the QMD file with appropriate libraries and data and go through the entire machine-learning process for the analytics objective.

Place Retail_sales.xlsx in the same M09 project folder as this QMD file before rendering.

Code
retail <- read_excel("Retail_sales.xlsx") |>
  clean_names() |>
  rename(
    revenue      = sales_revenue_usd,
    discount_pct = discount_percentage,
    mktg_spend   = marketing_spend_usd,
    units        = units_sold,
    category     = product_category,
    location     = store_location,
    day          = day_of_the_week,
    holiday      = holiday_effect
  ) |>
  mutate(
    date = as.Date(date),
    season = case_when(
      month(date) %in% c(12, 1, 2) ~ "Winter",
      month(date) %in% c(3, 4, 5)  ~ "Spring",
      month(date) %in% c(6, 7, 8)  ~ "Summer",
      TRUE ~ "Fall"
    ),
    season = factor(season,
                    levels = c("Winter", "Spring", "Summer", "Fall")),
    holiday = factor(
      if_else(as.logical(holiday), "Holiday", "Non-Holiday")
    ),
    category = factor(category),
    location = factor(location),
    day = factor(day)
  )

glimpse(retail)
Rows: 30,000
Columns: 12
$ store_id     <chr> "Spearsland", "Spearsland", "Spearsland", "Spearsland", "…
$ product_id   <chr> "52372247", "52372247", "52372247", "52372247", "52372247…
$ date         <date> 2022-01-01, 2022-01-02, 2022-01-03, 2022-01-04, 2022-01-…
$ units        <dbl> 9, 7, 1, 4, 2, 8, 6, 9, 7, 1, 4, 6, 3, 6, 3, 2, 8, 6, 13,…
$ revenue      <dbl> 2741.69, 2665.53, 380.79, 1523.16, 761.58, 3046.32, 2284.…
$ discount_pct <dbl> 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 15, 0, 0, 0, …
$ mktg_spend   <dbl> 81, 0, 0, 0, 0, 41, 0, 83, 0, 164, 61, 0, 197, 0, 163, 16…
$ location     <fct> Tanzania, Mauritania, Saint Pierre and Miquelon, Australi…
$ category     <fct> Furniture, Furniture, Furniture, Furniture, Furniture, Fu…
$ day          <fct> Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, F…
$ holiday      <fct> Non-Holiday, Non-Holiday, Non-Holiday, Non-Holiday, Non-H…
$ season       <fct> Winter, Winter, Winter, Winter, Winter, Winter, Winter, W…

2 1. Analytics Objective

2.1 Prompt

State your AO (Analytics Objective) for your project. If your AO did not involve machine learning, revise it appropriately. State whether it is supervised or unsupervised learning, identify the outcome and features, and name the broader category of machine-learning methods.

2.2 Response

2.2.1 Customer-oriented objective

The analytics objective is to predict sales revenue for a retail transaction using information available about the promotion, marketing activity, product, store, and shopping context. The business purpose is to help a retailer better anticipate revenue outcomes and identify the conditions most strongly associated with higher or lower sales performance.

This is supervised learning because the historical dataset contains a known outcome, revenue, that the model learns to predict.

The outcome is:

  • Sales Revenue (revenue) — continuous numeric target.

The primary features are:

  • discount_pct — discount percentage
  • mktg_spend — marketing spend
  • units — units sold
  • category — product category
  • location — store location
  • day — day of week
  • holiday — holiday indicator
  • season — derived season

Because the outcome is continuous, the broader machine-learning category is regression.

TipWhy this AO is useful

Instead of asking only whether discounts correlate with sales, a predictive model can evaluate several customer and retail conditions simultaneously and estimate expected revenue for new observations.

3 2. Method Selection

3.1 Prompt

Choose either a classification tree or regression tree for the chosen machine-learning task. First, pick a machine-learning method and explain why the method would be appropriate.

3.2 Response

I selected a regression decision tree because the outcome, sales revenue, is continuous.

A regression tree is useful here because retail relationships may not be linear. For example, the effect of a discount may change after a particular threshold, marketing spend may matter more for certain categories, and holiday conditions may interact with product or store characteristics. A decision tree can represent these nonlinear splits without requiring every relationship to be specified in advance.

Trees are also relatively interpretable. A retailer can follow a sequence of decision rules and understand why observations are placed into different predicted-revenue groups.

The main weakness is that a single deep tree can overfit. For that reason, this report evaluates pruning and also compares the tree with ensemble alternatives.

4 3. Data Preparation

4.1 Train/Test Split

Prompt: Go through the entire machine-learning process, including data splitting.

Code
set.seed(617)

retail_split <- initial_split(retail, prop = 0.80, strata = revenue)

retail_train <- training(retail_split)
retail_test  <- testing(retail_split)

tibble(
  sample = c("Training", "Testing"),
  rows = c(nrow(retail_train), nrow(retail_test))
)

An 80/20 split reserves most observations for learning model patterns while keeping a separate test set for evaluating performance on unseen observations.

4.2 Recipe

Prompt: Create an appropriate recipe for the machine-learning task.

Code
tree_rec <- recipe(
  revenue ~ discount_pct + mktg_spend + units +
    category + location + day + holiday + season,
  data = retail_train
) |>
  step_unknown(all_nominal_predictors()) |>
  step_novel(all_nominal_predictors())

A tree does not require normalization because its splits depend on feature values and ordering rather than distance or coefficient scale.

5 4. Baseline Regression Tree

5.1 Model Specification

Code
tree_spec <- decision_tree(
  cost_complexity = 0.001,
  tree_depth = 10,
  min_n = 10
) |>
  set_engine("rpart") |>
  set_mode("regression")

tree_wf <- workflow() |>
  add_recipe(tree_rec) |>
  add_model(tree_spec)

5.2 Model Fitting

Code
tree_fit <- fit(tree_wf, data = retail_train)
tree_fit
══ Workflow [trained] ══════════════════════════════════════════════════════════
Preprocessor: Recipe
Model: decision_tree()

── Preprocessor ────────────────────────────────────────────────────────────────
2 Recipe Steps

• step_unknown()
• step_novel()

── Model ───────────────────────────────────────────────────────────────────────
n= 23998 

node), split, n, deviance, yval
      * denotes terminal node

  1) root 23998 156389900000  2743.7400  
    2) units< 8.5 18733  54142120000  2088.1880  
      4) units< 4.5 8169   7579569000  1234.3000  
        8) units< 2.5 2603    747930500   654.1303  
         16) units< 1.5 1066    100510800   359.5969 *
         17) units>=1.5 1537    490807100   858.4065 *
        9) units>=2.5 5566   5545731000  1505.6220  
         18) category=Furniture,Groceries 2995   2338306000  1262.1040 *
         19) category=Clothing,Electronics 2571   2822920000  1789.3010  
           38) location=Afghanistan,American Samoa,Andorra,Angola,Anguilla,Argentina,Aruba,Austria,Bahamas,Bahrain,Bhutan,Bosnia and Herzegovina,Botswana,Bouvet Island (Bouvetoya),British Indian Ocean Territory (Chagos Archipelago),British Virgin Islands,Burkina Faso,Burundi,Cambodia,Cameroon,Canada,Central African Republic,China,Christmas Island,Congo,Costa Rica,Croatia,Cyprus,Czech Republic,Denmark,Dominica,Ecuador,Equatorial Guinea,Eritrea,Ethiopia,Falkland Islands (Malvinas),Faroe Islands,Finland,France,French Guiana,French Southern Territories,Gabon,Gambia,Germany,Ghana,Gibraltar,Greece,Greenland,Grenada,Guadeloupe,Guatemala,Guernsey,Guyana,Holy See (Vatican City State),Honduras,Hong Kong,Iceland,India,Indonesia,Isle of Man,Italy,Jersey,Jordan,Kazakhstan,Kiribati,Korea,Kuwait,Kyrgyz Republic,Lao People's Democratic Republic,Latvia,Lebanon,Liberia,Lithuania,Luxembourg,Macao,Madagascar,Malawi,Malaysia,Maldives,Mali,Mauritania,Mexico,Micronesia,Monaco,Mongolia,Montenegro,Mozambique,Namibia,New Caledonia,New Zealand,Niue,Norfolk Island,North Macedonia,Northern Mariana Islands,Norway,Paraguay,Pitcairn Islands,Qatar,Reunion,Romania,Russian Federation,Rwanda,Saint Helena,Saint Lucia,Saint Martin,Saint Vincent and the Grenadines,Sao Tome and Principe,Saudi Arabia,Slovakia (Slovak Republic),Solomon Islands,South Africa,South Georgia and the South Sandwich Islands,Spain,Switzerland,Syrian Arab Republic,Taiwan,Tajikistan,Thailand,Timor-Leste,Togo,Tokelau,Trinidad and Tobago,Tunisia,Turkey,Turkmenistan,Tuvalu,United Kingdom,United States of America,Uruguay,Uzbekistan,Vietnam,Yemen,Zimbabwe 1408   1459958000  1554.5690 *
           39) location=Albania,Algeria,Antarctica (the territory South of 60 deg S),Antigua and Barbuda,Armenia,Australia,Azerbaijan,Bangladesh,Barbados,Belarus,Belgium,Belize,Benin,Bermuda,Bolivia,Brazil,Brunei Darussalam,Bulgaria,Cape Verde,Cayman Islands,Chad,Chile,Cocos (Keeling) Islands,Colombia,Comoros,Cook Islands,Cote d'Ivoire,Cuba,Djibouti,Dominican Republic,Egypt,El Salvador,Estonia,Fiji,French Polynesia,Georgia,Guam,Guinea,Guinea-Bissau,Haiti,Heard Island and McDonald Islands,Hungary,Iran,Iraq,Ireland,Israel,Jamaica,Japan,Kenya,Lesotho,Libyan Arab Jamahiriya,Liechtenstein,Malta,Marshall Islands,Martinique,Mauritius,Mayotte,Moldova,Montserrat,Morocco,Myanmar,Nauru,Nepal,Netherlands,Netherlands Antilles,Nicaragua,Niger,Nigeria,Oman,Pakistan,Palau,Palestinian Territory,Panama,Papua New Guinea,Peru,Philippines,Poland,Portugal,Puerto Rico,Saint Barthelemy,Saint Kitts and Nevis,Saint Pierre and Miquelon,Samoa,San Marino,Senegal,Serbia,Seychelles,Sierra Leone,Singapore,Slovenia,Somalia,Sri Lanka,Sudan,Suriname,Svalbard & Jan Mayen Islands,Swaziland,Sweden,Tanzania,Tonga,Turks and Caicos Islands,Uganda,Ukraine,United Arab Emirates,United States Minor Outlying Islands,United States Virgin Islands,Vanuatu,Venezuela,Wallis and Futuna,Western Sahara,Zambia 1163   1191460000  2073.4830 *
      5) units>=4.5 10564  36000460000  2748.4880  
       10) category=Furniture,Groceries 5809  16275650000  2341.0240  
         20) units< 6.5 3267   6434099000  2026.4540  
           40) location=Afghanistan,Andorra,Angola,Antarctica (the territory South of 60 deg S),Antigua and Barbuda,Aruba,Australia,Azerbaijan,Bahrain,Bangladesh,Barbados,Belarus,Belize,Bermuda,Bhutan,Bosnia and Herzegovina,Brazil,British Indian Ocean Territory (Chagos Archipelago),British Virgin Islands,Brunei Darussalam,Bulgaria,Burkina Faso,Burundi,Cambodia,Canada,Cayman Islands,Central African Republic,Chad,Chile,China,Cocos (Keeling) Islands,Comoros,Congo,Cook Islands,Costa Rica,Cote d'Ivoire,Croatia,Cuba,Czech Republic,Denmark,Djibouti,Dominican Republic,Ecuador,El Salvador,Equatorial Guinea,Ethiopia,Falkland Islands (Malvinas),Faroe Islands,Fiji,Finland,French Guiana,French Polynesia,French Southern Territories,Gabon,Gambia,Ghana,Guam,Guatemala,Guernsey,Guinea,Heard Island and McDonald Islands,Hong Kong,Hungary,Iceland,India,Isle of Man,Italy,Jamaica,Japan,Jordan,Kazakhstan,Kiribati,Latvia,Lebanon,Lesotho,Liberia,Libyan Arab Jamahiriya,Liechtenstein,Luxembourg,Macao,Martinique,Mauritania,Mauritius,Mayotte,Mexico,Mongolia,Montserrat,Morocco,Mozambique,Myanmar,Namibia,Nepal,Netherlands Antilles,New Caledonia,New Zealand,Nicaragua,Norfolk Island,North Macedonia,Northern Mariana Islands,Norway,Oman,Palau,Palestinian Territory,Paraguay,Pitcairn Islands,Poland,Portugal,Reunion,Russian Federation,Rwanda,Saint Barthelemy,Saint Kitts and Nevis,Saint Lucia,Saint Vincent and the Grenadines,San Marino,Saudi Arabia,Senegal,Serbia,Sierra Leone,Singapore,Slovakia (Slovak Republic),Solomon Islands,South Africa,South Georgia and the South Sandwich Islands,Spain,Suriname,Svalbard & Jan Mayen Islands,Sweden,Switzerland,Syrian Arab Republic,Taiwan,Tajikistan,Tanzania,Thailand,Timor-Leste,Togo,Tokelau,Tunisia,Turkey,Tuvalu,Uganda,Ukraine,United States Minor Outlying Islands,United States of America,Uruguay,Uzbekistan,Venezuela,Vietnam,Wallis and Futuna,Zambia 2024   3322046000  1787.9660 *
           41) location=Albania,Algeria,American Samoa,Anguilla,Argentina,Armenia,Austria,Bahamas,Belgium,Benin,Bolivia,Botswana,Bouvet Island (Bouvetoya),Cameroon,Cape Verde,Christmas Island,Colombia,Cyprus,Dominica,Egypt,Eritrea,Estonia,France,Georgia,Germany,Gibraltar,Greece,Greenland,Grenada,Guadeloupe,Guinea-Bissau,Guyana,Haiti,Holy See (Vatican City State),Honduras,Indonesia,Iran,Iraq,Ireland,Israel,Jersey,Kenya,Korea,Kuwait,Kyrgyz Republic,Lao People's Democratic Republic,Lithuania,Madagascar,Malawi,Malaysia,Maldives,Mali,Malta,Marshall Islands,Micronesia,Moldova,Monaco,Montenegro,Nauru,Netherlands,Niger,Nigeria,Niue,Pakistan,Panama,Papua New Guinea,Peru,Philippines,Puerto Rico,Qatar,Romania,Saint Helena,Saint Martin,Saint Pierre and Miquelon,Samoa,Sao Tome and Principe,Seychelles,Slovenia,Somalia,Sri Lanka,Sudan,Swaziland,Tonga,Trinidad and Tobago,Turkmenistan,Turks and Caicos Islands,United Arab Emirates,United Kingdom,United States Virgin Islands,Vanuatu,Western Sahara,Yemen,Zimbabwe 1243   2809486000  2414.7890 *
         21) units>=6.5 2542   9102776000  2745.3130  
           42) location=Albania,Algeria,Andorra,Angola,Antarctica (the territory South of 60 deg S),Antigua and Barbuda,Aruba,Austria,Azerbaijan,Bahrain,Belgium,Bermuda,Bolivia,Bosnia and Herzegovina,Brazil,British Indian Ocean Territory (Chagos Archipelago),British Virgin Islands,Brunei Darussalam,Bulgaria,Burkina Faso,Cameroon,Canada,Central African Republic,Chile,Christmas Island,Cocos (Keeling) Islands,Colombia,Congo,Costa Rica,Czech Republic,Djibouti,Dominica,Ecuador,Egypt,El Salvador,Equatorial Guinea,Eritrea,Estonia,Fiji,French Guiana,French Polynesia,Germany,Gibraltar,Guadeloupe,Guam,Guinea,Guinea-Bissau,Hong Kong,Iceland,India,Indonesia,Iraq,Japan,Kenya,Kiribati,Korea,Liberia,Malawi,Malta,Martinique,Mexico,Micronesia,Monaco,Mongolia,Montenegro,Morocco,Myanmar,Namibia,Nepal,Netherlands,New Caledonia,New Zealand,Nicaragua,Nigeria,Northern Mariana Islands,Oman,Pakistan,Palau,Palestinian Territory,Panama,Papua New Guinea,Reunion,Saint Helena,Saint Martin,Saint Pierre and Miquelon,Samoa,San Marino,Sao Tome and Principe,Saudi Arabia,Senegal,Serbia,Seychelles,Sierra Leone,Singapore,Slovenia,South Africa,Spain,Sri Lanka,Suriname,Swaziland,Sweden,Syrian Arab Republic,Tajikistan,Tanzania,Thailand,Togo,Tokelau,Tonga,Trinidad and Tobago,Turkmenistan,Turks and Caicos Islands,Tuvalu,Uruguay,Uzbekistan,Vanuatu,Vietnam,Western Sahara,Yemen,Zimbabwe 1270   3470399000  2281.2030 *
           43) location=Afghanistan,American Samoa,Anguilla,Argentina,Armenia,Australia,Bahamas,Bangladesh,Barbados,Belarus,Belize,Benin,Bhutan,Botswana,Bouvet Island (Bouvetoya),Burundi,Cambodia,Cape Verde,Cayman Islands,Chad,China,Comoros,Cook Islands,Cote d'Ivoire,Croatia,Cuba,Cyprus,Denmark,Dominican Republic,Ethiopia,Falkland Islands (Malvinas),Faroe Islands,Finland,France,French Southern Territories,Gabon,Gambia,Georgia,Ghana,Greece,Greenland,Grenada,Guatemala,Guernsey,Guyana,Haiti,Heard Island and McDonald Islands,Holy See (Vatican City State),Honduras,Hungary,Iran,Ireland,Isle of Man,Israel,Italy,Jamaica,Jersey,Jordan,Kazakhstan,Kuwait,Kyrgyz Republic,Lao People's Democratic Republic,Latvia,Lebanon,Lesotho,Libyan Arab Jamahiriya,Liechtenstein,Lithuania,Luxembourg,Macao,Madagascar,Malaysia,Maldives,Mali,Marshall Islands,Mauritania,Mauritius,Mayotte,Moldova,Montserrat,Mozambique,Nauru,Netherlands Antilles,Niger,Niue,Norfolk Island,North Macedonia,Norway,Paraguay,Peru,Philippines,Pitcairn Islands,Poland,Portugal,Puerto Rico,Qatar,Romania,Russian Federation,Rwanda,Saint Barthelemy,Saint Kitts and Nevis,Saint Lucia,Saint Vincent and the Grenadines,Slovakia (Slovak Republic),Solomon Islands,Somalia,South Georgia and the South Sandwich Islands,Sudan,Svalbard & Jan Mayen Islands,Switzerland,Taiwan,Timor-Leste,Tunisia,Turkey,Uganda,Ukraine,United Arab Emirates,United Kingdom,United States Minor Outlying Islands,United States of America,United States Virgin Islands,Venezuela,Wallis and Futuna,Zambia 1272   5085698000  3208.6920 *
       11) category=Clothing,Electronics 4755  17582140000  3246.2710  
         22) units< 6.5 2706   7198226000  2887.6880  
           44) location=Afghanistan,Albania,Andorra,Antigua and Barbuda,Argentina,Australia,Austria,Bahamas,Bahrain,Belarus,Belgium,Bermuda,Bolivia,Botswana,British Virgin Islands,Burundi,Cambodia,Cape Verde,Cayman Islands,China,Christmas Island,Cocos (Keeling) Islands,Congo,Cook Islands,Croatia,Cuba,Czech Republic,Denmark,Ecuador,Equatorial Guinea,Eritrea,Ethiopia,Falkland Islands (Malvinas),Faroe Islands,Fiji,Finland,French Southern Territories,Gabon,Gambia,Georgia,Germany,Ghana,Gibraltar,Greece,Grenada,Guadeloupe,Guatemala,Guinea,Guinea-Bissau,Holy See (Vatican City State),Iceland,India,Iran,Ireland,Isle of Man,Italy,Japan,Jersey,Kuwait,Kyrgyz Republic,Lao People's Democratic Republic,Lebanon,Liberia,Libyan Arab Jamahiriya,Luxembourg,Malawi,Malaysia,Malta,Marshall Islands,Martinique,Mauritania,Mayotte,Morocco,Myanmar,Namibia,New Caledonia,New Zealand,Nicaragua,Nigeria,Norway,Pakistan,Palau,Panama,Papua New Guinea,Philippines,Pitcairn Islands,Portugal,Reunion,Rwanda,Saint Kitts and Nevis,Saint Lucia,Saint Martin,Saint Pierre and Miquelon,Saint Vincent and the Grenadines,Samoa,Sao Tome and Principe,Saudi Arabia,Senegal,Serbia,Sierra Leone,Slovakia (Slovak Republic),South Africa,Spain,Sudan,Svalbard & Jan Mayen Islands,Syrian Arab Republic,Taiwan,Togo,Tunisia,Turks and Caicos Islands,Uganda,Ukraine,United Arab Emirates,United States of America,Uruguay,Venezuela,Wallis and Futuna,Western Sahara,Zimbabwe 1265   3176520000  2493.3200 *
           45) location=Algeria,American Samoa,Angola,Anguilla,Antarctica (the territory South of 60 deg S),Armenia,Aruba,Azerbaijan,Bangladesh,Barbados,Belize,Benin,Bhutan,Bosnia and Herzegovina,Bouvet Island (Bouvetoya),Brazil,British Indian Ocean Territory (Chagos Archipelago),Brunei Darussalam,Bulgaria,Burkina Faso,Cameroon,Canada,Central African Republic,Chad,Chile,Colombia,Comoros,Costa Rica,Cote d'Ivoire,Cyprus,Djibouti,Dominica,Dominican Republic,Egypt,El Salvador,Estonia,France,French Guiana,French Polynesia,Greenland,Guam,Guernsey,Guyana,Haiti,Heard Island and McDonald Islands,Honduras,Hong Kong,Hungary,Indonesia,Iraq,Israel,Jamaica,Jordan,Kazakhstan,Kenya,Kiribati,Korea,Latvia,Lesotho,Liechtenstein,Lithuania,Macao,Madagascar,Maldives,Mali,Mauritius,Mexico,Micronesia,Moldova,Monaco,Mongolia,Montenegro,Montserrat,Mozambique,Nauru,Nepal,Netherlands,Netherlands Antilles,Niger,Niue,Norfolk Island,North Macedonia,Northern Mariana Islands,Oman,Palestinian Territory,Paraguay,Peru,Poland,Puerto Rico,Qatar,Romania,Russian Federation,Saint Barthelemy,Saint Helena,San Marino,Seychelles,Singapore,Slovenia,Solomon Islands,Somalia,South Georgia and the South Sandwich Islands,Sri Lanka,Suriname,Swaziland,Sweden,Switzerland,Tajikistan,Tanzania,Thailand,Timor-Leste,Tokelau,Tonga,Trinidad and Tobago,Turkey,Turkmenistan,Tuvalu,United Kingdom,United States Minor Outlying Islands,United States Virgin Islands,Uzbekistan,Vanuatu,Vietnam,Yemen,Zambia 1441   3652256000  3233.8880 *
         23) units>=6.5 2049   9576458000  3719.8320  
           46) location=Albania,Algeria,American Samoa,Andorra,Antigua and Barbuda,Austria,Bangladesh,Barbados,Belize,Bhutan,Bolivia,Bosnia and Herzegovina,Botswana,Brazil,British Indian Ocean Territory (Chagos Archipelago),British Virgin Islands,Bulgaria,Burkina Faso,Cayman Islands,Chad,Chile,Christmas Island,Cocos (Keeling) Islands,Congo,Costa Rica,Cote d'Ivoire,Croatia,Cuba,Czech Republic,Djibouti,Dominica,Dominican Republic,Ecuador,Eritrea,Falkland Islands (Malvinas),Faroe Islands,Finland,French Polynesia,French Southern Territories,Gibraltar,Greenland,Grenada,Guam,Guinea,Guinea-Bissau,Haiti,Heard Island and McDonald Islands,Holy See (Vatican City State),Honduras,Hong Kong,Iran,Iraq,Israel,Jamaica,Japan,Jordan,Kenya,Kiribati,Korea,Kuwait,Liberia,Libyan Arab Jamahiriya,Macao,Madagascar,Maldives,Malta,Martinique,Mauritius,Micronesia,Monaco,Nauru,Netherlands,Netherlands Antilles,Nicaragua,Niger,Niue,Norfolk Island,North Macedonia,Northern Mariana Islands,Norway,Panama,Peru,Philippines,Pitcairn Islands,Reunion,Romania,Russian Federation,Saint Barthelemy,Saint Helena,Saint Lucia,Saint Pierre and Miquelon,Samoa,Sao Tome and Principe,Senegal,Seychelles,Singapore,Slovenia,Somalia,South Africa,Sri Lanka,Suriname,Svalbard & Jan Mayen Islands,Sweden,Taiwan,Tanzania,Timor-Leste,Togo,Tunisia,Ukraine,United Arab Emirates,United States Minor Outlying Islands,United States of America,Uzbekistan,Vanuatu,Vietnam,Wallis and Futuna,Yemen,Zambia,Zimbabwe 997   4257328000  3100.2400  
             92) location=American Samoa,Bangladesh,Barbados,Bhutan,Chile,Costa Rica,Croatia,Dominica,Dominican Republic,Faroe Islands,French Southern Territories,Haiti,Holy See (Vatican City State),Iraq,North Macedonia,Norway,Panama,Romania,Russian Federation,Saint Barthelemy,Saint Helena,Saint Pierre and Miquelon,Senegal,South Africa,Sri Lanka,Timor-Leste,Yemen,Zambia,Zimbabwe 200    685485100  2262.8860 *
             93) location=Albania,Algeria,Andorra,Antigua and Barbuda,Austria,Belize,Bolivia,Bosnia and Herzegovina,Botswana,Brazil,British Indian Ocean Territory (Chagos Archipelago),British Virgin Islands,Bulgaria,Burkina Faso,Cayman Islands,Chad,Christmas Island,Cocos (Keeling) Islands,Congo,Cote d'Ivoire,Cuba,Czech Republic,Djibouti,Ecuador,Eritrea,Falkland Islands (Malvinas),Finland,French Polynesia,Gibraltar,Greenland,Grenada,Guam,Guinea,Guinea-Bissau,Heard Island and McDonald Islands,Honduras,Hong Kong,Iran,Israel,Jamaica,Japan,Jordan,Kenya,Kiribati,Korea,Kuwait,Liberia,Libyan Arab Jamahiriya,Macao,Madagascar,Maldives,Malta,Martinique,Mauritius,Micronesia,Monaco,Nauru,Netherlands,Netherlands Antilles,Nicaragua,Niger,Niue,Norfolk Island,Northern Mariana Islands,Peru,Philippines,Pitcairn Islands,Reunion,Saint Lucia,Samoa,Sao Tome and Principe,Seychelles,Singapore,Slovenia,Somalia,Suriname,Svalbard & Jan Mayen Islands,Sweden,Taiwan,Tanzania,Togo,Tunisia,Ukraine,United Arab Emirates,United States Minor Outlying Islands,United States of America,Uzbekistan,Vanuatu,Vietnam,Wallis and Futuna 797   3396420000  3310.3670 *
           47) location=Afghanistan,Angola,Anguilla,Antarctica (the territory South of 60 deg S),Argentina,Armenia,Aruba,Australia,Azerbaijan,Bahamas,Bahrain,Belarus,Belgium,Benin,Bermuda,Bouvet Island (Bouvetoya),Brunei Darussalam,Burundi,Cambodia,Cameroon,Canada,Cape Verde,Central African Republic,China,Colombia,Comoros,Cook Islands,Cyprus,Denmark,Egypt,El Salvador,Equatorial Guinea,Estonia,Ethiopia,Fiji,France,French Guiana,Gabon,Gambia,Georgia,Germany,Ghana,Greece,Guadeloupe,Guatemala,Guernsey,Guyana,Hungary,Iceland,India,Indonesia,Ireland,Isle of Man,Italy,Jersey,Kazakhstan,Kyrgyz Republic,Lao People's Democratic Republic,Latvia,Lebanon,Lesotho,Liechtenstein,Lithuania,Luxembourg,Malawi,Malaysia,Mali,Marshall Islands,Mauritania,Mayotte,Mexico,Moldova,Mongolia,Montenegro,Montserrat,Morocco,Mozambique,Myanmar,Namibia,Nepal,New Caledonia,New Zealand,Nigeria,Oman,Pakistan,Palau,Palestinian Territory,Papua New Guinea,Paraguay,Poland,Portugal,Puerto Rico,Qatar,Rwanda,Saint Kitts and Nevis,Saint Martin,Saint Vincent and the Grenadines,San Marino,Saudi Arabia,Serbia,Sierra Leone,Slovakia (Slovak Republic),Solomon Islands,South Georgia and the South Sandwich Islands,Spain,Sudan,Swaziland,Switzerland,Syrian Arab Republic,Tajikistan,Thailand,Tokelau,Tonga,Trinidad and Tobago,Turkey,Turkmenistan,Turks and Caicos Islands,Tuvalu,Uganda,United Kingdom,United States Virgin Islands,Uruguay,Venezuela,Western Sahara 1052   4573656000  4307.0300  
             94) location=Afghanistan,Angola,Anguilla,Antarctica (the territory South of 60 deg S),Argentina,Australia,Azerbaijan,Bahamas,Bahrain,Belarus,Belgium,Benin,Bermuda,Brunei Darussalam,Cambodia,China,Denmark,El Salvador,Estonia,Ethiopia,Fiji,France,French Guiana,Gambia,Georgia,Ghana,Greece,Guadeloupe,Guernsey,Guyana,Hungary,Iceland,India,Ireland,Isle of Man,Kazakhstan,Kyrgyz Republic,Lao People's Democratic Republic,Latvia,Lesotho,Liechtenstein,Marshall Islands,Mauritania,Mexico,Montenegro,Montserrat,Morocco,Mozambique,Myanmar,Namibia,Nepal,New Caledonia,New Zealand,Oman,Palau,Palestinian Territory,Papua New Guinea,Poland,Portugal,Qatar,Rwanda,Saint Kitts and Nevis,Saint Martin,Saint Vincent and the Grenadines,San Marino,Saudi Arabia,Serbia,Sierra Leone,Solomon Islands,South Georgia and the South Sandwich Islands,Spain,Sudan,Switzerland,Syrian Arab Republic,Thailand,Tokelau,Tonga,Turkey,Turkmenistan,Tuvalu,Uganda,United Kingdom,United States Virgin Islands,Venezuela,Western Sahara 752   3372405000  4063.4800 *
             95) location=Armenia,Aruba,Bouvet Island (Bouvetoya),Burundi,Cameroon,Canada,Cape Verde,Central African Republic,Colombia,Comoros,Cook Islands,Cyprus,Egypt,Equatorial Guinea,Gabon,Germany,Guatemala,Indonesia,Italy,Jersey,Lebanon,Lithuania,Luxembourg,Malawi,Malaysia,Mali,Mayotte,Moldova,Mongolia,Nigeria,Pakistan,Paraguay,Puerto Rico,Slovakia (Slovak Republic),Swaziland,Tajikistan,Trinidad and Tobago,Turks and Caicos Islands,Uruguay 300   1044833000  4917.5280 *
    3) units>=8.5 5265  65553470000  5076.2120  
      6) units< 11.5 3638  28076790000  4377.6640  
       12) category=Furniture,Groceries 1565  10138340000  3650.3550  
         24) location=Angola,Anguilla,Antarctica (the territory South of 60 deg S),Antigua and Barbuda,Armenia,Aruba,Bahamas,Bangladesh,Barbados,Belgium,Belize,Benin,Bermuda,Bolivia,Bouvet Island (Bouvetoya),Brazil,British Indian Ocean Territory (Chagos Archipelago),Brunei Darussalam,Bulgaria,Cameroon,Canada,Central African Republic,Chad,Chile,Christmas Island,Comoros,Cook Islands,Croatia,Cuba,Cyprus,Czech Republic,Djibouti,Dominican Republic,El Salvador,Equatorial Guinea,Estonia,Ethiopia,Falkland Islands (Malvinas),Faroe Islands,Fiji,Finland,French Guiana,Georgia,Germany,Ghana,Greece,Grenada,Guadeloupe,Guam,Guatemala,Guernsey,Guyana,Holy See (Vatican City State),Honduras,Hungary,Iceland,Iran,Iraq,Ireland,Israel,Italy,Jamaica,Jersey,Jordan,Kenya,Kiribati,Korea,Lao People's Democratic Republic,Latvia,Lebanon,Liberia,Lithuania,Luxembourg,Madagascar,Malaysia,Maldives,Mali,Malta,Mauritius,Mexico,Monaco,Mongolia,Montenegro,Mozambique,Myanmar,Namibia,Nepal,Netherlands,Netherlands Antilles,Nicaragua,Nigeria,Norfolk Island,Northern Mariana Islands,Norway,Panama,Papua New Guinea,Paraguay,Peru,Philippines,Pitcairn Islands,Portugal,Puerto Rico,Qatar,Russian Federation,Rwanda,Saint Barthelemy,Saint Helena,Saint Kitts and Nevis,Saint Lucia,Saint Vincent and the Grenadines,San Marino,Sao Tome and Principe,Saudi Arabia,Serbia,Sierra Leone,Singapore,Slovakia (Slovak Republic),Slovenia,Solomon Islands,Somalia,Suriname,Svalbard & Jan Mayen Islands,Swaziland,Switzerland,Taiwan,Tanzania,Tokelau,Tonga,Trinidad and Tobago,Tunisia,Turkmenistan,Turks and Caicos Islands,Tuvalu,Uganda,Ukraine,United Arab Emirates,United Kingdom,United States Minor Outlying Islands,United States Virgin Islands,Vanuatu,Venezuela,Vietnam,Wallis and Futuna,Yemen,Zambia,Zimbabwe 969   4409427000  2975.4500  
           48) location=Antigua and Barbuda,Barbados,Benin,Cameroon,Chad,Fiji,Georgia,Greece,Grenada,Guyana,Honduras,Iceland,Iraq,Ireland,Israel,Korea,Latvia,Lebanon,Liberia,Madagascar,Maldives,Monaco,Mongolia,Namibia,Netherlands,Nicaragua,Norfolk Island,Norway,Papua New Guinea,Portugal,Qatar,Saint Barthelemy,Saint Kitts and Nevis,Saint Vincent and the Grenadines,Sao Tome and Principe,Solomon Islands,Svalbard & Jan Mayen Islands,Switzerland,Tokelau,Tonga,Trinidad and Tobago,Turkmenistan,United Kingdom,United States Minor Outlying Islands,United States Virgin Islands,Venezuela,Vietnam,Wallis and Futuna 277    607183300  2289.7020 *
           49) location=Angola,Anguilla,Antarctica (the territory South of 60 deg S),Armenia,Aruba,Bahamas,Bangladesh,Belgium,Belize,Bermuda,Bolivia,Bouvet Island (Bouvetoya),Brazil,British Indian Ocean Territory (Chagos Archipelago),Brunei Darussalam,Bulgaria,Canada,Central African Republic,Chile,Christmas Island,Comoros,Cook Islands,Croatia,Cuba,Cyprus,Czech Republic,Djibouti,Dominican Republic,El Salvador,Equatorial Guinea,Estonia,Ethiopia,Falkland Islands (Malvinas),Faroe Islands,Finland,French Guiana,Germany,Ghana,Guadeloupe,Guam,Guatemala,Guernsey,Holy See (Vatican City State),Hungary,Iran,Italy,Jamaica,Jersey,Jordan,Kenya,Kiribati,Lao People's Democratic Republic,Lithuania,Luxembourg,Malaysia,Mali,Malta,Mauritius,Mexico,Montenegro,Mozambique,Myanmar,Nepal,Netherlands Antilles,Nigeria,Northern Mariana Islands,Panama,Paraguay,Peru,Philippines,Pitcairn Islands,Puerto Rico,Russian Federation,Rwanda,Saint Helena,Saint Lucia,San Marino,Saudi Arabia,Serbia,Sierra Leone,Singapore,Slovakia (Slovak Republic),Slovenia,Somalia,Suriname,Swaziland,Taiwan,Tanzania,Tunisia,Turks and Caicos Islands,Tuvalu,Uganda,Ukraine,United Arab Emirates,Vanuatu,Yemen,Zambia,Zimbabwe 692   3619843000  3249.9470  
             98) units< 10.5 568   2558269000  3101.7550 *
             99) units>=10.5 124    991962500  3928.7610  
              198) location=Angola,Antarctica (the territory South of 60 deg S),Belgium,Belize,Bermuda,Brazil,Bulgaria,Canada,Central African Republic,Christmas Island,Cook Islands,Croatia,Cyprus,Czech Republic,El Salvador,Faroe Islands,Finland,Ghana,Guam,Guernsey,Jersey,Lao People's Democratic Republic,Luxembourg,Malta,Mauritius,Mexico,Montenegro,Mozambique,Myanmar,Northern Mariana Islands,Puerto Rico,Russian Federation,Saint Helena,San Marino,Serbia,Sierra Leone,Singapore,Somalia,Taiwan,Tanzania,Vanuatu,Yemen 76    191161000  2764.6590 *
              199) location=Armenia,Bahamas,British Indian Ocean Territory (Chagos Archipelago),Brunei Darussalam,Chile,Comoros,Equatorial Guinea,Falkland Islands (Malvinas),French Guiana,Germany,Jamaica,Kiribati,Lithuania,Malaysia,Nigeria,Peru,Pitcairn Islands,Saudi Arabia,Slovakia (Slovak Republic),Slovenia,Turks and Caicos Islands,Uganda,Ukraine,Zimbabwe 48    534743400  5771.9230 *
         25) location=Afghanistan,Albania,Algeria,American Samoa,Andorra,Argentina,Australia,Austria,Azerbaijan,Bahrain,Belarus,Bhutan,Bosnia and Herzegovina,Botswana,British Virgin Islands,Burkina Faso,Burundi,Cambodia,Cape Verde,Cayman Islands,China,Cocos (Keeling) Islands,Colombia,Congo,Costa Rica,Cote d'Ivoire,Denmark,Dominica,Ecuador,Egypt,Eritrea,France,French Polynesia,French Southern Territories,Gambia,Gibraltar,Greenland,Guinea,Guinea-Bissau,Haiti,Heard Island and McDonald Islands,Hong Kong,India,Indonesia,Isle of Man,Japan,Kazakhstan,Kuwait,Kyrgyz Republic,Lesotho,Libyan Arab Jamahiriya,Liechtenstein,Macao,Malawi,Marshall Islands,Mauritania,Mayotte,Micronesia,Moldova,Montserrat,Morocco,Nauru,New Caledonia,New Zealand,Niger,Niue,North Macedonia,Oman,Pakistan,Palau,Palestinian Territory,Poland,Reunion,Romania,Saint Martin,Saint Pierre and Miquelon,Samoa,Senegal,Seychelles,South Africa,South Georgia and the South Sandwich Islands,Spain,Sri Lanka,Sudan,Sweden,Syrian Arab Republic,Tajikistan,Thailand,Timor-Leste,Togo,Turkey,United States of America,Uruguay,Uzbekistan,Western Sahara 596   4569931000  4747.6440  
           50) location=Albania,Andorra,Argentina,Australia,Bahrain,Belarus,Bosnia and Herzegovina,British Virgin Islands,Burkina Faso,Burundi,Cape Verde,Cayman Islands,China,Cocos (Keeling) Islands,Colombia,Congo,Costa Rica,Denmark,Dominica,Ecuador,Eritrea,France,French Southern Territories,Gibraltar,Greenland,Guinea,Guinea-Bissau,Haiti,Heard Island and McDonald Islands,Hong Kong,Indonesia,Isle of Man,Japan,Kazakhstan,Kuwait,Kyrgyz Republic,Liechtenstein,Macao,Malawi,Mauritania,Mayotte,Montserrat,New Zealand,Niger,Niue,North Macedonia,Oman,Pakistan,Palestinian Territory,Poland,Reunion,Romania,Saint Pierre and Miquelon,Seychelles,South Georgia and the South Sandwich Islands,Spain,Sudan,Sweden,Syrian Arab Republic,Tajikistan,Thailand,Timor-Leste,Togo,Turkey,United States of America,Uruguay,Western Sahara 447   3224386000  4388.4100 *
           51) location=Afghanistan,Algeria,American Samoa,Austria,Azerbaijan,Bhutan,Botswana,Cambodia,Cote d'Ivoire,Egypt,French Polynesia,Gambia,India,Lesotho,Libyan Arab Jamahiriya,Marshall Islands,Micronesia,Moldova,Morocco,Nauru,New Caledonia,Palau,Saint Martin,Samoa,Senegal,South Africa,Sri Lanka,Uzbekistan 149   1114806000  5825.3440 *
       13) category=Clothing,Electronics 2073  16485610000  4926.7420  
         26) location=Afghanistan,Albania,Andorra,Anguilla,Antarctica (the territory South of 60 deg S),Argentina,Armenia,Aruba,Austria,Azerbaijan,Bahrain,Belarus,Belize,Bhutan,Bolivia,Bosnia and Herzegovina,Brazil,British Indian Ocean Territory (Chagos Archipelago),British Virgin Islands,Burkina Faso,Burundi,Cambodia,Cameroon,Central African Republic,Chile,China,Christmas Island,Colombia,Costa Rica,Croatia,Djibouti,Dominica,Eritrea,Ethiopia,Fiji,Finland,French Guiana,French Polynesia,Germany,Greece,Greenland,Guam,Guatemala,Guinea,Guyana,Haiti,Holy See (Vatican City State),Hong Kong,Israel,Jamaica,Jordan,Kenya,Korea,Lao People's Democratic Republic,Lebanon,Libyan Arab Jamahiriya,Liechtenstein,Macao,Madagascar,Maldives,Mali,Malta,Marshall Islands,Martinique,Mauritania,Mayotte,Micronesia,Moldova,Monaco,Montenegro,Montserrat,New Caledonia,New Zealand,Niger,Niue,Norfolk Island,Northern Mariana Islands,Pakistan,Palau,Panama,Paraguay,Peru,Philippines,Pitcairn Islands,Qatar,Reunion,Romania,Rwanda,Saint Barthelemy,Saint Helena,Saint Kitts and Nevis,Saint Lucia,Saint Martin,Saint Pierre and Miquelon,Samoa,San Marino,Sao Tome and Principe,Saudi Arabia,Senegal,Serbia,Solomon Islands,Somalia,South Africa,Spain,Sudan,Suriname,Swaziland,Taiwan,Timor-Leste,Tunisia,Turkmenistan,Tuvalu,Ukraine,United Arab Emirates,United Kingdom,United States Minor Outlying Islands,United States of America,Uruguay,Wallis and Futuna,Yemen,Zambia,Zimbabwe 1028   7338422000  4120.7440  

...
and 56 more lines.

5.3 Tree Visualization

Code
tree_fit |>
  extract_fit_engine() |>
  rpart.plot(
    type = 2,
    extra = 101,
    fallen.leaves = TRUE,
    cex = 0.65
  )

Regression tree for predicting retail sales revenue.

5.4 Test-Set Evaluation

Code
tree_test_results <- predict(tree_fit, retail_test) |>
  bind_cols(retail_test |> select(revenue))

tree_test_metrics <- tree_test_results |>
  metrics(truth = revenue, estimate = .pred)

tree_test_metrics

For regression, RMSE measures the typical magnitude of prediction errors in revenue units, while (R^2) describes the proportion of outcome variation captured by the model. Lower RMSE and higher (R^2) indicate better predictive performance.

6 5. Alternative Tree-Based Methods

6.1 Prompt

What alternative methods can you try to improve the metrics produced above? Try them. Compare all methods using 10-fold cross-validation. Interpret the results. Which one is best?

6.2 Response

A single tree is interpretable but can have relatively high variance. I therefore compare it with two ensemble methods:

  1. Random Forest — reduces variance by averaging many decorrelated trees.
  2. XGBoost — sequentially builds trees that focus on correcting earlier prediction errors.

6.3 10-Fold Cross-Validation

Code
set.seed(617)
retail_folds <- vfold_cv(retail_train, v = 10, strata = revenue)

reg_metrics <- metric_set(rmse, rsq, mae)
ctrl <- control_resamples(save_pred = TRUE)

6.4 Decision Tree CV

Code
tree_cv <- tree_wf |>
  fit_resamples(
    resamples = retail_folds,
    metrics = reg_metrics,
    control = ctrl
  )

6.5 Random Forest CV

Code
rf_spec <- rand_forest(
  trees = 500,
  mtry = 4,
  min_n = 5
) |>
  set_engine("ranger", importance = "permutation") |>
  set_mode("regression")

rf_wf <- workflow() |>
  add_recipe(tree_rec) |>
  add_model(rf_spec)

rf_cv <- rf_wf |>
  fit_resamples(
    resamples = retail_folds,
    metrics = reg_metrics,
    control = ctrl
  )

6.6 XGBoost CV

Code
xgb_rec <- tree_rec |>
  step_dummy(all_nominal_predictors())

xgb_spec <- boost_tree(
  trees = 500,
  tree_depth = 6,
  learn_rate = 0.05,
  loss_reduction = 0,
  min_n = 10,
  sample_size = 0.8,
  mtry = 1
) |>
  set_engine("xgboost") |>
  set_mode("regression")

xgb_wf <- workflow() |>
  add_recipe(xgb_rec) |>
  add_model(xgb_spec)

xgb_cv <- xgb_wf |>
  fit_resamples(
    resamples = retail_folds,
    metrics = reg_metrics,
    control = ctrl
  )

6.7 Cross-Validated Model Comparison

Code
cv_comparison <- bind_rows(
  collect_metrics(tree_cv) |> mutate(model = "Decision Tree"),
  collect_metrics(rf_cv)   |> mutate(model = "Random Forest"),
  collect_metrics(xgb_cv)  |> mutate(model = "XGBoost")
) |>
  select(model, .metric, mean, std_err) |>
  arrange(.metric, mean)

cv_comparison
Code
cv_comparison |>
  filter(.metric == "rmse") |>
  ggplot(aes(x = reorder(model, mean), y = mean)) +
  geom_col() +
  geom_errorbar(
    aes(ymin = mean - std_err, ymax = mean + std_err),
    width = 0.15
  ) +
  coord_flip() +
  labs(
    x = NULL,
    y = "Cross-Validated RMSE",
    title = "Model Comparison",
    subtitle = "Lower RMSE indicates better predictive accuracy"
  ) +
  theme_minimal()

Ten-fold cross-validated RMSE across the three tree-based methods.

The preferred model is the one with the lowest cross-validated RMSE, considered together with (R^2), MAE, interpretability, and the business objective. Cross-validation is more informative than selecting a model based on training accuracy because every candidate is repeatedly evaluated on held-out folds.

7 6. Feature Importance

7.1 Prompt

Produce a chart that shows the importance of features. Is the result reasonable? Why or why not?

Code
rf_fit <- fit(rf_wf, data = retail_train)
Code
rf_fit |>
  extract_fit_engine() |>
  vip(num_features = 15)

Permutation feature importance from the fitted random forest.

Feature importance measures how useful predictors are to the fitted model. If variables such as units sold, marketing spend, discounts, or product/store characteristics rank highly, that is substantively plausible because they are directly connected with transaction performance.

However, importance is predictive rather than causal. A high-importance feature should not automatically be interpreted as something that causes revenue to increase.

8 7. Decision Tree Pruning

8.1 Prompt

Fit decision trees across cost_complexity values of c(0.0001, 0.001, 0.005, 0.01, 0.05, 0.10). Plot train vs. test performance across all values. At what value does test performance peak? What happens to training performance at the same value?

8.2 Why RMSE and (R^2) replace AUC

AUC requires a categorical outcome with positive and negative classes. Revenue is continuous, so using AUC would not be valid for this AO. I use RMSE as the primary pruning criterion and report (R^2) as a complementary measure.

8.3 Pruning Function

Code
fit_tree_cp <- function(cp_value) {

  spec <- decision_tree(
    cost_complexity = cp_value,
    tree_depth = 30,
    min_n = 2
  ) |>
    set_engine("rpart") |>
    set_mode("regression")

  wf <- workflow() |>
    add_recipe(tree_rec) |>
    add_model(spec)

  fitted <- fit(wf, data = retail_train)

  train_pred <- predict(fitted, retail_train) |>
    bind_cols(retail_train |> select(revenue))

  test_pred <- predict(fitted, retail_test) |>
    bind_cols(retail_test |> select(revenue))

  train_rmse <- rmse_vec(
    truth = train_pred$revenue,
    estimate = train_pred$.pred
  )

  test_rmse <- rmse_vec(
    truth = test_pred$revenue,
    estimate = test_pred$.pred
  )

  train_rsq <- rsq_vec(
    truth = train_pred$revenue,
    estimate = train_pred$.pred
  )

  test_rsq <- rsq_vec(
    truth = test_pred$revenue,
    estimate = test_pred$.pred
  )

  leaves <- fitted |>
    extract_fit_engine() |>
    pluck("frame") |>
    filter(var == "<leaf>") |>
    nrow()

  tibble(
    cp = cp_value,
    train_rmse = train_rmse,
    test_rmse = test_rmse,
    train_rsq = train_rsq,
    test_rsq = test_rsq,
    leaves = leaves
  )
}

8.4 Fit All Requested Cost-Complexity Values

Code
cp_values <- c(0.0001, 0.001, 0.005, 0.01, 0.05, 0.10)

pruning_results <- map_dfr(cp_values, fit_tree_cp)

pruning_results

8.5 Train vs. Test RMSE

Code
pruning_results |>
  select(cp, train_rmse, test_rmse) |>
  pivot_longer(
    cols = c(train_rmse, test_rmse),
    names_to = "sample",
    values_to = "rmse"
  ) |>
  ggplot(aes(x = factor(cp), y = rmse, group = sample, linetype = sample)) +
  geom_line() +
  geom_point(size = 2.5) +
  labs(
    x = "Cost Complexity (cp)",
    y = "RMSE",
    linetype = "Sample",
    title = "Decision Tree Pruning",
    subtitle = "Lower test RMSE indicates better generalization"
  ) +
  theme_minimal()

Training and test RMSE across requested cost-complexity values.

8.6 Train vs. Test (R^2)

Code
pruning_results |>
  select(cp, train_rsq, test_rsq) |>
  pivot_longer(
    cols = c(train_rsq, test_rsq),
    names_to = "sample",
    values_to = "rsq"
  ) |>
  ggplot(aes(x = factor(cp), y = rsq, group = sample, linetype = sample)) +
  geom_line() +
  geom_point(size = 2.5) +
  labs(
    x = "Cost Complexity (cp)",
    y = expression(R^2),
    linetype = "Sample",
    title = "Decision Tree Fit Across Pruning Levels"
  ) +
  theme_minimal()

Training and test R-squared across requested cost-complexity values.

8.7 Optimal cp

Code
optimal_cp <- pruning_results |>
  slice_min(test_rmse, n = 1, with_ties = FALSE)

optimal_cp

The optimal requested cp is the value producing the lowest test RMSE. At this point I compare training RMSE with test RMSE. A more complex tree can continue improving its fit to training observations even after its performance on unseen observations begins to deteriorate.

9 8. Leaf Nodes at the Optimal cp

9.1 Prompt

At the optimal cp, how many leaf nodes does the tree have? Use extract_fit_engine() |> pluck("frame") |> filter(var == "<leaf>") |> nrow().

Code
best_cp <- optimal_cp$cp[[1]]

optimal_tree_spec <- decision_tree(
  cost_complexity = best_cp,
  tree_depth = 30,
  min_n = 2
) |>
  set_engine("rpart") |>
  set_mode("regression")

optimal_tree_wf <- workflow() |>
  add_recipe(tree_rec) |>
  add_model(optimal_tree_spec)

optimal_tree_fit <- fit(optimal_tree_wf, data = retail_train)

optimal_leaf_nodes <- optimal_tree_fit |>
  extract_fit_engine() |>
  pluck("frame") |>
  filter(var == "<leaf>") |>
  nrow()

optimal_leaf_nodes
[1] 13

The rendered result above gives the exact number of terminal leaf nodes in the best tree among the requested pruning values.

10 9. Explaining Overfitting to a Marketing Manager

10.1 Prompt

In plain English, explain why a tree with 200 leaf nodes might perform worse on new customers than a tree with 15 leaf nodes even though it was more accurate on the training data.

10.2 Response

Imagine that the 200-leaf tree creates extremely specific customer rules. It might learn that a particular combination of discount, store, product category, day, and marketing spend was associated with a certain revenue outcome in the historical dataset. Some of those rules may represent genuine customer patterns, but others may simply capture random quirks in the sample.

The 15-leaf tree is forced to focus on broader and more repeatable patterns. It may make a few more mistakes on customers it has already seen, but its rules can transfer more reliably to new transactions.

This is the difference between memorizing historical customers and learning patterns that generalize. Pruning deliberately accepts some loss of training accuracy when that tradeoff produces better predictions for future customers.

ImportantMarketing interpretation

The most complicated model is not automatically the most useful model. The goal is not to explain every fluctuation in historical sales; it is to make reliable decisions about customers and transactions the retailer has not seen yet.

11 10. Overall Interpretation

Strengths

  • Easy to visualize and communicate
  • Handles nonlinear relationships
  • Captures interactions automatically
  • Requires relatively little preprocessing

Limitation

A single tree can be unstable and prone to overfitting.

Strengths

  • Reduces variance by averaging many trees
  • Usually generalizes better than one tree
  • Provides feature importance

Limitation

The combined forest is harder to explain as a single set of business rules.

Strengths

  • Sequentially corrects prediction errors
  • Can capture complex nonlinear patterns
  • Often provides strong predictive accuracy

Limitation

It introduces more tuning parameters and is less directly interpretable than one decision tree.

The model comparison illustrates an important lesson from the Trees and Ensembles module: interpretability and predictive performance are related but distinct objectives. A single tree provides a clear description of decision rules, while ensemble methods can improve prediction by combining many trees.

12 11. Final Reflection

This exercise changed how I think about decision trees. The value of a tree is not simply that it can split data into groups. The more important idea is controlling the balance between model complexity and generalization.

The pruning exercise makes this visible. A very flexible tree can continue reducing training error by creating increasingly specific leaves, but those additional rules can eventually represent noise rather than stable retail behavior. Cost-complexity pruning provides a systematic way to reduce that risk.

Comparing the decision tree with random forest and XGBoost also demonstrates why ensembles are powerful. Random forests reduce the instability of individual trees by averaging many of them, while boosting builds trees sequentially to correct previous errors. The best method should ultimately be selected using performance on unseen data rather than how closely it fits the training sample.

For the retail project, the most useful outcome is therefore not just a prediction of revenue. The analysis also provides a framework for understanding which information contributes most to predictive performance and how much complexity is justified when the goal is making decisions about future retail activity.

Appendix

12.1 Course Sources