library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(caret)
## Loading required package: lattice
## 
## Attaching package: 'caret'
## 
## The following object is masked from 'package:purrr':
## 
##     lift
library(fastDummies)

wine <- readRDS(gzcon(url("https://github.com/cd-public/D505/raw/master/dat/wine.rds")))

Abstract

This contains my assignment for features mainly about carret.

Step Up Code

Explanation: - tidyverse - load tidyverse for data manipulation and visualization - caret - for machine learning functionalities - fastDummies - for creating dummy variables if needed - wine - loads the wine dataset from GitHub

Feature Engineering

We begin by engineering a number of features.

Data Cleaning

print(colnames(wine))
##  [1] "id"                    "country"               "description"          
##  [4] "designation"           "points"                "price"                
##  [7] "province"              "region_1"              "region_2"             
## [10] "taster_name"           "taster_twitter_handle" "title"                
## [13] "variety"               "winery"                "year"
sum(is.na(wine))
## [1] 104228
colSums(is.na(wine))
##                    id               country           description 
##                     0                    53                     0 
##           designation                points                 price 
##                 25200                     0                     0 
##              province              region_1              region_2 
##                    53                 17844                 56475 
##           taster_name taster_twitter_handle                 title 
##                     0                  4603                     0 
##               variety                winery                  year 
##                     0                     0                     0
wine_clean <- wine %>% select(-designation, -region_2)
wine_clean <- wine_clean %>% drop_na(country, province, region_1)
colSums(is.na(wine_clean))
##                    id               country           description 
##                     0                     0                     0 
##                points                 price              province 
##                     0                     0                     0 
##              region_1           taster_name taster_twitter_handle 
##                     0                     0                  2726 
##                 title               variety                winery 
##                     0                     0                     0 
##                  year 
##                     0
wine_clean <- wine_clean %>% select(-taster_twitter_handle)
colSums(is.na(wine_clean))
##          id     country description      points       price    province 
##           0           0           0           0           0           0 
##    region_1 taster_name       title     variety      winery        year 
##           0           0           0           0           0           0
wine_clean <- wine_clean %>%
  mutate(
    log_price = log(price),
    points_squared = points^2,
    price_per_point = price / points,
    price_per_year = ifelse(!is.na(year), price / (2025 - year), NA),
    points_price_ratio = points / price,
    is_expensive = ifelse(price > 50, 1, 0),
    wine_age = ifelse(!is.na(year), 2025 - year, NA),
    description_length = nchar(description),
    variety_type = ifelse(variety %in% c("Cabernet Sauvignon", "Merlot", "Pinot Noir"), "Red", "Other"),
    country_region = paste(country, province, sep = "_")
  ) %>%
  drop_na()

wine_clean <- wine_clean %>%
  select(log_price, points_squared, price_per_point, price_per_year, 
         points_price_ratio, is_expensive, wine_age, description_length, 
         variety_type, country_region)

Caret

We now use a train/test split to evaluate the features.

set.seed(123)
train_index <- createDataPartition(wine_clean$log_price, p = 0.8, list = FALSE)
train_data <- wine_clean[train_index, ]
test_data <- wine_clean[-train_index, ]

dim(train_data)
## [1] 57372    10
dim(test_data)
## [1] 14340    10
nrow(train_data) / nrow(wine_clean)
## [1] 0.8000335
nrow(test_data) / nrow(wine_clean)
## [1] 0.1999665
train_control <- trainControl(method = "boot", number = 100)

