Revenue Management a ML approach

Fernando Torres H.

07/09/2018


The Dataset

Predictors


Forecasting Luxury Hotels ADR

AutoArima

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(0,1,1)
## Q* = 5.1789, df = 9, p-value = 0.8184
## 
## Model df: 1.   Total lags used: 10


Manual Tunning Arima

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(0,1,2)
## Q* = 5.4877, df = 8, p-value = 0.7044
## 
## Model df: 2.   Total lags used: 10


Comparing Manual Tunning vs AutoArima


AutoArima

##                      ME     RMSE      MAE       MPE     MAPE      MASE
## Training set -0.9533837 4.246097 3.506598 -1.163669 3.723640 0.8370144
## Test set      2.8351020 2.908660 2.835102  3.122545 3.122545 0.6767303
##                    ACF1 Theil's U
## Training set -0.2249606        NA
## Test set     -0.5000000  1.680848


Manual Tunning

##                      ME     RMSE      MAE       MPE     MAPE      MASE
## Training set -0.9239521 4.187894 3.415028 -1.128631 3.626349 0.8151569
## Test set      3.1064190 3.208963 3.106419  3.420638 3.420638 0.7414929
##                     ACF1 Theil's U
## Training set -0.09791375        NA
## Test set     -0.50000000  1.770523



Forecast Night Sold


This model must be trained with the data of the hotel in analysis

library(parallel)

# Calculate the number of cores
no_cores <- detectCores() - 1

