To understand the factors that influence the use of cars as a mode of transport and to that best explains the employee’s decision to use cars as the main means of transport
Read the data and understand the structure
library(caret)
## Loading required package: lattice
## Loading required package: ggplot2
library(car)
## Loading required package: carData
library(DMwR)
## Loading required package: grid
carsbasedata<-read.csv("C:\\Users\\acer\\Documents\\PGPBABI\\Machine Learning\\GA\\cars.csv", header = TRUE)
str(carsbasedata)
## 'data.frame': 444 obs. of 9 variables:
## $ Age : int 28 23 29 28 27 26 28 26 22 27 ...
## $ Gender : Factor w/ 2 levels "Female","Male": 2 1 2 1 2 2 2 1 2 2 ...
## $ Engineer : int 0 1 1 1 1 1 1 1 1 1 ...
## $ MBA : int 0 0 0 1 0 0 0 0 0 0 ...
## $ Work.Exp : int 4 4 7 5 4 4 5 3 1 4 ...
## $ Salary : num 14.3 8.3 13.4 13.4 13.4 12.3 14.4 10.5 7.5 13.5 ...
## $ Distance : num 3.2 3.3 4.1 4.5 4.6 4.8 5.1 5.1 5.1 5.2 ...
## $ license : int 0 0 0 0 0 1 0 0 0 0 ...
## $ Transport: Factor w/ 3 levels "2Wheeler","Car",..: 3 3 3 3 3 3 1 3 3 3 ...
## The columns Engineer,MBA and license need to be converted into factors
carsbasedata$Engineer<-as.factor(carsbasedata$Engineer)
carsbasedata$MBA<-as.factor(carsbasedata$MBA)
carsbasedata$license<-as.factor(carsbasedata$license)
carsbasedata<-knnImputation(carsbasedata)
Our primary interest as per problem statement is to understand the factors influencing car usage. Hence we will create a nwe column for Car usage. It will take value 0 for Public Transport & 2 Wheeler and 1 for car usage ## Understand the proprotion of cars in Transport Mode
carsbasedata$CarUsage<-ifelse(carsbasedata$Transport =='Car',1,0)
table(carsbasedata$CarUsage)
##
## 0 1
## 383 61
sum(carsbasedata$CarUsage == 1)/nrow(carsbasedata)
## [1] 0.1373874
carsbasedata$CarUsage<-as.factor(carsbasedata$CarUsage)
The number of records for people travelling by car is in minority. Hence we need to use an appropriate sampling method on the train data. We will explore using SMOTE We will use logistic regression, decision trees to see the best fit model and also explore a couple of blackbox models for prediction later on ## Balancing the data
##Split the data into test and train
set.seed(400)
carindex<-createDataPartition(carsbasedata$CarUsage, p=0.7,list = FALSE,times = 1)
carsdatatrain<-carsbasedata[carindex,]
carsdatatest<-carsbasedata[-carindex,]
prop.table(table(carsdatatrain$CarUsage))
##
## 0 1
## 0.8621795 0.1378205
prop.table(table(carsdatatest$CarUsage))
##
## 0 1
## 0.8636364 0.1363636
carsdatatrain<-carsdatatrain[,c(1:8,10)]
carsdatatest<-carsdatatest[,c(1:8,10)]
## The train and test data have almost same percentage of cars usage as the base data
## Apply SMOTE on Training data set
library(DMwR)
attach(carsdatatrain)
carsdataSMOTE<-SMOTE(CarUsage~., carsdatatrain, perc.over = 250,perc.under = 150)
prop.table(table(carsdataSMOTE$CarUsage))
##
## 0 1
## 0.5 0.5
We now have an equal split in the data between car users and non car users. Let us proceed with building the models ## Model Building We will use the Logistic regression method a model on the SMOTE data to understand the factors influencing car usage. Since we have only limited variable, we will use them all in model building
##Create control parameter for GLM
outcomevar<-'CarUsage'
regressors<-c("Age","Work.Exp","Salary","Distance","license","Engineer","MBA","Gender")
trainctrl<-trainControl(method = 'repeatedcv',number = 10,repeats = 3)
carsglm<-train(carsdataSMOTE[,regressors],carsdataSMOTE[,outcomevar],method = "glm", family = "binomial",trControl = trainctrl)
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: algorithm did not converge
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: algorithm did not converge
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: algorithm did not converge
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
summary(carsglm$finalModel)
##
## Call:
## NULL
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -2.98326 -0.00024 0.00000 0.00000 1.11801
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -118.62275 51.84138 -2.288 0.0221 *
## Age 3.69904 1.69960 2.176 0.0295 *
## Work.Exp -1.20774 0.89958 -1.343 0.1794
## Salary 0.96031 0.72224 1.330 0.1836
## Distance -0.04112 0.32873 -0.125 0.9005
## license1 4.44597 2.89203 1.537 0.1242
## Engineer1 -0.72971 2.98679 -0.244 0.8070
## MBA1 -1.05817 1.70158 -0.622 0.5340
## GenderMale -3.03060 2.10593 -1.439 0.1501
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 357.664 on 257 degrees of freedom
## Residual deviance: 17.959 on 249 degrees of freedom
## AIC: 35.959
##
## Number of Fisher Scoring iterations: 12
carglmcoeff<-exp(coef(carsglm$finalModel))
write.csv(carglmcoeff,file = "Coeffs.csv")
varImp(object = carsglm)
## glm variable importance
##
## Overall
## Age 100.000
## license1 68.845
## GenderMale 64.056
## Work.Exp 59.351
## Salary 58.720
## MBA1 24.219
## Engineer1 5.813
## Distance 0.000
plot(varImp(object = carsglm), main="Vairable Importance for Logistic Regression")
## Model Interpretation
From the model we see that Age and License are more significant. When we look at the odds and probabilities table, we get to see that Increase in age by 1 year implies that thre is a 98% probability that the employee will use a car. As expected , if the employee has a license, then it implies a 99% probability that he/she will use a car. One lkah increase in salary increases the probability of car usage by 72% The null deviance of this model is 357.664 and the residual deviance is 17.959. This yields a McFadden R Sqaure o almost 0.94 yielding a very good fit. We get to see Accuracy and Kappa values are high We shall do the prediction based on this model
carusageprediction<-predict.train(object = carsglm,carsdatatest[,regressors],type = "raw")
confusionMatrix(carusageprediction,carsdatatest[,outcomevar], positive='1')
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 108 1
## 1 6 17
##
## Accuracy : 0.947
## 95% CI : (0.8938, 0.9784)
## No Information Rate : 0.8636
## P-Value [Acc > NIR] : 0.001692
##
## Kappa : 0.7984
## Mcnemar's Test P-Value : 0.130570
##
## Sensitivity : 0.9444
## Specificity : 0.9474
## Pos Pred Value : 0.7391
## Neg Pred Value : 0.9908
## Prevalence : 0.1364
## Detection Rate : 0.1288
## Detection Prevalence : 0.1742
## Balanced Accuracy : 0.9459
##
## 'Positive' Class : 1
##
carusagepreddata<-carsdatatest
carusagepreddata$predictusage<-carusageprediction
We see that the accuracy of prediction is 95% with almost all non users gettng predicted accurately. We have a 94% accuracy in predicting the car users.
Let us perform the prediction for the two given cases
carunknown<-read.csv("cars2.csv", header = TRUE)
carunknown$license<-as.factor(carunknown$license)
carunknown$Engineer<-as.factor(carunknown$Engineer)
carunknown$MBA<-as.factor(carunknown$MBA)
carunknown$predictcaruse<-predict.train(object = carsglm,carunknown[,regressors],type = "raw")
print(carunknown)
## Age Gender Engineer MBA Work.Exp Salary Distance license predictcaruse
## 1 25 Male 0 0 2 10 5 1 0
## 2 25 Female 1 0 2 10 5 0 0
As seen, the model has predicted that both the new rows are predicted to be not car users
Let us now try using glmnet method of caret package to try and run ridge Regression Model
trainctrlgn<-trainControl(method = 'cv',number = 10,returnResamp = 'none')
carsglmnet<-train(CarUsage~Age+Work.Exp+Salary+Distance+license, data = carsdataSMOTE, method = 'glmnet', trControl = trainctrlgn)
carsglmnet
## glmnet
##
## 258 samples
## 5 predictor
## 2 classes: '0', '1'
##
## No pre-processing
## Resampling: Cross-Validated (10 fold)
## Summary of sample sizes: 232, 232, 232, 232, 232, 232, ...
## Resampling results across tuning parameters:
##
## alpha lambda Accuracy Kappa
## 0.10 0.0008540753 0.9807692 0.9615385
## 0.10 0.0085407532 0.9730769 0.9461538
## 0.10 0.0854075320 0.9575385 0.9150897
## 0.55 0.0008540753 0.9807692 0.9615385
## 0.55 0.0085407532 0.9769231 0.9538462
## 0.55 0.0854075320 0.9536923 0.9073974
## 1.00 0.0008540753 0.9846154 0.9692308
## 1.00 0.0085407532 0.9846154 0.9692308
## 1.00 0.0854075320 0.9730769 0.9461538
##
## Accuracy was used to select the optimal model using the largest value.
## The final values used for the model were alpha = 1 and lambda
## = 0.008540753.
varImp(object = carsglmnet)
## glmnet variable importance
##
## Overall
## license1 100.000
## Age 99.068
## Distance 21.095
## Salary 8.684
## Work.Exp 0.000
plot(varImp(object = carsglmnet), main="Vairable Importance for Logistic Regression - Post Ridge Regularization")
We get license and Age as the most significant variables, followed by the distance in the improtance of variables. Let us try prediction using the regularized model
carusagepredictiong<-predict.train(object = carsglmnet,carsdatatest[,regressors],type = "raw")
confusionMatrix(carusagepredictiong,carsdatatest[,outcomevar], positive='1')
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 109 2
## 1 5 16
##
## Accuracy : 0.947
## 95% CI : (0.8938, 0.9784)
## No Information Rate : 0.8636
## P-Value [Acc > NIR] : 0.001692
##
## Kappa : 0.7896
## Mcnemar's Test P-Value : 0.449692
##
## Sensitivity : 0.8889
## Specificity : 0.9561
## Pos Pred Value : 0.7619
## Neg Pred Value : 0.9820
## Prevalence : 0.1364
## Detection Rate : 0.1212
## Detection Prevalence : 0.1591
## Balanced Accuracy : 0.9225
##
## 'Positive' Class : 1
##
## Let us predict for unknown cases
carunknown$predictcarusegn<-predict.train(object = carsglmnet,carunknown[,regressors],type = "raw")
print(carunknown)
## Age Gender Engineer MBA Work.Exp Salary Distance license predictcaruse
## 1 25 Male 0 0 2 10 5 1 0
## 2 25 Female 1 0 2 10 5 0 0
## predictcarusegn
## 1 0
## 2 0
We see that the accuracy of prediction is 94.7% with almost all non users gettng predicted accurately. However we have a 88% accuracy in predicting the car users, slightly lower than the regular GLM model. The unknown cases are also predicted as not car users
Though the problem sgtatement is to more predominantly look at the factors influencing car usage, the dataset given is a good case for a linear discriminant analysis to understand the factors driving the choice of transportaion mode.
##Split the original base data into test and train samples again
carsbasedatalda<-read.csv("cars.csv", header = TRUE)
carsbasedatalda$Gender<-as.factor(carsbasedatalda$Gender)
carsbasedatalda$Engineer<-as.factor(carsbasedatalda$Engineer)
carsbasedatalda$MBA<-as.factor(carsbasedatalda$MBA)
carsbasedatalda<-knnImputation(carsbasedatalda)
set.seed(400)
carindexlda<-createDataPartition(carsbasedatalda$Transport, p=0.7,list = FALSE,times = 1)
carstrainlda<-carsbasedatalda[carindexlda,]
carstestlda<-carsbasedatalda[-carindexlda,]
carstrainlda$license<-as.factor(carstrainlda$license)
carstestlda$license<-as.factor(carstestlda$license)
cartrainlda.car<-carstrainlda[carstrainlda$Transport %in% c("Car", "Public Transport"),]
cartrainlda.twlr<-carstrainlda[carstrainlda$Transport %in% c("2Wheeler", "Public Transport"),]
cartrainlda.car$Transport<-as.character(cartrainlda.car$Transport)
cartrainlda.car$Transport<-as.factor(cartrainlda.car$Transport)
cartrainlda.twlr$Transport<-as.character(cartrainlda.twlr$Transport)
cartrainlda.twlr$Transport<-as.factor(cartrainlda.twlr$Transport)
prop.table(table(cartrainlda.car$Transport))
##
## Car Public Transport
## 0.1699605 0.8300395
prop.table(table(cartrainlda.twlr$Transport))
##
## 2Wheeler Public Transport
## 0.2193309 0.7806691
carldatwlrsm <- SMOTE(Transport~., data = cartrainlda.twlr, perc.over = 150, perc.under=200)
table(carldatwlrsm$Transport)
##
## 2Wheeler Public Transport
## 118 118
carldacarsm <- SMOTE(Transport~., data = cartrainlda.car, perc.over = 175, perc.under=200)
table(carldacarsm$Transport)
##
## Car Public Transport
## 86 86
carldacar<-carldacarsm[carldacarsm$Transport %in% c("Car"),]
carsdatatrainldasm<-rbind(carldatwlrsm,carldacar)
str(carsdatatrainldasm)
## 'data.frame': 322 obs. of 9 variables:
## $ Age : num 24 27 24 29 26 23 27 25 26 26 ...
## $ Gender : Factor w/ 2 levels "Female","Male": 2 2 2 2 2 2 1 2 1 1 ...
## $ Engineer : Factor w/ 2 levels "0","1": 2 1 1 2 2 2 2 1 2 2 ...
## $ MBA : Factor w/ 2 levels "0","1": 1 1 2 2 1 1 1 1 1 2 ...
## $ Work.Exp : num 4 5 2 6 4 2 3 3 6 4 ...
## $ Salary : num 10.9 13.8 8.5 14.6 12.7 8.5 10.7 9.9 17.8 12.8 ...
## $ Distance : num 9 15.2 8.5 10.2 9 6.1 11.7 15.9 10.4 10.8 ...
## $ license : Factor w/ 2 levels "0","1": 1 1 2 2 2 1 1 1 1 1 ...
## $ Transport: Factor w/ 3 levels "2Wheeler","Public Transport",..: 2 2 2 2 2 2 2 2 2 2 ...
table(carsdatatrainldasm$Transport)
##
## 2Wheeler Public Transport Car
## 118 118 86
## Build the model
attach(carsdatatrainldasm)
## The following objects are masked from carsdatatrain:
##
## Age, Distance, Engineer, Gender, license, MBA, Salary,
## Work.Exp
trainctrllda<-trainControl(method = 'cv',number = 10)
carslda<-train(Transport~Age+Work.Exp+Salary+Distance+license+Gender+Engineer+MBA ,data = carsdatatrainldasm, method="lda", trControl=trainctrllda)
carslda$finalModel
## Call:
## lda(x, grouping = y)
##
## Prior probabilities of groups:
## 2Wheeler Public Transport Car
## 0.3664596 0.3664596 0.2670807
##
## Group means:
## Age Work.Exp Salary Distance license1 GenderMale
## 2Wheeler 25.25983 3.726144 12.36309 12.23362 0.2627119 0.5000000
## Public Transport 26.55085 4.983051 13.51864 10.68729 0.1440678 0.6949153
## Car 35.75833 15.854594 36.15677 15.59036 0.7093023 0.7093023
## Engineer1 MBA1
## 2Wheeler 0.6949153 0.2542373
## Public Transport 0.6864407 0.2796610
## Car 0.8488372 0.2558140
##
## Coefficients of linear discriminants:
## LD1 LD2
## Age 0.210574627 -0.1462080
## Work.Exp 0.081188593 -0.0836168
## Salary 0.007534406 0.0476583
## Distance 0.074968787 0.1906158
## license1 0.416869466 1.2676211
## GenderMale -0.186709183 -1.0865173
## Engineer1 0.150855710 0.1757128
## MBA1 -0.072490532 -0.1201606
##
## Proportion of trace:
## LD1 LD2
## 0.9477 0.0523
plot(varImp(object = carslda),main="Variable Importance for Linear Discriminant Analysis" )
As per the out put, the first discriminant function achieves 90% separation and as per that Age, Work Experience and Salary play an important part in the choice of transport, followed by Distance and License
carsldapredict<-predict.train(object = carslda,newdata = carstestlda)
confusionMatrix(carsldapredict,carstestlda[,9])
## Warning in confusionMatrix.default(carsldapredict, carstestlda[, 9]):
## Levels are not in the same order for reference and data. Refactoring data
## to match.
## Confusion Matrix and Statistics
##
## Reference
## Prediction 2Wheeler Car Public Transport
## 2Wheeler 15 0 12
## Car 1 14 1
## Public Transport 8 4 77
##
## Overall Statistics
##
## Accuracy : 0.803
## 95% CI : (0.7249, 0.8671)
## No Information Rate : 0.6818
## P-Value [Acc > NIR] : 0.001323
##
## Kappa : 0.5952
## Mcnemar's Test P-Value : 0.308022
##
## Statistics by Class:
##
## Class: 2Wheeler Class: Car Class: Public Transport
## Sensitivity 0.6250 0.7778 0.8556
## Specificity 0.8889 0.9825 0.7143
## Pos Pred Value 0.5556 0.8750 0.8652
## Neg Pred Value 0.9143 0.9655 0.6977
## Prevalence 0.1818 0.1364 0.6818
## Detection Rate 0.1136 0.1061 0.5833
## Detection Prevalence 0.2045 0.1212 0.6742
## Balanced Accuracy 0.7569 0.8801 0.7849
The overall accuracy is 78% with a prediction of cars usage at 83% Let us understand the transportaion choice of two unknown cases
predictTransportuk<-predict.train(object = carslda,newdata = carunknown)
carunknown$predictTransport<-predictTransportuk
print(carunknown)
## Age Gender Engineer MBA Work.Exp Salary Distance license predictcaruse
## 1 25 Male 0 0 2 10 5 1 0
## 2 25 Female 1 0 2 10 5 0 0
## predictcarusegn predictTransport
## 1 0 Public Transport
## 2 0 Public Transport
As per the prediction by LDA, both employees will take public transport as a means of transporation
Let us try and run penalised LDA for the model above
trainctrlpda<-trainControl(method = 'cv',number = 10, returnResamp = 'all')
carspda<-train(Transport~Age+Work.Exp+Salary+Distance+license+Gender+Engineer+MBA ,data = carsdatatrainldasm, method="pda", trControl=trainctrlpda)
carspda$finalModel
## Call:
## mda::fda(formula = as.formula(".outcome ~ ."), data = dat, method = mda::gen.ridge,
## lambda = param$lambda)
##
## Dimension: 2
##
## Percent Between-Group Variance Explained:
## v1 v2
## 94.77 100.00
##
## Degrees of Freedom (per dimension): 7.992829
##
## Training Misclassification Error: 0.28882 ( N = 322 )
carspda
## Penalized Discriminant Analysis
##
## 322 samples
## 8 predictor
## 3 classes: '2Wheeler', 'Public Transport', 'Car'
##
## No pre-processing
## Resampling: Cross-Validated (10 fold)
## Summary of sample sizes: 289, 290, 290, 290, 290, 290, ...
## Resampling results across tuning parameters:
##
## lambda Accuracy Kappa
## 0e+00 0.6977548 0.5410021
## 1e-04 0.6977548 0.5410021
## 1e-01 0.7007851 0.5457593
##
## Accuracy was used to select the optimal model using the largest value.
## The final value used for the model was lambda = 0.1.
plot(varImp(object = carspda), main="Variable Importance for Penalized Discriminant Analysis")
Variable importance under penalised discriminant analysis is the same as LDA
carspdapredict<-predict.train(object = carspda,newdata = carstestlda)
confusionMatrix(carspdapredict,carstestlda[,9])
## Warning in confusionMatrix.default(carspdapredict, carstestlda[, 9]):
## Levels are not in the same order for reference and data. Refactoring data
## to match.
## Confusion Matrix and Statistics
##
## Reference
## Prediction 2Wheeler Car Public Transport
## 2Wheeler 15 0 12
## Car 1 14 1
## Public Transport 8 4 77
##
## Overall Statistics
##
## Accuracy : 0.803
## 95% CI : (0.7249, 0.8671)
## No Information Rate : 0.6818
## P-Value [Acc > NIR] : 0.001323
##
## Kappa : 0.5952
## Mcnemar's Test P-Value : 0.308022
##
## Statistics by Class:
##
## Class: 2Wheeler Class: Car Class: Public Transport
## Sensitivity 0.6250 0.7778 0.8556
## Specificity 0.8889 0.9825 0.7143
## Pos Pred Value 0.5556 0.8750 0.8652
## Neg Pred Value 0.9143 0.9655 0.6977
## Prevalence 0.1818 0.1364 0.6818
## Detection Rate 0.1136 0.1061 0.5833
## Detection Prevalence 0.2045 0.1212 0.6742
## Balanced Accuracy 0.7569 0.8801 0.7849
The result is very similar to LDA. Let us predict the 2 unknown cases
predictTransportuk1<-predict.train(object = carslda,newdata = carunknown)
carunknown$predictTransportpda<-predictTransportuk1
print(carunknown)
## Age Gender Engineer MBA Work.Exp Salary Distance license predictcaruse
## 1 25 Male 0 0 2 10 5 1 0
## 2 25 Female 1 0 2 10 5 0 0
## predictcarusegn predictTransport predictTransportpda
## 1 0 Public Transport Public Transport
## 2 0 Public Transport Public Transport
As per the prediction by LDA, both employees will take public transport as a means of transporation. The cases are precited to be choosing Public Transport.
Let us try a descision tree method , CART to infer and understand from the dataset
carscart<-train(Transport~.,carsdatatrainldasm,method = 'rpart', trControl = trainControl(method = 'cv',number = 5,savePredictions = 'final'))
carscart$finalModel
## n= 322
##
## node), split, n, loss, yval, (yprob)
## * denotes terminal node
##
## 1) root 322 204 2Wheeler (0.366459627 0.366459627 0.267080745)
## 2) Age< 30.02888 228 111 2Wheeler (0.513157895 0.482456140 0.004385965)
## 4) Distance>=10.90546 127 44 2Wheeler (0.653543307 0.338582677 0.007874016) *
## 5) Distance< 10.90546 101 34 Public Transport (0.336633663 0.663366337 0.000000000) *
## 3) Age>=30.02888 94 9 Car (0.010638298 0.085106383 0.904255319) *
library(rattle)
## Rattle: A free graphical interface for data science with R.
## Version 5.1.0 Copyright (c) 2006-2017 Togaware Pty Ltd.
## Type 'rattle()' to shake, rattle, and roll your data.
fancyRpartPlot(carscart$finalModel)
Age and distance are the major variables based on which CART has done the split Let us predict the accuracy of the model in test data
predictions_CART<-predict(carscart,carstestlda)
confusionMatrix(predictions_CART,carstestlda$Transport)
## Warning in confusionMatrix.default(predictions_CART, carstestlda
## $Transport): Levels are not in the same order for reference and data.
## Refactoring data to match.
## Confusion Matrix and Statistics
##
## Reference
## Prediction 2Wheeler Car Public Transport
## 2Wheeler 15 0 31
## Car 1 17 5
## Public Transport 8 1 54
##
## Overall Statistics
##
## Accuracy : 0.6515
## 95% CI : (0.5637, 0.7323)
## No Information Rate : 0.6818
## P-Value [Acc > NIR] : 0.8007180
##
## Kappa : 0.4068
## Mcnemar's Test P-Value : 0.0006336
##
## Statistics by Class:
##
## Class: 2Wheeler Class: Car Class: Public Transport
## Sensitivity 0.6250 0.9444 0.6000
## Specificity 0.7130 0.9474 0.7857
## Pos Pred Value 0.3261 0.7391 0.8571
## Neg Pred Value 0.8953 0.9908 0.4783
## Prevalence 0.1818 0.1364 0.6818
## Detection Rate 0.1136 0.1288 0.4091
## Detection Prevalence 0.3485 0.1742 0.4773
## Balanced Accuracy 0.6690 0.9459 0.6929
We get an overall accuracy of 55% with car usage getting predicted at 88% accuracy Let us predict for the unknown cases
predictTransportuk2<-predict.train(object = carscart,newdata = carunknown)
carunknown$predictTransportcart<-predictTransportuk2
print(carunknown)
## Age Gender Engineer MBA Work.Exp Salary Distance license predictcaruse
## 1 25 Male 0 0 2 10 5 1 0
## 2 25 Female 1 0 2 10 5 0 0
## predictcarusegn predictTransport predictTransportpda
## 1 0 Public Transport Public Transport
## 2 0 Public Transport Public Transport
## predictTransportcart
## 1 Public Transport
## 2 Public Transport
CART model also predicts the transport mode as Public Transport for the 2 cases
boostcontrol <- trainControl(number=10)
xgbGrid <- expand.grid(
eta = 0.3,
max_depth = 1,
nrounds = 50,
gamma = 0,
colsample_bytree = 0.6,
min_child_weight = 1, subsample = 1
)
carsxgb <- train(Transport ~ .,carsdatatrainldasm,trControl = boostcontrol,tuneGrid = xgbGrid,metric = "Accuracy",method = "xgbTree")
carsxgb$finalModel
## ##### xgb.Booster
## raw: 38.5 Kb
## call:
## xgboost::xgb.train(params = list(eta = param$eta, max_depth = param$max_depth,
## gamma = param$gamma, colsample_bytree = param$colsample_bytree,
## min_child_weight = param$min_child_weight, subsample = param$subsample),
## data = x, nrounds = param$nrounds, num_class = length(lev),
## objective = "multi:softprob")
## params (as set within xgb.train):
## eta = "0.3", max_depth = "1", gamma = "0", colsample_bytree = "0.6", min_child_weight = "1", subsample = "1", num_class = "3", objective = "multi:softprob", silent = "1"
## xgb.attributes:
## niter
## callbacks:
## cb.print.evaluation(period = print_every_n)
## niter: 50
## xNames: AgeGenderMaleEngineer1MBA1Work.ExpSalaryDistancelicense1
## problemType: Classification
## tuneValue:
## nrounds max_depth eta gamma colsample_bytree min_child_weight subsample
## 1 50 1 0.3 0 0.6 1 1
## obsLevels: 2WheelerPublic TransportCar
## param:
## list()
Let us predict using the test dataset
predictions_xgb<-predict(carsxgb,carstestlda)
confusionMatrix(predictions_xgb,carstestlda$Transport)
## Warning in confusionMatrix.default(predictions_xgb, carstestlda$Transport):
## Levels are not in the same order for reference and data. Refactoring data
## to match.
## Confusion Matrix and Statistics
##
## Reference
## Prediction 2Wheeler Car Public Transport
## 2Wheeler 15 0 18
## Car 1 17 1
## Public Transport 8 1 71
##
## Overall Statistics
##
## Accuracy : 0.7803
## 95% CI : (0.7, 0.8477)
## No Information Rate : 0.6818
## P-Value [Acc > NIR] : 0.00823
##
## Kappa : 0.5789
## Mcnemar's Test P-Value : 0.18342
##
## Statistics by Class:
##
## Class: 2Wheeler Class: Car Class: Public Transport
## Sensitivity 0.6250 0.9444 0.7889
## Specificity 0.8333 0.9825 0.7857
## Pos Pred Value 0.4545 0.8947 0.8875
## Neg Pred Value 0.9091 0.9912 0.6346
## Prevalence 0.1818 0.1364 0.6818
## Detection Rate 0.1136 0.1288 0.5379
## Detection Prevalence 0.2500 0.1439 0.6061
## Balanced Accuracy 0.7292 0.9635 0.7873
The overall accuracy is at 73% with accuracy of car usage predicted at 88% Let us try and predict for the two unknown cases
predictTransportuk3<-predict.train(object = carsxgb,newdata = carunknown)
carunknown$predictTransportxgb<-predictTransportuk3
print(carunknown)
## Age Gender Engineer MBA Work.Exp Salary Distance license predictcaruse
## 1 25 Male 0 0 2 10 5 1 0
## 2 25 Female 1 0 2 10 5 0 0
## predictcarusegn predictTransport predictTransportpda
## 1 0 Public Transport Public Transport
## 2 0 Public Transport Public Transport
## predictTransportcart predictTransportxgb
## 1 Public Transport 2Wheeler
## 2 Public Transport 2Wheeler
Interestingly, XgB model has predicted the case with Male, license yes and distance as 5 KM to beusing 2 Wheeler as a mode of transport and the other case to be using Public Transport
We will now use multinomial logistic regression to understand the factors driving transport mode choice. In this, the data is relevelled with respect to one of the three classes and 2 independent Logistic regression models are run. In our case, 2-Wheeler class is taken as the reference class.
carsmlr<-train(Transport ~.,carsdatatrainldasm,method = "multinom")
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 237.192746
## iter 20 value 184.556974
## iter 30 value 169.855050
## iter 40 value 169.455498
## iter 50 value 169.455170
## final value 169.455131
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 237.573946
## iter 20 value 196.662905
## final value 196.100093
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 237.193131
## iter 20 value 184.612516
## iter 30 value 170.602470
## iter 40 value 170.292215
## iter 50 value 170.292011
## final value 170.291991
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 217.341691
## iter 20 value 171.258377
## iter 30 value 156.882633
## iter 40 value 156.356639
## iter 50 value 156.281151
## iter 60 value 156.272282
## final value 156.263682
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 217.597761
## iter 20 value 186.830700
## final value 186.549764
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 217.341951
## iter 20 value 171.338597
## iter 30 value 157.766864
## iter 40 value 157.453579
## iter 50 value 157.430751
## iter 60 value 157.428884
## final value 157.427619
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 221.673852
## iter 20 value 161.585830
## iter 30 value 146.915896
## iter 40 value 142.670731
## iter 50 value 142.450371
## iter 60 value 142.245563
## iter 70 value 142.240373
## iter 80 value 142.053958
## iter 90 value 141.960555
## iter 100 value 141.956644
## final value 141.956644
## stopped after 100 iterations
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 222.014026
## iter 20 value 187.788120
## iter 30 value 187.088792
## final value 187.088789
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 221.674197
## iter 20 value 161.749455
## iter 30 value 149.001115
## iter 40 value 147.852502
## iter 50 value 147.825846
## iter 60 value 147.815484
## iter 70 value 147.807070
## final value 147.807067
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 240.338655
## iter 20 value 152.975171
## iter 30 value 137.310115
## iter 40 value 133.404821
## iter 50 value 133.172788
## iter 60 value 132.915733
## iter 70 value 132.853315
## iter 80 value 132.832126
## iter 90 value 132.830889
## iter 100 value 132.830178
## final value 132.830178
## stopped after 100 iterations
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 242.287435
## iter 20 value 168.076076
## iter 30 value 167.178308
## final value 167.178279
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 240.340641
## iter 20 value 153.066603
## iter 30 value 139.806060
## iter 40 value 139.568768
## iter 50 value 139.532543
## iter 60 value 139.518452
## iter 70 value 139.517056
## final value 139.507564
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 219.578839
## iter 20 value 169.702343
## iter 30 value 155.429872
## iter 40 value 154.487917
## iter 50 value 154.487309
## iter 60 value 154.487163
## final value 154.486668
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 222.179801
## iter 20 value 187.234643
## iter 30 value 186.882545
## final value 186.882535
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 219.581494
## iter 20 value 169.765363
## iter 30 value 156.095480
## final value 155.389311
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 236.109718
## iter 20 value 170.754225
## iter 30 value 157.734744
## final value 156.993661
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 236.337031
## iter 20 value 190.417696
## iter 30 value 189.330347
## iter 30 value 189.330346
## iter 30 value 189.330346
## final value 189.330346
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 236.109947
## iter 20 value 170.851484
## iter 30 value 158.485693
## final value 157.907969
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 211.672156
## iter 20 value 162.216504
## iter 30 value 152.728964
## iter 40 value 152.056439
## iter 50 value 151.989943
## iter 60 value 151.973445
## iter 70 value 151.956463
## iter 70 value 151.956463
## iter 70 value 151.956463
## final value 151.956463
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 212.099173
## iter 20 value 178.085317
## iter 30 value 177.669211
## final value 177.669205
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 211.672587
## iter 20 value 162.322899
## iter 30 value 153.531484
## iter 40 value 153.100731
## iter 50 value 153.082640
## iter 60 value 153.079831
## final value 153.076829
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 210.826151
## iter 20 value 164.161739
## iter 30 value 154.797119
## iter 40 value 154.491655
## iter 50 value 154.491414
## final value 154.491407
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 211.280318
## iter 20 value 179.415901
## iter 30 value 179.186696
## iter 30 value 179.186695
## iter 30 value 179.186695
## final value 179.186695
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 210.826612
## iter 20 value 164.251211
## iter 30 value 155.291386
## iter 40 value 155.044557
## final value 155.044458
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 221.219881
## iter 20 value 181.606449
## iter 30 value 172.091712
## iter 40 value 171.483751
## iter 50 value 171.475754
## iter 60 value 171.474994
## final value 171.474840
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 221.554922
## iter 20 value 195.084787
## iter 30 value 193.519523
## final value 193.519499
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 221.220221
## iter 20 value 181.662587
## iter 30 value 172.537349
## iter 40 value 171.959161
## iter 50 value 171.953029
## final value 171.952439
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 231.210504
## iter 20 value 173.696030
## iter 30 value 154.406197
## final value 154.275914
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 231.582676
## iter 20 value 189.901146
## iter 30 value 189.451688
## final value 189.451681
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 231.210881
## iter 20 value 173.759304
## iter 30 value 155.381149
## iter 40 value 155.289515
## iter 50 value 155.289164
## final value 155.289141
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 227.286067
## iter 20 value 163.721684
## iter 30 value 150.708078
## iter 40 value 150.092463
## iter 50 value 150.037849
## iter 60 value 150.024405
## iter 60 value 150.024405
## iter 60 value 150.024405
## final value 150.024405
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 227.657045
## iter 20 value 184.308026
## iter 30 value 183.659705
## final value 183.659690
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 227.286444
## iter 20 value 163.844875
## iter 30 value 152.090152
## iter 40 value 151.493757
## iter 50 value 151.490307
## final value 151.489799
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 214.482753
## iter 20 value 160.220934
## iter 30 value 151.603339
## iter 40 value 150.395167
## iter 50 value 150.358448
## iter 60 value 150.353563
## final value 150.352786
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 215.189918
## iter 20 value 169.779188
## iter 30 value 168.743649
## final value 168.743620
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 214.483479
## iter 20 value 160.258776
## iter 30 value 151.992973
## iter 40 value 150.915310
## iter 50 value 150.889919
## iter 60 value 150.886709
## final value 150.884703
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 228.856660
## iter 20 value 168.001438
## iter 30 value 154.236725
## iter 40 value 153.867964
## iter 50 value 153.845862
## iter 60 value 153.842756
## final value 153.839375
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 229.444001
## iter 20 value 184.308154
## iter 30 value 183.868037
## iter 30 value 183.868036
## iter 30 value 183.868035
## final value 183.868035
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 228.857257
## iter 20 value 168.065554
## iter 30 value 154.855369
## iter 40 value 154.542843
## iter 50 value 154.522111
## iter 60 value 154.519223
## final value 154.516941
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 234.254206
## iter 20 value 168.284999
## iter 30 value 155.742483
## iter 40 value 155.014042
## iter 50 value 154.947951
## iter 60 value 154.939998
## final value 154.914585
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 235.388715
## iter 20 value 184.201160
## iter 30 value 182.909514
## final value 182.909450
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 234.255365
## iter 20 value 168.353558
## iter 30 value 156.431196
## iter 40 value 155.805762
## iter 50 value 155.756946
## iter 60 value 155.747332
## final value 155.730193
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 194.478763
## iter 20 value 162.071172
## iter 30 value 153.316407
## iter 40 value 152.720165
## iter 50 value 152.708530
## iter 60 value 152.707081
## final value 152.705612
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 195.044455
## iter 20 value 169.153387
## iter 30 value 168.399732
## final value 168.399723
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 194.479335
## iter 20 value 162.094802
## iter 30 value 153.696140
## iter 40 value 153.147440
## iter 50 value 153.139821
## iter 60 value 153.138985
## final value 153.138800
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 259.507213
## iter 20 value 185.620246
## iter 30 value 171.900994
## iter 40 value 171.676761
## iter 50 value 171.675108
## iter 60 value 171.674814
## final value 171.674579
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 259.940535
## iter 20 value 199.377311
## iter 30 value 198.536398
## final value 198.536393
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 259.507655
## iter 20 value 185.669986
## iter 30 value 172.353149
## iter 40 value 172.153199
## iter 50 value 172.152002
## iter 60 value 172.151876
## final value 172.151773
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 216.104304
## iter 20 value 169.319193
## iter 30 value 163.306010
## final value 163.300003
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 216.509222
## iter 20 value 191.712747
## final value 191.537661
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 216.104715
## iter 20 value 169.495059
## iter 30 value 163.760883
## final value 163.755633
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 200.594142
## iter 20 value 151.856399
## iter 30 value 133.452187
## iter 40 value 127.258073
## iter 50 value 127.152551
## iter 60 value 127.146114
## iter 70 value 127.139747
## final value 127.139210
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 200.969405
## iter 20 value 169.051070
## iter 30 value 168.584656
## final value 168.584649
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 200.594521
## iter 20 value 151.955300
## iter 30 value 135.924719
## iter 40 value 134.835537
## iter 50 value 134.523859
## iter 60 value 134.444202
## iter 70 value 134.425891
## final value 134.425421
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 236.519208
## iter 20 value 166.315086
## iter 30 value 152.931391
## iter 40 value 152.098932
## iter 50 value 152.035764
## iter 60 value 152.024331
## iter 70 value 152.015512
## final value 152.015438
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 236.779646
## iter 20 value 191.975327
## final value 191.787626
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 236.519471
## iter 20 value 166.465638
## iter 30 value 154.046241
## iter 40 value 153.618817
## iter 50 value 153.613194
## final value 153.613091
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 223.902979
## iter 20 value 175.641691
## iter 30 value 161.255781
## iter 40 value 160.755490
## iter 50 value 160.744350
## iter 60 value 160.741224
## iter 70 value 160.729691
## iter 70 value 160.729691
## iter 70 value 160.729691
## final value 160.729691
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 224.080360
## iter 20 value 192.553242
## final value 191.824785
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 223.903158
## iter 20 value 175.709316
## iter 30 value 162.143535
## iter 40 value 161.789752
## iter 50 value 161.789271
## final value 161.789111
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 209.894815
## iter 20 value 162.849167
## iter 30 value 149.773550
## iter 40 value 141.618418
## iter 50 value 141.514060
## iter 60 value 141.498647
## iter 70 value 141.491611
## final value 141.488150
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 210.239682
## iter 20 value 181.508139
## iter 30 value 181.122050
## final value 181.122048
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 209.895164
## iter 20 value 162.944388
## iter 30 value 151.469777
## iter 40 value 150.465912
## iter 50 value 150.179928
## iter 60 value 150.116537
## iter 70 value 150.107270
## final value 150.101462
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 219.334247
## iter 20 value 163.087354
## iter 30 value 143.014069
## iter 40 value 139.192967
## iter 50 value 137.875567
## iter 60 value 137.324815
## iter 70 value 137.289675
## iter 80 value 136.452028
## iter 90 value 135.966665
## iter 100 value 135.947421
## final value 135.947421
## stopped after 100 iterations
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 219.806713
## iter 20 value 187.418888
## iter 30 value 186.891634
## iter 30 value 186.891633
## iter 30 value 186.891632
## final value 186.891632
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 219.334727
## iter 20 value 163.218993
## iter 30 value 145.475390
## iter 40 value 145.072904
## iter 50 value 145.017251
## iter 60 value 145.014875
## final value 145.009032
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 205.382859
## iter 20 value 161.026725
## iter 30 value 153.569868
## iter 40 value 153.506484
## iter 50 value 153.504985
## final value 153.504933
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 205.808631
## iter 20 value 170.782394
## iter 30 value 170.529465
## iter 30 value 170.529463
## iter 30 value 170.529463
## final value 170.529463
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 205.383289
## iter 20 value 161.070168
## iter 30 value 153.977220
## iter 40 value 153.937842
## iter 50 value 153.937341
## final value 153.937331
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 201.014116
## iter 20 value 147.069236
## iter 30 value 130.513895
## iter 40 value 127.718324
## iter 50 value 127.466167
## iter 60 value 127.324066
## iter 70 value 127.303915
## iter 80 value 127.155641
## iter 90 value 127.120671
## iter 100 value 127.119651
## final value 127.119651
## stopped after 100 iterations
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 201.984893
## iter 20 value 161.284255
## iter 30 value 160.668203
## final value 160.668175
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 201.015111
## iter 20 value 147.133871
## iter 30 value 131.861267
## iter 40 value 130.397608
## iter 50 value 130.333288
## iter 60 value 130.305895
## iter 70 value 130.297079
## final value 130.297076
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 245.622515
## iter 20 value 192.146403
## iter 30 value 176.987516
## iter 40 value 176.244638
## iter 50 value 176.188856
## iter 60 value 176.182244
## final value 176.179717
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 245.993832
## iter 20 value 211.996790
## final value 211.341732
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 245.622893
## iter 20 value 192.271097
## iter 30 value 178.089553
## iter 40 value 177.355048
## iter 50 value 177.332968
## final value 177.328965
## converged
## # weights: 30 (18 variable)
## initial value 353.753157
## iter 10 value 218.032720
## iter 20 value 173.350700
## iter 30 value 163.770891
## iter 40 value 163.750951
## iter 40 value 163.750950
## iter 40 value 163.750950
## final value 163.750950
## converged
carsmlr$finalModel
## Call:
## nnet::multinom(formula = .outcome ~ ., data = dat, decay = param$decay)
##
## Coefficients:
## (Intercept) Age GenderMale Engineer1 MBA1
## Public Transport -2.924602 0.1867473 0.9073215 -0.1392119 0.1814413
## Car -73.157600 2.4072670 -0.8481166 1.4958898 -0.7794798
## Work.Exp Salary Distance license1
## Public Transport 0.1027101 -0.07091949 -0.1481504 -1.154896
## Car -1.0684135 0.17301043 0.3334671 1.378113
##
## Residual Deviance: 327.5019
## AIC: 363.5019
carmlrcoeff<-exp(coef(carsmlr$finalModel))
write.csv(carmlrcoeff,file = "Coeffsmlr.csv")
plot(varImp(object=carsmlr), main = "Variable Importance for Multinomial Logit")
The model has a residual deviance 296.416. The model implies that an increase in Age by 1 year increases the odds of taking Public Transport as compared to 2 Wheeler by 1.3 (57%), whereas it increses the odds of choosing car by 12 (92%) Age and license are the two main important factors in deciding mode of transport
Let us try and predict using the test data
predictions_mlr<-predict(carsmlr,carstestlda)
confusionMatrix(predictions_mlr,carstestlda$Transport)
## Warning in confusionMatrix.default(predictions_mlr, carstestlda$Transport):
## Levels are not in the same order for reference and data. Refactoring data
## to match.
## Confusion Matrix and Statistics
##
## Reference
## Prediction 2Wheeler Car Public Transport
## 2Wheeler 16 0 8
## Car 1 18 2
## Public Transport 7 0 80
##
## Overall Statistics
##
## Accuracy : 0.8636
## 95% CI : (0.7931, 0.9171)
## No Information Rate : 0.6818
## P-Value [Acc > NIR] : 1.242e-06
##
## Kappa : 0.725
## Mcnemar's Test P-Value : 0.3815
##
## Statistics by Class:
##
## Class: 2Wheeler Class: Car Class: Public Transport
## Sensitivity 0.6667 1.0000 0.8889
## Specificity 0.9259 0.9737 0.8333
## Pos Pred Value 0.6667 0.8571 0.9195
## Neg Pred Value 0.9259 1.0000 0.7778
## Prevalence 0.1818 0.1364 0.6818
## Detection Rate 0.1212 0.1364 0.6061
## Detection Prevalence 0.1818 0.1591 0.6591
## Balanced Accuracy 0.7963 0.9868 0.8611
The overall accuracy is at 70% with accuracy of car usage predicted at 94% Let us try and predict for the two unknown cases
predictTransportuk4<-predict.train(object = carsmlr,newdata = carunknown)
carunknown$predictTransportmlr<-predictTransportuk4
print(carunknown)
## Age Gender Engineer MBA Work.Exp Salary Distance license predictcaruse
## 1 25 Male 0 0 2 10 5 1 0
## 2 25 Female 1 0 2 10 5 0 0
## predictcarusegn predictTransport predictTransportpda
## 1 0 Public Transport Public Transport
## 2 0 Public Transport Public Transport
## predictTransportcart predictTransportxgb predictTransportmlr
## 1 Public Transport 2Wheeler Public Transport
## 2 Public Transport 2Wheeler Public Transport
The model has predicted both cases to be using public transport
rftrcontrol<-control <- trainControl(method="repeatedcv", number=10, repeats=3)
mtry<-sqrt(ncol(carsdatatrainldasm))
tunegridrf <- expand.grid(.mtry=mtry)
carsrf<-train(Transport ~.,carsdatatrainldasm,method = "rf", trControl=rftrcontrol, tuneGrid = tunegridrf)
carsrf$finalModel
##
## Call:
## randomForest(x = x, y = y, mtry = param$mtry)
## Type of random forest: classification
## Number of trees: 500
## No. of variables tried at each split: 3
##
## OOB estimate of error rate: 16.77%
## Confusion matrix:
## 2Wheeler Public Transport Car class.error
## 2Wheeler 85 32 1 0.27966102
## Public Transport 14 100 4 0.15254237
## Car 2 1 83 0.03488372
plot(varImp(object=carsrf), main = "Variable Importance for Random Forest")
The out of bag error estimate rate is 16.7% in the training dataset. Age, Work Experience, Distance and Salary are the most significant variables Let us try and predict for test data
predictions_rf<-predict(carsrf,carstestlda)
confusionMatrix(predictions_rf,carstestlda$Transport)
## Warning in confusionMatrix.default(predictions_rf, carstestlda$Transport):
## Levels are not in the same order for reference and data. Refactoring data
## to match.
## Confusion Matrix and Statistics
##
## Reference
## Prediction 2Wheeler Car Public Transport
## 2Wheeler 18 0 29
## Car 1 17 1
## Public Transport 5 1 60
##
## Overall Statistics
##
## Accuracy : 0.7197
## 95% CI : (0.6349, 0.7943)
## No Information Rate : 0.6818
## P-Value [Acc > NIR] : 0.2011606
##
## Kappa : 0.5123
## Mcnemar's Test P-Value : 0.0004523
##
## Statistics by Class:
##
## Class: 2Wheeler Class: Car Class: Public Transport
## Sensitivity 0.7500 0.9444 0.6667
## Specificity 0.7315 0.9825 0.8571
## Pos Pred Value 0.3830 0.8947 0.9091
## Neg Pred Value 0.9294 0.9912 0.5455
## Prevalence 0.1818 0.1364 0.6818
## Detection Rate 0.1364 0.1288 0.4545
## Detection Prevalence 0.3561 0.1439 0.5000
## Balanced Accuracy 0.7407 0.9635 0.7619
We have an overall accuracy of 72% and 94% accuracy for prediction of car usage Let us now predict the choice of transport for 2 unknown cases
predictTransportuk5<-predict.train(object = carsrf,newdata = carunknown)
carunknown$predictTransportrf<-predictTransportuk5
print(carunknown)
## Age Gender Engineer MBA Work.Exp Salary Distance license predictcaruse
## 1 25 Male 0 0 2 10 5 1 0
## 2 25 Female 1 0 2 10 5 0 0
## predictcarusegn predictTransport predictTransportpda
## 1 0 Public Transport Public Transport
## 2 0 Public Transport Public Transport
## predictTransportcart predictTransportxgb predictTransportmlr
## 1 Public Transport 2Wheeler Public Transport
## 2 Public Transport 2Wheeler Public Transport
## predictTransportrf
## 1 Public Transport
## 2 2Wheeler
We have one record (female,engineer) predicted to choose 2 Wheeler and the other record to have chosen Public Transport