model <- train(log_price ~ ., data = wine_clean, method = "lm", trControl = train_control)
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
## Warning in predict.lm(modelFit, newdata): prediction from rank-deficient fit;
## attr(*, "non-estim") has doubtful cases
summary(model)
## 
## Call:
## lm(formula = .outcome ~ ., data = dat)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -8.0684 -0.0674 -0.0254  0.0518  1.8355 
## 
## Coefficients:
##                                               Estimate Std. Error  t value
## (Intercept)                                  3.141e+00  9.540e-03  329.218
## points_squared                               9.679e-05  1.192e-06   81.198
## price_per_point                              4.053e-01  4.824e-03   84.025
## price_per_year                              -1.178e-02  6.879e-04  -17.120
## points_price_ratio                          -2.026e-01  2.985e-04 -678.842
## is_expensive                                 3.308e-01  1.474e-03  224.443
## wine_age                                     9.612e-04  1.886e-04    5.097
## description_length                           1.075e-05  8.299e-06    1.295
## variety_typeRed                              2.439e-02  1.182e-03   20.643
## country_regionArgentina_Other               -7.589e-03  5.518e-03   -1.375
## `country_regionAustralia_Australia Other`    1.169e-01  9.237e-03   12.654
## `country_regionAustralia_New South Wales`   -2.273e-02  1.351e-02   -1.682
## `country_regionAustralia_South Australia`   -2.962e-02  3.999e-03   -7.406
## country_regionAustralia_Tasmania            -1.171e-02  2.165e-02   -0.541
## country_regionAustralia_Victoria            -2.486e-02  7.304e-03   -3.403
## `country_regionAustralia_Western Australia` -3.823e-02  7.643e-03   -5.002
## `country_regionCanada_British Columbia`     -3.718e-02  9.323e-03   -3.988
## country_regionCanada_Ontario                -1.166e-02  1.255e-02   -0.929
## country_regionFrance_Alsace                 -4.282e-02  3.487e-03  -12.279
## country_regionFrance_Beaujolais             -5.384e-02  4.517e-03  -11.919
## country_regionFrance_Bordeaux               -2.010e-02  2.831e-03   -7.100
## country_regionFrance_Burgundy                2.515e-02  3.081e-03    8.163
## country_regionFrance_Champagne               5.709e-02  6.200e-03    9.208
## `country_regionFrance_France Other`          1.844e-02  6.368e-03    2.896
## `country_regionFrance_Languedoc-Roussillon` -6.374e-03  5.590e-03   -1.140
## `country_regionFrance_Loire Valley`         -4.015e-02  3.765e-03  -10.664
## country_regionFrance_Provence               -4.914e-02  4.408e-03  -11.148
## `country_regionFrance_Rhône Valley`         -1.484e-03  4.224e-03   -0.351
## `country_regionFrance_Southwest France`     -2.624e-02  3.869e-03   -6.782
## `country_regionItaly_Central Italy`         -2.526e-02  5.202e-03   -4.855
## `country_regionItaly_Italy Other`            7.740e-03  1.525e-02    0.507
## country_regionItaly_Lombardy                -1.090e-02  6.905e-03   -1.579
## `country_regionItaly_Northeastern Italy`    -3.090e-02  3.981e-03   -7.763
## `country_regionItaly_Northwestern Italy`    -7.852e-02  5.101e-02   -1.539
## country_regionItaly_Piedmont                 2.179e-02  3.356e-03    6.494
## `country_regionItaly_Sicily & Sardinia`     -2.106e-02  4.631e-03   -4.548
## `country_regionItaly_Southern Italy`        -2.916e-02  5.336e-03   -5.465
## country_regionItaly_Tuscany                 -2.703e-03  2.934e-03   -0.921
## country_regionItaly_Veneto                   1.667e-03  4.713e-03    0.354
## country_regionSpain_Andalucia               -5.049e-02  1.694e-02   -2.981
## country_regionSpain_Catalonia               -1.421e-02  4.557e-03   -3.118
## `country_regionSpain_Central Spain`          9.075e-02  5.733e-03   15.829
## country_regionSpain_Galicia                 -6.404e-02  6.221e-03  -10.293
## country_regionSpain_Levante                  5.717e-02  5.943e-03    9.619
## `country_regionSpain_Northern Spain`         6.269e-03  2.808e-03    2.233
## `country_regionSpain_Spain Other`            8.119e-02  1.675e-02    4.846
## `country_regionSpain_Spanish Islands`       -3.227e-02  2.386e-02   -1.352
## country_regionUS_Arizona                    -1.239e-02  3.611e-02   -0.343
## country_regionUS_California                 -8.751e-03  2.324e-03   -3.766
## country_regionUS_Colorado                    7.316e-03  1.694e-02    0.432
## country_regionUS_Connecticut                -1.495e-02  8.062e-02   -0.185
## country_regionUS_Idaho                       1.551e-01  2.247e-02    6.901
## country_regionUS_Iowa                       -7.319e-02  1.140e-01   -0.642
## country_regionUS_Kentucky                    6.041e-02  1.140e-01    0.530
## country_regionUS_Massachusetts              -5.961e-02  8.062e-02   -0.739
## country_regionUS_Michigan                   -4.291e-03  1.155e-02   -0.372
## country_regionUS_Missouri                   -2.642e-02  6.584e-02   -0.401
## country_regionUS_Nevada                     -3.246e-02  6.584e-02   -0.493
## `country_regionUS_New Jersey`               -2.395e-02  5.102e-02   -0.469
## `country_regionUS_New Mexico`               -1.721e-02  2.497e-02   -0.689
## `country_regionUS_New York`                 -4.634e-02  3.141e-03  -14.756
## `country_regionUS_North Carolina`           -4.951e-02  2.951e-02   -1.678
## country_regionUS_Ohio                       -1.498e-02  4.035e-02   -0.371
## country_regionUS_Oregon                     -2.781e-02  2.697e-03  -10.310
## country_regionUS_Pennsylvania               -3.886e-02  3.169e-02   -1.226
## country_regionUS_Texas                      -1.608e-02  1.361e-02   -1.181
## country_regionUS_Vermont                     1.457e-02  6.584e-02    0.221
## country_regionUS_Virginia                   -1.771e-02  6.515e-03   -2.718
## country_regionUS_Washington                 -1.504e-02  2.472e-03   -6.083
##                                             Pr(>|t|)    
## (Intercept)                                  < 2e-16 ***
## points_squared                               < 2e-16 ***
## price_per_point                              < 2e-16 ***
## price_per_year                               < 2e-16 ***
## points_price_ratio                           < 2e-16 ***
## is_expensive                                 < 2e-16 ***
## wine_age                                    3.46e-07 ***
## description_length                          0.195301    
## variety_typeRed                              < 2e-16 ***
## country_regionArgentina_Other               0.169017    
## `country_regionAustralia_Australia Other`    < 2e-16 ***
## `country_regionAustralia_New South Wales`   0.092646 .  
## `country_regionAustralia_South Australia`   1.32e-13 ***
## country_regionAustralia_Tasmania            0.588663    
## country_regionAustralia_Victoria            0.000666 ***
## `country_regionAustralia_Western Australia` 5.69e-07 ***
## `country_regionCanada_British Columbia`     6.67e-05 ***
## country_regionCanada_Ontario                0.352860    
## country_regionFrance_Alsace                  < 2e-16 ***
## country_regionFrance_Beaujolais              < 2e-16 ***
## country_regionFrance_Bordeaux               1.26e-12 ***
## country_regionFrance_Burgundy               3.33e-16 ***
## country_regionFrance_Champagne               < 2e-16 ***
## `country_regionFrance_France Other`         0.003781 ** 
## `country_regionFrance_Languedoc-Roussillon` 0.254188    
## `country_regionFrance_Loire Valley`          < 2e-16 ***
## country_regionFrance_Provence                < 2e-16 ***
## `country_regionFrance_Rhône Valley`         0.725396    
## `country_regionFrance_Southwest France`     1.20e-11 ***
## `country_regionItaly_Central Italy`         1.20e-06 ***
## `country_regionItaly_Italy Other`           0.611866    
## country_regionItaly_Lombardy                0.114291    
## `country_regionItaly_Northeastern Italy`    8.41e-15 ***
## `country_regionItaly_Northwestern Italy`    0.123751    
## country_regionItaly_Piedmont                8.42e-11 ***
## `country_regionItaly_Sicily & Sardinia`     5.43e-06 ***
## `country_regionItaly_Southern Italy`        4.65e-08 ***
## country_regionItaly_Tuscany                 0.356986    
## country_regionItaly_Veneto                  0.723593    
## country_regionSpain_Andalucia               0.002874 ** 
## country_regionSpain_Catalonia               0.001820 ** 
## `country_regionSpain_Central Spain`          < 2e-16 ***
## country_regionSpain_Galicia                  < 2e-16 ***
## country_regionSpain_Levante                  < 2e-16 ***
## `country_regionSpain_Northern Spain`        0.025557 *  
## `country_regionSpain_Spain Other`           1.27e-06 ***
## `country_regionSpain_Spanish Islands`       0.176293    
## country_regionUS_Arizona                    0.731536    
## country_regionUS_California                 0.000166 ***
## country_regionUS_Colorado                   0.665889    
## country_regionUS_Connecticut                0.852903    
## country_regionUS_Idaho                      5.20e-12 ***
## country_regionUS_Iowa                       0.520812    
## country_regionUS_Kentucky                   0.596187    
## country_regionUS_Massachusetts              0.459671    
## country_regionUS_Michigan                   0.710177    
## country_regionUS_Missouri                   0.688203    
## country_regionUS_Nevada                     0.621954    
## `country_regionUS_New Jersey`               0.638720    
## `country_regionUS_New Mexico`               0.490753    
## `country_regionUS_New York`                  < 2e-16 ***
## `country_regionUS_North Carolina`           0.093359 .  
## country_regionUS_Ohio                       0.710462    
## country_regionUS_Oregon                      < 2e-16 ***
## country_regionUS_Pennsylvania               0.220110    
## country_regionUS_Texas                      0.237501    
## country_regionUS_Vermont                    0.824830    
## country_regionUS_Virginia                   0.006570 ** 
## country_regionUS_Washington                 1.18e-09 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.114 on 71643 degrees of freedom
## Multiple R-squared:  0.9691, Adjusted R-squared:  0.9691 
## F-statistic: 3.305e+04 on 68 and 71643 DF,  p-value: < 2.2e-16
model$results
##   intercept      RMSE  Rsquared        MAE      RMSESD  RsquaredSD       MAESD
## 1      TRUE 0.1168612 0.9674893 0.07654025 0.009384021 0.005157647 0.002511029
predictions <- predict(model, newdata = wine_clean)
rmse <- sqrt(mean((predictions - wine_clean$log_price)^2))
print(paste("RMSE on the full dataset:", round(rmse, 2)))
## [1] "RMSE on the full dataset: 0.11"