# Initiate cluster
cl <- makeCluster(no_cores, type="FORK")
## + Fold1: mtry=  2, min.node.size=5, splitrule=variance 
## - Fold1: mtry=  2, min.node.size=5, splitrule=variance 
## + Fold1: mtry= 13, min.node.size=5, splitrule=variance 
## - Fold1: mtry= 13, min.node.size=5, splitrule=variance 
## + Fold1: mtry= 25, min.node.size=5, splitrule=variance 
## - Fold1: mtry= 25, min.node.size=5, splitrule=variance 
## + Fold1: mtry= 37, min.node.size=5, splitrule=variance 
## - Fold1: mtry= 37, min.node.size=5, splitrule=variance 
## + Fold1: mtry= 48, min.node.size=5, splitrule=variance 
## - Fold1: mtry= 48, min.node.size=5, splitrule=variance 
## + Fold1: mtry= 60, min.node.size=5, splitrule=variance 
## - Fold1: mtry= 60, min.node.size=5, splitrule=variance 
## + Fold1: mtry= 72, min.node.size=5, splitrule=variance 
## - Fold1: mtry= 72, min.node.size=5, splitrule=variance 
## + Fold1: mtry= 83, min.node.size=5, splitrule=variance 
## - Fold1: mtry= 83, min.node.size=5, splitrule=variance 
## + Fold1: mtry= 95, min.node.size=5, splitrule=variance 
## - Fold1: mtry= 95, min.node.size=5, splitrule=variance 
## + Fold1: mtry=107, min.node.size=5, splitrule=variance 
## - Fold1: mtry=107, min.node.size=5, splitrule=variance 
## + Fold1: mtry=  2, min.node.size=5, splitrule=extratrees 
## - Fold1: mtry=  2, min.node.size=5, splitrule=extratrees 
## + Fold1: mtry= 13, min.node.size=5, splitrule=extratrees 
## - Fold1: mtry= 13, min.node.size=5, splitrule=extratrees 
## + Fold1: mtry= 25, min.node.size=5, splitrule=extratrees 
## - Fold1: mtry= 25, min.node.size=5, splitrule=extratrees 
## + Fold1: mtry= 37, min.node.size=5, splitrule=extratrees 
## - Fold1: mtry= 37, min.node.size=5, splitrule=extratrees 
## + Fold1: mtry= 48, min.node.size=5, splitrule=extratrees 
## - Fold1: mtry= 48, min.node.size=5, splitrule=extratrees 
## + Fold1: mtry= 60, min.node.size=5, splitrule=extratrees 
## - Fold1: mtry= 60, min.node.size=5, splitrule=extratrees 
## + Fold1: mtry= 72, min.node.size=5, splitrule=extratrees 
## - Fold1: mtry= 72, min.node.size=5, splitrule=extratrees 
## + Fold1: mtry= 83, min.node.size=5, splitrule=extratrees 
## - Fold1: mtry= 83, min.node.size=5, splitrule=extratrees 
## + Fold1: mtry= 95, min.node.size=5, splitrule=extratrees 
## - Fold1: mtry= 95, min.node.size=5, splitrule=extratrees 
## + Fold1: mtry=107, min.node.size=5, splitrule=extratrees 
## - Fold1: mtry=107, min.node.size=5, splitrule=extratrees 
## + Fold2: mtry=  2, min.node.size=5, splitrule=variance 
## - Fold2: mtry=  2, min.node.size=5, splitrule=variance 
## + Fold2: mtry= 13, min.node.size=5, splitrule=variance 
## - Fold2: mtry= 13, min.node.size=5, splitrule=variance 
## + Fold2: mtry= 25, min.node.size=5, splitrule=variance 
## - Fold2: mtry= 25, min.node.size=5, splitrule=variance 
## + Fold2: mtry= 37, min.node.size=5, splitrule=variance 
## - Fold2: mtry= 37, min.node.size=5, splitrule=variance 
## + Fold2: mtry= 48, min.node.size=5, splitrule=variance 
## - Fold2: mtry= 48, min.node.size=5, splitrule=variance 
## + Fold2: mtry= 60, min.node.size=5, splitrule=variance 
## - Fold2: mtry= 60, min.node.size=5, splitrule=variance 
## + Fold2: mtry= 72, min.node.size=5, splitrule=variance 
## - Fold2: mtry= 72, min.node.size=5, splitrule=variance 
## + Fold2: mtry= 83, min.node.size=5, splitrule=variance 
## - Fold2: mtry= 83, min.node.size=5, splitrule=variance 
## + Fold2: mtry= 95, min.node.size=5, splitrule=variance 
## - Fold2: mtry= 95, min.node.size=5, splitrule=variance 
## + Fold2: mtry=107, min.node.size=5, splitrule=variance 
## - Fold2: mtry=107, min.node.size=5, splitrule=variance 
## + Fold2: mtry=  2, min.node.size=5, splitrule=extratrees 
## - Fold2: mtry=  2, min.node.size=5, splitrule=extratrees 
## + Fold2: mtry= 13, min.node.size=5, splitrule=extratrees 
## - Fold2: mtry= 13, min.node.size=5, splitrule=extratrees 
## + Fold2: mtry= 25, min.node.size=5, splitrule=extratrees 
## - Fold2: mtry= 25, min.node.size=5, splitrule=extratrees 
## + Fold2: mtry= 37, min.node.size=5, splitrule=extratrees 
## - Fold2: mtry= 37, min.node.size=5, splitrule=extratrees 
## + Fold2: mtry= 48, min.node.size=5, splitrule=extratrees 
## - Fold2: mtry= 48, min.node.size=5, splitrule=extratrees 
## + Fold2: mtry= 60, min.node.size=5, splitrule=extratrees 
## - Fold2: mtry= 60, min.node.size=5, splitrule=extratrees 
## + Fold2: mtry= 72, min.node.size=5, splitrule=extratrees 
## - Fold2: mtry= 72, min.node.size=5, splitrule=extratrees 
## + Fold2: mtry= 83, min.node.size=5, splitrule=extratrees 
## - Fold2: mtry= 83, min.node.size=5, splitrule=extratrees 
## + Fold2: mtry= 95, min.node.size=5, splitrule=extratrees 
## - Fold2: mtry= 95, min.node.size=5, splitrule=extratrees 
## + Fold2: mtry=107, min.node.size=5, splitrule=extratrees 
## - Fold2: mtry=107, min.node.size=5, splitrule=extratrees 
## + Fold3: mtry=  2, min.node.size=5, splitrule=variance 
## - Fold3: mtry=  2, min.node.size=5, splitrule=variance 
## + Fold3: mtry= 13, min.node.size=5, splitrule=variance 
## - Fold3: mtry= 13, min.node.size=5, splitrule=variance 
## + Fold3: mtry= 25, min.node.size=5, splitrule=variance 
## - Fold3: mtry= 25, min.node.size=5, splitrule=variance 
## + Fold3: mtry= 37, min.node.size=5, splitrule=variance 
## - Fold3: mtry= 37, min.node.size=5, splitrule=variance 
## + Fold3: mtry= 48, min.node.size=5, splitrule=variance 
## - Fold3: mtry= 48, min.node.size=5, splitrule=variance 
## + Fold3: mtry= 60, min.node.size=5, splitrule=variance 
## - Fold3: mtry= 60, min.node.size=5, splitrule=variance 
## + Fold3: mtry= 72, min.node.size=5, splitrule=variance 
## - Fold3: mtry= 72, min.node.size=5, splitrule=variance 
## + Fold3: mtry= 83, min.node.size=5, splitrule=variance 
## - Fold3: mtry= 83, min.node.size=5, splitrule=variance 
## + Fold3: mtry= 95, min.node.size=5, splitrule=variance 
## - Fold3: mtry= 95, min.node.size=5, splitrule=variance 
## + Fold3: mtry=107, min.node.size=5, splitrule=variance 
## - Fold3: mtry=107, min.node.size=5, splitrule=variance 
## + Fold3: mtry=  2, min.node.size=5, splitrule=extratrees 
## - Fold3: mtry=  2, min.node.size=5, splitrule=extratrees 
## + Fold3: mtry= 13, min.node.size=5, splitrule=extratrees 
## - Fold3: mtry= 13, min.node.size=5, splitrule=extratrees 
## + Fold3: mtry= 25, min.node.size=5, splitrule=extratrees 
## - Fold3: mtry= 25, min.node.size=5, splitrule=extratrees 
## + Fold3: mtry= 37, min.node.size=5, splitrule=extratrees 
## - Fold3: mtry= 37, min.node.size=5, splitrule=extratrees 
## + Fold3: mtry= 48, min.node.size=5, splitrule=extratrees 
## - Fold3: mtry= 48, min.node.size=5, splitrule=extratrees 
## + Fold3: mtry= 60, min.node.size=5, splitrule=extratrees 
## - Fold3: mtry= 60, min.node.size=5, splitrule=extratrees 
## + Fold3: mtry= 72, min.node.size=5, splitrule=extratrees 
## - Fold3: mtry= 72, min.node.size=5, splitrule=extratrees 
## + Fold3: mtry= 83, min.node.size=5, splitrule=extratrees 
## - Fold3: mtry= 83, min.node.size=5, splitrule=extratrees 
## + Fold3: mtry= 95, min.node.size=5, splitrule=extratrees 
## - Fold3: mtry= 95, min.node.size=5, splitrule=extratrees 
## + Fold3: mtry=107, min.node.size=5, splitrule=extratrees 
## - Fold3: mtry=107, min.node.size=5, splitrule=extratrees 
## + Fold4: mtry=  2, min.node.size=5, splitrule=variance 
## - Fold4: mtry=  2, min.node.size=5, splitrule=variance 
## + Fold4: mtry= 13, min.node.size=5, splitrule=variance 
## - Fold4: mtry= 13, min.node.size=5, splitrule=variance 
## + Fold4: mtry= 25, min.node.size=5, splitrule=variance 
## - Fold4: mtry= 25, min.node.size=5, splitrule=variance 
## + Fold4: mtry= 37, min.node.size=5, splitrule=variance 
## - Fold4: mtry= 37, min.node.size=5, splitrule=variance 
## + Fold4: mtry= 48, min.node.size=5, splitrule=variance 
## - Fold4: mtry= 48, min.node.size=5, splitrule=variance 
## + Fold4: mtry= 60, min.node.size=5, splitrule=variance 
## - Fold4: mtry= 60, min.node.size=5, splitrule=variance 
## + Fold4: mtry= 72, min.node.size=5, splitrule=variance 
## - Fold4: mtry= 72, min.node.size=5, splitrule=variance 
## + Fold4: mtry= 83, min.node.size=5, splitrule=variance 
## - Fold4: mtry= 83, min.node.size=5, splitrule=variance 
## + Fold4: mtry= 95, min.node.size=5, splitrule=variance 
## - Fold4: mtry= 95, min.node.size=5, splitrule=variance 
## + Fold4: mtry=107, min.node.size=5, splitrule=variance 
## - Fold4: mtry=107, min.node.size=5, splitrule=variance 
## + Fold4: mtry=  2, min.node.size=5, splitrule=extratrees 
## - Fold4: mtry=  2, min.node.size=5, splitrule=extratrees 
## + Fold4: mtry= 13, min.node.size=5, splitrule=extratrees 
## - Fold4: mtry= 13, min.node.size=5, splitrule=extratrees 
## + Fold4: mtry= 25, min.node.size=5, splitrule=extratrees 
## - Fold4: mtry= 25, min.node.size=5, splitrule=extratrees 
## + Fold4: mtry= 37, min.node.size=5, splitrule=extratrees 
## - Fold4: mtry= 37, min.node.size=5, splitrule=extratrees 
## + Fold4: mtry= 48, min.node.size=5, splitrule=extratrees 
## - Fold4: mtry= 48, min.node.size=5, splitrule=extratrees 
## + Fold4: mtry= 60, min.node.size=5, splitrule=extratrees 
## - Fold4: mtry= 60, min.node.size=5, splitrule=extratrees 
## + Fold4: mtry= 72, min.node.size=5, splitrule=extratrees 
## - Fold4: mtry= 72, min.node.size=5, splitrule=extratrees 
## + Fold4: mtry= 83, min.node.size=5, splitrule=extratrees 
## - Fold4: mtry= 83, min.node.size=5, splitrule=extratrees 
## + Fold4: mtry= 95, min.node.size=5, splitrule=extratrees 
## - Fold4: mtry= 95, min.node.size=5, splitrule=extratrees 
## + Fold4: mtry=107, min.node.size=5, splitrule=extratrees 
## - Fold4: mtry=107, min.node.size=5, splitrule=extratrees 
## + Fold5: mtry=  2, min.node.size=5, splitrule=variance 
## - Fold5: mtry=  2, min.node.size=5, splitrule=variance 
## + Fold5: mtry= 13, min.node.size=5, splitrule=variance 
## - Fold5: mtry= 13, min.node.size=5, splitrule=variance 
## + Fold5: mtry= 25, min.node.size=5, splitrule=variance 
## - Fold5: mtry= 25, min.node.size=5, splitrule=variance 
## + Fold5: mtry= 37, min.node.size=5, splitrule=variance 
## - Fold5: mtry= 37, min.node.size=5, splitrule=variance 
## + Fold5: mtry= 48, min.node.size=5, splitrule=variance 
## - Fold5: mtry= 48, min.node.size=5, splitrule=variance 
## + Fold5: mtry= 60, min.node.size=5, splitrule=variance 
## - Fold5: mtry= 60, min.node.size=5, splitrule=variance 
## + Fold5: mtry= 72, min.node.size=5, splitrule=variance 
## - Fold5: mtry= 72, min.node.size=5, splitrule=variance 
## + Fold5: mtry= 83, min.node.size=5, splitrule=variance 
## - Fold5: mtry= 83, min.node.size=5, splitrule=variance 
## + Fold5: mtry= 95, min.node.size=5, splitrule=variance 
## - Fold5: mtry= 95, min.node.size=5, splitrule=variance 
## + Fold5: mtry=107, min.node.size=5, splitrule=variance 
## - Fold5: mtry=107, min.node.size=5, splitrule=variance 
## + Fold5: mtry=  2, min.node.size=5, splitrule=extratrees 
## - Fold5: mtry=  2, min.node.size=5, splitrule=extratrees 
## + Fold5: mtry= 13, min.node.size=5, splitrule=extratrees 
## - Fold5: mtry= 13, min.node.size=5, splitrule=extratrees 
## + Fold5: mtry= 25, min.node.size=5, splitrule=extratrees 
## - Fold5: mtry= 25, min.node.size=5, splitrule=extratrees 
## + Fold5: mtry= 37, min.node.size=5, splitrule=extratrees 
## - Fold5: mtry= 37, min.node.size=5, splitrule=extratrees 
## + Fold5: mtry= 48, min.node.size=5, splitrule=extratrees 
## - Fold5: mtry= 48, min.node.size=5, splitrule=extratrees 
## + Fold5: mtry= 60, min.node.size=5, splitrule=extratrees 
## - Fold5: mtry= 60, min.node.size=5, splitrule=extratrees 
## + Fold5: mtry= 72, min.node.size=5, splitrule=extratrees 
## - Fold5: mtry= 72, min.node.size=5, splitrule=extratrees 
## + Fold5: mtry= 83, min.node.size=5, splitrule=extratrees 
## - Fold5: mtry= 83, min.node.size=5, splitrule=extratrees 
## + Fold5: mtry= 95, min.node.size=5, splitrule=extratrees 
## - Fold5: mtry= 95, min.node.size=5, splitrule=extratrees 
## + Fold5: mtry=107, min.node.size=5, splitrule=extratrees 
## - Fold5: mtry=107, min.node.size=5, splitrule=extratrees 
## Aggregating results
## Selecting tuning parameters
## Fitting mtry = 2, splitrule = variance, min.node.size = 5 on full training set
# Stop parallel computing
stopCluster(cl)
## ranger variable importance
## 
##   only 20 most important variables shown (out of 107)
## 
##                  Overall
## Wholeyear_week49  100.00
## National_ADR_Lux   99.60
## Weekendyes         90.64
## ADR_Mercado        66.91
## Month05            50.63
## Wholeyear_week21   44.24
## Wholeyear_week52   41.21
## Month02            40.72
## Month06            39.94
## Month12            36.07
## Wholeyear_week15   34.65
## Month10            34.26
## Holidayyes         33.77
## Wholeyear_week19   32.71
## Wholeyear_week26   30.66
## Wholeyear_week08   28.86
## GoodWeatheryes     26.90
## Wholeyear_week03   25.99
## Wholeyear_week34   25.98
## Wholeyear_week18   24.95
##       RMSE    Rsquared      MAE Resample
## 1 1.719262 0.009438843 1.411568    Fold1
## 2 1.691215 0.031882053 1.398527    Fold3
## 3 1.678387 0.056666844 1.384714    Fold5
## 4 1.694757 0.023463762 1.412371    Fold2
## 5 1.698751 0.027569647 1.405008    Fold4


