Modeling is a process to provide low-dimensional summary of a dataset. The goal is to partition data into patterns and residuals. There are two parts to modeling defining a family of models and generating a fitted model.
Statistical Machine Learning used to modeling a dataset, for estimate and inference. Example a model Y=f(x)+e, estimate is to knowthe dimensions of an X, inference is to conclude how X can explain Y.
# package
library(ggplot2)
library(caret)
## Warning: package 'caret' was built under R version 4.3.2
## Loading required package: lattice
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.3 ✔ readr 2.1.4
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ lubridate 1.9.3 ✔ tibble 3.2.1
## ✔ purrr 1.0.2 ✔ tidyr 1.3.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ✖ purrr::lift() masks caret::lift()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(AER)
## Warning: package 'AER' was built under R version 4.3.2
## Loading required package: car
## Loading required package: carData
##
## Attaching package: 'car'
##
## The following object is masked from 'package:dplyr':
##
## recode
##
## The following object is masked from 'package:purrr':
##
## some
##
## Loading required package: lmtest
## Warning: package 'lmtest' was built under R version 4.3.2
## Loading required package: zoo
## Warning: package 'zoo' was built under R version 4.3.2
##
## Attaching package: 'zoo'
##
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
##
## Loading required package: sandwich
## Warning: package 'sandwich' was built under R version 4.3.2
## Loading required package: survival
##
## Attaching package: 'survival'
##
## The following object is masked from 'package:caret':
##
## cluster
library(corrplot)
## Warning: package 'corrplot' was built under R version 4.3.2
## corrplot 0.92 loaded
library(randomForest)
## Warning: package 'randomForest' was built under R version 4.3.2
## randomForest 4.7-1.1
## Type rfNews() to see new features/changes/bug fixes.
##
## Attaching package: 'randomForest'
##
## The following object is masked from 'package:dplyr':
##
## combine
##
## The following object is masked from 'package:ggplot2':
##
## margin
data(Affairs, package="AER")
head(Affairs, 10)
summary(Affairs)
## affairs gender age yearsmarried children
## Min. : 0.000 female:315 Min. :17.50 Min. : 0.125 no :171
## 1st Qu.: 0.000 male :286 1st Qu.:27.00 1st Qu.: 4.000 yes:430
## Median : 0.000 Median :32.00 Median : 7.000
## Mean : 1.456 Mean :32.49 Mean : 8.178
## 3rd Qu.: 0.000 3rd Qu.:37.00 3rd Qu.:15.000
## Max. :12.000 Max. :57.00 Max. :15.000
## religiousness education occupation rating
## Min. :1.000 Min. : 9.00 Min. :1.000 Min. :1.000
## 1st Qu.:2.000 1st Qu.:14.00 1st Qu.:3.000 1st Qu.:3.000
## Median :3.000 Median :16.00 Median :5.000 Median :4.000
## Mean :3.116 Mean :16.17 Mean :4.195 Mean :3.932
## 3rd Qu.:4.000 3rd Qu.:18.00 3rd Qu.:6.000 3rd Qu.:5.000
## Max. :5.000 Max. :20.00 Max. :7.000 Max. :5.000
Data named Affairs have 9 variables such as affairs, gender, age, years married, children, religiousness, education, occupation, and rating. From 9 variables, children is gonna be used as Y variable and the others as X variables.
# Using bar chart to see numbers for Yes and No
ggplot(Affairs, aes(x = children)) +
geom_bar(fill = "lightblue") +
labs(x = "Y Respond", y = "Frekuensi", title = "Bar Chart Y Respond") +
theme_minimal()
Affairs.2 <- Affairs %>%
mutate(gender = ifelse(gender == "male", 1, 0)) %>%
mutate(children = ifelse(children == "no", 0, 1))
head(Affairs.2)
multicol <- cor(Affairs.2)
corrplot(multicol, method = "number")
The variable respond show, >150 “No” or didn’t have children and >400 “Yes” or have children.After checking multicolinearity there are variables that indicate have multicolinearity such as years married and age; and education and occupation.Because some variables have multicolinearity the variables years married and age gonna exclude it from the data.
Affairs <- subset(Affairs, select = c("affairs","gender","children","religiousness","rating","education","occupation"))
head(Affairs,10)
Affairs$children <- as.factor(Affairs$children)
Affairs$gender <- as.factor(Affairs$gender)
Affairs$religiousness <- as.double(Affairs$religiousness)
Affairs$rating <- as.double(Affairs$rating)
Affairs$occupation <- as.double(Affairs$occupation)
# Data Split
set.seed(1910)
split.data <- createDataPartition(Affairs$children, p = 0.8, list=FALSE)
trainData <- Affairs[split.data,]
testData <- Affairs[-split.data,]
# Logistic Regression
log.reg <- glm(children~ ., data = trainData, family = binomial)
summary(log.reg)
##
## Call:
## glm(formula = children ~ ., family = binomial, data = trainData)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 1.04092 0.93596 1.112 0.266077
## affairs 0.08941 0.04002 2.234 0.025486 *
## gendermale 0.63746 0.24556 2.596 0.009434 **
## religiousness 0.34322 0.09348 3.671 0.000241 ***
## rating -0.42409 0.11308 -3.750 0.000177 ***
## education 0.06388 0.05546 1.152 0.249346
## occupation -0.20984 0.07561 -2.775 0.005517 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 574.75 on 480 degrees of freedom
## Residual deviance: 525.33 on 474 degrees of freedom
## AIC: 539.33
##
## Number of Fisher Scoring iterations: 4
rob.reg.log<-predict(log.reg, testData, type="response")
prediksi<-as.factor(ifelse(rob.reg.log>0.5,"yes","no"))
pred.aktual<-data.frame(prediksi,testData$children)
head(pred.aktual)
confusionMatrix(prediksi, testData$children)
## Confusion Matrix and Statistics
##
## Reference
## Prediction no yes
## no 9 5
## yes 25 81
##
## Accuracy : 0.75
## 95% CI : (0.6627, 0.8245)
## No Information Rate : 0.7167
## P-Value [Acc > NIR] : 0.2415025
##
## Kappa : 0.2512
##
## Mcnemar's Test P-Value : 0.0005226
##
## Sensitivity : 0.2647
## Specificity : 0.9419
## Pos Pred Value : 0.6429
## Neg Pred Value : 0.7642
## Prevalence : 0.2833
## Detection Rate : 0.0750
## Detection Prevalence : 0.1167
## Balanced Accuracy : 0.6033
##
## 'Positive' Class : no
##
# Random Forest
rf_model <- randomForest(children ~ ., data = trainData)
summary(rf_model)
## Length Class Mode
## call 3 -none- call
## type 1 -none- character
## predicted 481 factor numeric
## err.rate 1500 -none- numeric
## confusion 6 -none- numeric
## votes 962 matrix numeric
## oob.times 481 -none- numeric
## classes 2 -none- character
## importance 6 -none- numeric
## importanceSD 0 -none- NULL
## localImportance 0 -none- NULL
## proximity 0 -none- NULL
## ntree 1 -none- numeric
## mtry 1 -none- numeric
## forest 14 -none- list
## y 481 factor numeric
## test 0 -none- NULL
## inbag 0 -none- NULL
## terms 3 terms call
rf_predictions <- predict(rf_model, newdata = testData)
summary(rf_predictions)
## no yes
## 24 96
confusionMatrix(as.factor(rf_predictions), as.factor(testData$children))
## Confusion Matrix and Statistics
##
## Reference
## Prediction no yes
## no 15 9
## yes 19 77
##
## Accuracy : 0.7667
## 95% CI : (0.6807, 0.839)
## No Information Rate : 0.7167
## P-Value [Acc > NIR] : 0.13169
##
## Kappa : 0.3694
##
## Mcnemar's Test P-Value : 0.08897
##
## Sensitivity : 0.4412
## Specificity : 0.8953
## Pos Pred Value : 0.6250
## Neg Pred Value : 0.8021
## Prevalence : 0.2833
## Detection Rate : 0.1250
## Detection Prevalence : 0.2000
## Balanced Accuracy : 0.6683
##
## 'Positive' Class : no
##
Logistic regression and random forest modeling predicted people have affairs even they are have children with accuracy of logistic regression 75% and random forest 77%, from the accuracy value, random forest is the best method to predict the data. Sensitivity and specificity value need to evaluate. Sensitivity is indicates the model is good at capturing positive instances and specificity is indicates the model is good at avoiding false positives. Based on accuracy, sensitivity, and specificity random forest method is better than logistic regression.