Model Performance Summary

  • RMSE (Resampling): 0.11897 — Low, indicating good fit.
  • R-squared (Resampling): 0.9664 — Explains 96.64% of the variance, excellent!
  • MAE (Resampling): 0.0771 — Low error on average.
  • RMSE on Test Data: 0.1123 — Slightly lower than resampling, showing strong generalization.

Conclusion: The model performs well with minimal error, high R-squared, and good consistency across resampling iterations.

Variable Selection

importance <- varImp(model, scale = FALSE)
importance_df <- importance$importance
top_10_features <- importance_df %>% arrange(desc(Overall)) %>% head(10)

print(top_10_features)
##                                             Overall
## points_price_ratio                        678.84195
## is_expensive                              224.44340
## price_per_point                            84.02487
## points_squared                             81.19805
## variety_typeRed                            20.64278
## price_per_year                             17.12023
## `country_regionSpain_Central Spain`        15.82920
## `country_regionUS_New York`                14.75615
## `country_regionAustralia_Australia Other`  12.65365
## country_regionFrance_Alsace                12.27927
ggplot(top_10_features, aes(x = reorder(rownames(top_10_features), Overall), y = Overall)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  coord_flip() + 
  labs(title = "Top 10 Important Features", x = "Features", y = "Importance (Overall)") +
  theme_minimal()