Forecast Rooms’ Desired Occupation

## + Fold1: mtry=  2 
## - Fold1: mtry=  2 
## + Fold1: mtry= 55 
## - Fold1: mtry= 55 
## + Fold1: mtry=108 
## - Fold1: mtry=108 
## + Fold2: mtry=  2 
## - Fold2: mtry=  2 
## + Fold2: mtry= 55 
## - Fold2: mtry= 55 
## + Fold2: mtry=108 
## - Fold2: mtry=108 
## + Fold3: mtry=  2 
## - Fold3: mtry=  2 
## + Fold3: mtry= 55 
## - Fold3: mtry= 55 
## + Fold3: mtry=108 
## - Fold3: mtry=108 
## + Fold4: mtry=  2 
## - Fold4: mtry=  2 
## + Fold4: mtry= 55 
## - Fold4: mtry= 55 
## + Fold4: mtry=108 
## - Fold4: mtry=108 
## + Fold5: mtry=  2 
## - Fold5: mtry=  2 
## + Fold5: mtry= 55 
## - Fold5: mtry= 55 
## + Fold5: mtry=108 
## - Fold5: mtry=108 
## Aggregating results
## Selecting tuning parameters
## Fitting mtry = 55 on full training set
##         ROC      Sens      Spec Resample
## 1 0.8684702 0.8638961 0.7112676    Fold1
## 2 0.8637218 0.8894081 0.6028202    Fold3
## 3 0.8695320 0.8707165 0.6839013    Fold2
## 4 0.8702965 0.8872727 0.6486486    Fold5
## 5 0.8649469 0.8712357 0.6568743    Fold4
## rf variable importance
## 
##   only 20 most important variables shown (out of 108)
## 
##                      Overall
## ADR                  100.000
## HotelEspana           76.538
## ADR_Mercado           65.146
## National_ADR_Lux      40.057
## HotelGalapagosSuites  36.385
## HotelCucuve           19.788
## HotelLaZayapa          7.149
## Weekendyes             6.977
## Month08                6.343
## GoodWeatheryes         4.572
## Wholeyear_week52       3.408
## Wholeyear_week29       3.294
## Date10                 3.280
## Holidayyes             3.128
## Date3                  2.915
## Date18                 2.890
## Date2                  2.876
## Month07                2.875
## Date7                  2.867
## Wholeyear_week28       2.780
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  No Yes
##        No  885 102
##        Yes 146 354
##                                           
##                Accuracy : 0.8332          
##                  95% CI : (0.8133, 0.8518)
##     No Information Rate : 0.6933          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.6181          
##  Mcnemar's Test P-Value : 0.006324        
##                                           
##             Sensitivity : 0.8584          
##             Specificity : 0.7763          
##          Pos Pred Value : 0.8967          
##          Neg Pred Value : 0.7080          
##              Prevalence : 0.6933          
##          Detection Rate : 0.5952          
##    Detection Prevalence : 0.6638          
##       Balanced Accuracy : 0.8174          
##                                           
##        'Positive' Class : No              
## 


Visualisations