In this homework assignment, we will explore, analyze and model a data set containing information on crime for various neighborhoods of a major city. Each record has a response variable indicating whether or not the crime rate is above the median crime rate (1) or not (0).
Our objective is to build a binary logistic regression model on the training data set to predict whether the neighborhood will be at risk for high crime levels. We will provide classifications and probabilities for the evaluation data set using our binary logistic regression model.
We will only use the variables provided to us (or variables that we derived from the variables given). Below is a short description of the variables of interest in the data set:
zn
: proportion of residential land zoned for large lots (over 25000 square feet) (predictor variable)chas
: a dummy var. for whether the suburb borders the Charles River (1) or not (0) (predictor variable)nox
: nitrogen oxides concentration (parts per 10 million) (predictor variable)rm
: average number of rooms per dwelling (predictor variable)age
: proportion of owner-occupied units built prior to 1940 (predictor variable)dis
: weighted mean of distances to five Boston employment centers (predictor variable)rad
: index of accessibility to radial highways (predictor variable)tax
: full-value property-tax rate per $10,000 (predictor variable)ptratio
: pupil-teacher ratio by town (predictor variable)black
: 1000(Bk - 0.63)2 where Bk is the proportion of blacks by town (predictor variable)lstat
: lower status of the population (percent) (predictor variable)medv
: median value of owner-occupied homes in $1000s (predictor variable)target
: whether the crime rate is above the median crime rate (1) or not (0) (response variable)crime <- read.csv("https://raw.githubusercontent.com/josephsimone/Data621/master/project3/crime-training-data_modified.csv")
crime_eval <- read.csv("https://raw.githubusercontent.com/josephsimone/Data621/master/project3/crime-evaluation-data_modified.csv")
kable(head(crime))
zn | indus | chas | nox | rm | age | dis | rad | tax | ptratio | lstat | medv | target |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 19.58 | 0 | 0.605 | 7.929 | 96.2 | 2.0459 | 5 | 403 | 14.7 | 3.70 | 50.0 | 1 |
0 | 19.58 | 1 | 0.871 | 5.403 | 100.0 | 1.3216 | 5 | 403 | 14.7 | 26.82 | 13.4 | 1 |
0 | 18.10 | 0 | 0.740 | 6.485 | 100.0 | 1.9784 | 24 | 666 | 20.2 | 18.85 | 15.4 | 1 |
30 | 4.93 | 0 | 0.428 | 6.393 | 7.8 | 7.0355 | 6 | 300 | 16.6 | 5.19 | 23.7 | 0 |
0 | 2.46 | 0 | 0.488 | 7.155 | 92.2 | 2.7006 | 3 | 193 | 17.8 | 4.82 | 37.9 | 0 |
0 | 8.56 | 0 | 0.520 | 6.781 | 71.3 | 2.8561 | 5 | 384 | 20.9 | 7.67 | 26.5 | 0 |
##
## 0 1
## 237 229
zn | indus | chas | nox | rm | age | |
---|---|---|---|---|---|---|
Min. : 0.00 | Min. : 0.460 | Min. :0.00000 | Min. :0.3890 | Min. :3.863 | Min. : 2.90 | |
1st Qu.: 0.00 | 1st Qu.: 5.145 | 1st Qu.:0.00000 | 1st Qu.:0.4480 | 1st Qu.:5.887 | 1st Qu.: 43.88 | |
Median : 0.00 | Median : 9.690 | Median :0.00000 | Median :0.5380 | Median :6.210 | Median : 77.15 | |
Mean : 11.58 | Mean :11.105 | Mean :0.07082 | Mean :0.5543 | Mean :6.291 | Mean : 68.37 | |
3rd Qu.: 16.25 | 3rd Qu.:18.100 | 3rd Qu.:0.00000 | 3rd Qu.:0.6240 | 3rd Qu.:6.630 | 3rd Qu.: 94.10 | |
Max. :100.00 | Max. :27.740 | Max. :1.00000 | Max. :0.8710 | Max. :8.780 | Max. :100.00 |
dis | rad | tax | ptratio | lstat | medv | |
---|---|---|---|---|---|---|
Min. : 1.130 | Min. : 1.00 | Min. :187.0 | Min. :12.6 | Min. : 1.730 | Min. : 5.00 | |
1st Qu.: 2.101 | 1st Qu.: 4.00 | 1st Qu.:281.0 | 1st Qu.:16.9 | 1st Qu.: 7.043 | 1st Qu.:17.02 | |
Median : 3.191 | Median : 5.00 | Median :334.5 | Median :18.9 | Median :11.350 | Median :21.20 | |
Mean : 3.796 | Mean : 9.53 | Mean :409.5 | Mean :18.4 | Mean :12.631 | Mean :22.59 | |
3rd Qu.: 5.215 | 3rd Qu.:24.00 | 3rd Qu.:666.0 | 3rd Qu.:20.2 | 3rd Qu.:16.930 | 3rd Qu.:25.00 | |
Max. :12.127 | Max. :24.00 | Max. :711.0 | Max. :22.0 | Max. :37.970 | Max. :50.00 |
ntrain<-select_if(crime, is.numeric)
ntrain %>%
keep(is.numeric) %>%
gather() %>%
ggplot(aes(value)) +
facet_wrap(~ key, scales = "free") +
geom_density()
Of each continuous independent variable with target.
par(mfrow = c(4,3))
boxplot(zn~target, ylab="zn", xlab= "target", col="steel blue",data = crime)
boxplot(indus~target, ylab="indus", xlab= "target", col="steel blue",data = crime)
boxplot(chas~target, ylab="chas", xlab= "target", col="steel blue",data = crime)
boxplot(nox~target, ylab="nox", xlab= "target", col="steel blue",data = crime)
boxplot(rm~target, ylab="rm", xlab= "target", col="steel blue",data = crime)
boxplot(age~target, ylab="age", xlab= "target", col="steel blue",data = crime)
boxplot(dis~target, ylab="dis", xlab= "target", col="steel blue",data = crime)
boxplot(rad~target, ylab="rad", xlab= "target", col="steel blue",data = crime)
boxplot(tax~target, ylab="tax", xlab= "target", col="steel blue",data = crime)
boxplot(ptratio~target, ylab="ptratio", xlab= "target", col="steel blue",data = crime)
boxplot(lstat~target, ylab="lstat", xlab= "target", col="steel blue",data = crime)
boxplot(medv~target, ylab="medv", xlab= "target", col="steel blue",data = crime)
From the above plots, we can infer that the crime rate is above the median when majority of the predictors are high. For instance, have a look at nox
(nitrogen oxide) and tax
(property tax).
##
## Pearson's product-moment correlation
##
## data: crime$rad and crime$tax
## t = 46.239, df = 464, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
## 0.8888115 0.9214292
## sample estimates:
## cor
## 0.9064632
## [1] FALSE
There does not appear to be missing cases.
Use scale function to scale all variables to mean and standard devatiotion of target variable.
## [1] 0.4914163
## [1] 0.5004636
# Scale Predictor Variables
ntrain.scaled <- (as.data.frame(scale(ntrain[, -which(names(ntrain) == "target")])) + mean(ntrain$target)*2) / 2
ntrain.scaled <- cbind.data.frame(target = ntrain$target, ntrain.scaled)
# Variable Mean and Standard Deviation
colMeans(ntrain.scaled);apply(ntrain.scaled,2,sd)
## target zn indus chas nox rm age dis
## 0.4914163 0.4914163 0.4914163 0.4914163 0.4914163 0.4914163 0.4914163 0.4914163
## rad tax ptratio lstat medv
## 0.4914163 0.4914163 0.4914163 0.4914163 0.4914163
## target zn indus chas nox rm age dis
## 0.5004636 0.5000000 0.5000000 0.5000000 0.5000000 0.5000000 0.5000000 0.5000000
## rad tax ptratio lstat medv
## 0.5000000 0.5000000 0.5000000 0.5000000 0.5000000
After scaling, the predictor and responce variables posses approximately equal means and standard deviations.
We will use sigmoid function to scale all variables between zero and one.
The following transformation will map each of the values on to the Logistic curve. This will allow us to construct a linear model on with the scaled data.
y = "https://upload.wikimedia.org/wikipedia/commons/thumb/8/88/Logistic-curve.svg/2560px-Logistic-curve.svg.png"
download.file(y,'y.png', mode = 'wb')
jj <- readPNG("y.png",native=TRUE)
plot(0:1,0:1,type="n",ann=FALSE,axes=FALSE)
rasterImage(jj,0,0,1,1)
# Squish Scaled Data
ntrain.scaled.sigmoid <- as.data.frame(lapply(ntrain.scaled,sigmoid))
# Variable Mean and Standard Deviation
colMeans(ntrain.scaled.sigmoid);apply(ntrain.scaled.sigmoid,2,sd)
## target zn indus chas nox rm age dis
## 0.6135460 0.6110187 0.6132653 0.6102377 0.6127209 0.6135238 0.6149403 0.6123702
## rad tax ptratio lstat medv
## 0.6119626 0.6125669 0.6153707 0.6125611 0.6124636
## target zn indus chas nox rm age
## 0.11563640 0.09545625 0.11283836 0.08254726 0.10869567 0.10784268 0.11746022
## dis rad tax ptratio lstat medv
## 0.10676718 0.10725490 0.11004905 0.11728960 0.10721135 0.10502008
## scale only predictors
ntrain.scaled.sigmoid2 <- as.data.frame(lapply(ntrain.scaled[,-1],sigmoid))
ntrain.scaled.sigmoid2$target <- crime$target
After applying the sigmoid function, the predictor and responce variables still retain approximately equal means and standard deviations.
target <- crime$target
mb = preProcess(crime[,-13],
c("BoxCox", "center", "scale", "nzv"))
crime_trans = data.frame(
ct = predict(mb, crime[,-13]))
crime_trans$target <- target
names(crime_trans) <- names(crime)
Here all variables were transformed except the target variable. The variables were transformed using Box-Cox. In addition, the variables were scaled, centered and non-zero-variance values were removed (if any).
##
## Call:
## glm(formula = target ~ ., family = binomial, data = ntrain.scaled)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.8464 -0.1445 -0.0017 0.0029 3.4665
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -11.1603 1.8624 -5.993 2.07e-09 ***
## zn -3.0816 1.6195 -1.903 0.05706 .
## indus -0.8847 0.6520 -1.357 0.17485
## chas 0.4678 0.3880 1.205 0.22803
## nox 11.4619 1.8507 6.193 5.90e-10 ***
## rm -0.8282 1.0190 -0.813 0.41637
## age 1.9366 0.7825 2.475 0.01333 *
## dis 3.1126 0.9704 3.208 0.00134 **
## rad 11.5760 2.8343 4.084 4.42e-05 ***
## tax -2.0724 0.9922 -2.089 0.03674 *
## ptratio 1.7687 0.5564 3.179 0.00148 **
## lstat 0.6515 0.7677 0.849 0.39608
## medv 3.3415 1.2620 2.648 0.00810 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 645.88 on 465 degrees of freedom
## Residual deviance: 192.05 on 453 degrees of freedom
## AIC: 218.05
##
## Number of Fisher Scoring iterations: 9
##
## Call:
## glm(formula = target ~ zn + nox + age + dis + rad + tax + ptratio +
## medv, family = binomial, data = ntrain.scaled)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.8295 -0.1752 -0.0021 0.0032 3.4191
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -9.7770 1.5871 -6.160 7.26e-10 ***
## zn -3.2079 1.4962 -2.144 0.03203 *
## nox 9.9885 1.5584 6.410 1.46e-10 ***
## age 1.8664 0.6203 3.009 0.00262 **
## dis 2.7597 0.9020 3.060 0.00222 **
## rad 12.5965 2.6021 4.841 1.29e-06 ***
## tax -2.6045 0.8908 -2.924 0.00346 **
## ptratio 1.4219 0.4894 2.905 0.00367 **
## medv 2.0415 0.6550 3.117 0.00183 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 645.88 on 465 degrees of freedom
## Residual deviance: 197.32 on 457 degrees of freedom
## AIC: 215.32
##
## Number of Fisher Scoring iterations: 9
After using stepAIC method, ‘stepAIC’ function, we are now left with eight independent variables which also resulted in having the minimum AIC value so far.
## zn nox age dis rad tax ptratio medv
## 1.789037 3.172660 1.701974 3.595939 1.697110 1.754274 1.865085 2.193689
##
## Call:
## lm(formula = target ~ nox + age + rad + medv, data = ntrain.scaled.sigmoid)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.134511 -0.042567 -0.009906 0.027400 0.208979
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.08854 0.04178 -2.120 0.034580 *
## nox 0.52443 0.05396 9.718 < 2e-16 ***
## age 0.16209 0.04349 3.727 0.000218 ***
## rad 0.32503 0.04035 8.056 6.83e-15 ***
## medv 0.13418 0.03697 3.629 0.000316 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.07138 on 461 degrees of freedom
## Multiple R-squared: 0.6223, Adjusted R-squared: 0.619
## F-statistic: 189.9 on 4 and 461 DF, p-value: < 2.2e-16
Using the sigmoid scaled data in a linear model has further contrained the relevant predictor variables and minimized the intercept (when compared to the binomial model). This suggests these adjusted variables contain most of the relevant information about this system.
## nox age rad medv
## 3.140318 2.382030 1.709335 1.376141
##
## Call:
## glm(formula = target ~ ., family = binomial, data = crime_trans)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.9381 -0.1116 -0.0010 0.1137 3.4325
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.082410 0.316075 -0.261 0.794301
## zn -0.519732 0.627379 -0.828 0.407433
## indus -0.003522 0.379970 -0.009 0.992603
## chas 0.242925 0.195625 1.242 0.214316
## nox 4.889837 0.772981 6.326 2.52e-10 ***
## rm -0.375393 0.453263 -0.828 0.407556
## age 1.154904 0.373442 3.093 0.001984 **
## dis 1.834862 0.469904 3.905 9.43e-05 ***
## rad 2.728346 0.634460 4.300 1.71e-05 ***
## tax -0.322880 0.408076 -0.791 0.428812
## ptratio 0.979115 0.277238 3.532 0.000413 ***
## lstat -0.048931 0.424222 -0.115 0.908173
## medv 1.845058 0.642208 2.873 0.004066 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 645.88 on 465 degrees of freedom
## Residual deviance: 196.79 on 453 degrees of freedom
## AIC: 222.79
##
## Number of Fisher Scoring iterations: 8
##
## Call:
## glm(formula = target ~ chas + nox + age + dis + rad + ptratio +
## medv, family = binomial, data = crime_trans)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.9253 -0.1524 -0.0029 0.1179 3.3556
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.1509 0.2265 0.666 0.50533
## chas 0.3094 0.1779 1.739 0.08200 .
## nox 4.8640 0.7230 6.728 1.73e-11 ***
## age 1.0055 0.3060 3.286 0.00102 **
## dis 1.8161 0.4323 4.201 2.66e-05 ***
## rad 2.2998 0.4433 5.188 2.12e-07 ***
## ptratio 0.9617 0.2432 3.954 7.67e-05 ***
## medv 1.5353 0.3609 4.254 2.10e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 645.88 on 465 degrees of freedom
## Residual deviance: 199.53 on 458 degrees of freedom
## AIC: 215.53
##
## Number of Fisher Scoring iterations: 8
Results show that model did not improve with just transforming the predictors, even after using the stepAIC function. However, this model would be considered less complex as it has 1 less predictor than model 1 and model 2.
## chas nox age dis rad ptratio medv
## 1.114122 3.738991 1.862143 3.338080 1.113786 1.889139 2.520938
##
## Call:
## glm(formula = target ~ ., family = binomial, data = ntrain.scaled.sigmoid2)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.8536 -0.1490 -0.0032 0.0128 3.4196
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -73.414 12.477 -5.884 4.00e-09 ***
## zn -10.849 6.394 -1.697 0.089724 .
## indus -3.328 3.023 -1.101 0.270913
## chas 2.711 2.353 1.152 0.249269
## nox 49.003 7.861 6.234 4.55e-10 ***
## rm -4.482 4.403 -1.018 0.308709
## age 8.887 3.337 2.664 0.007732 **
## dis 15.312 4.424 3.461 0.000537 ***
## rad 45.586 11.386 4.004 6.24e-05 ***
## tax -7.362 4.204 -1.751 0.079923 .
## ptratio 7.755 2.445 3.172 0.001512 **
## lstat 2.348 3.636 0.646 0.518439
## medv 16.961 5.923 2.863 0.004192 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 645.88 on 465 degrees of freedom
## Residual deviance: 195.93 on 453 degrees of freedom
## AIC: 221.93
##
## Number of Fisher Scoring iterations: 9
##
## Call:
## glm(formula = target ~ zn + nox + age + dis + rad + tax + ptratio +
## medv, family = binomial, data = ntrain.scaled.sigmoid2)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.7611 -0.1632 -0.0036 0.0080 3.3806
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -64.719 10.770 -6.009 1.87e-09 ***
## zn -11.852 5.947 -1.993 0.04627 *
## nox 43.260 6.654 6.502 7.95e-11 ***
## age 8.042 2.684 2.996 0.00273 **
## dis 13.442 4.135 3.251 0.00115 **
## rad 49.279 10.579 4.658 3.19e-06 ***
## tax -9.616 3.811 -2.523 0.01162 *
## ptratio 6.000 2.139 2.806 0.00502 **
## medv 10.007 3.292 3.040 0.00236 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 645.88 on 465 degrees of freedom
## Residual deviance: 200.56 on 457 degrees of freedom
## AIC: 218.56
##
## Number of Fisher Scoring iterations: 8
## zn nox age dis rad tax ptratio medv
## 1.612196 3.354050 1.746804 3.611908 1.709746 1.875620 1.983801 2.466023
ANOVA
Model 2 is built on a different scale than the other 3 models, so it cannot be compared with them under the anova function. However we’ll show what it looks like in that case.
ANOVA (Comparing the other 3 models)
Model one does seem to perform better than the other three models.
# Predict the probability of crime positivity
probabilities <- predict(mod1, ntrain.scaled, type = "response")
predicted.classes <- ifelse(probabilities > 0.5, 1, 0)
ntrain.scaled$pred.class <- predicted.classes
table("Predictions" = ntrain.scaled$pred.class, "Actual" = ntrain.scaled$target)
## Actual
## Predictions 0 1
## 0 218 22
## 1 19 207
Accuracy can be defined as the fraction of predicitons our model got right. Also known as the error rate, the accuracy rate makes no distinction about the type of error being made.
\[\large \text{Accuracy} = \large \frac{TP+TN}{TP+FP+TN+FN}\]
The Classification Error Rate calculates the number of incorrect predictions out of the total number of predictions in the dataset.
\[\large \text{Classification Error Rate} = \large \frac{FP+FN}{TP+FP+TN+FN}\]
This is the positive value or the fraction of the positive predictions that are actually positive.
\[\large \text{Precision} = \large \frac{TP}{TP+FP}\]
The sensitivity is sometimes considered the true positive rate since it measures the accuracy in the event population.
\[\large \text{Sensitivity} = \large \frac{TP}{TP+FN}\]
This is the true negatitive rate or the proportion of negatives that are correctly identified.
\[\large \text{Specificity} = \large \frac{TN}{TN+FP}\]
The F1 Score of Predictions measures the test’s accuracy, on a scale of 0 to 1 where a value of 1 is the most accurate and the value of 0 is the least accurate.
\[\large \text{F1 Score} = \large \frac{2 * Precision*Sensitivity}{Precision + Sensitivity}\]
cl_f1score <- function(df){
cm <- table("Predictions" = df$pred.class, "Actual" = df$target)
TP <- cm[2,2]
TN <- cm[1,1]
FP <- cm[2,1]
FN <- cm[1,2]
f1score <- (2 * cl_precision(df) * cl_sensitivity(df)) / (cl_precision(df) + cl_sensitivity(df))
return(f1score)
}
f1_score_function <- function(cl_precision, cl_sensitivity){
f1_score <- (2*cl_precision*cl_sensitivity)/(cl_precision+cl_sensitivity)
return (f1_score)
}
(f1_score_function(0, .5))
## [1] 0
## [1] 1
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.01996 0.22535 0.36911 0.39160 0.51737 0.92954
Shows how the true positive rate against the false positive rate at various threshold settings. The AUC (Area Under Curve) tells how much model is capable of distinguishing between classes. Higher the AUC is better, that is, how well the model is at predicting 0s as 0s and 1s as 1s.
Creating an ROC Function
ROC <- function(x, y){
x <- x[order(y, decreasing = TRUE)]
t_p_r <- cumsum(x) / sum(x)
f_p_r <- cumsum(!x) / sum(!x)
xy <- data.frame(t_p_r,f_p_r, x)
f_p_r_df <- c(diff(xy$f_p_r), 0)
t_p_r_df <- c(diff(xy$t_p_r), 0)
A_U_C <- round(sum(xy$t_p_r *f_p_r_df) + sum(t_p_r_df *f_p_r_df)/2, 4)
plot(xy$f_p_r, xy$t_p_r, type = "l",
main = "ROC Curve",
xlab = "False Postive Rate",
ylab = "True Positive Rate")
abline(a = 0, b = 1)
legend(.6, .4, A_U_C, title = "Area Under Curve")
}
## $rect
## $rect$w
## [1] 0.2621094
##
## $rect$h
## [1] 0.2041679
##
## $rect$left
## [1] 0.6
##
## $rect$top
## [1] 0.4
##
##
## $text
## $text$x
## [1] 0.7038086
##
## $text$y
## [1] 0.2638881
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
Despite the custom and built-in functions for both ROC curves are slightly different, the measure is still the same rounded off to the nearest tenths (0.91
). However, the second ROC curve is more accurate.
Listed below are the results of metrics done for the classification model that was chosen (Model 1).
Metric <- c('Accuracy','Classification Error Rate', 'Precision', 'Sensitivity','Specificity', 'F1 Score')
Score <- round(c(cl_accuracy(ntrain.scaled), cl_cer(ntrain.scaled), cl_precision (ntrain.scaled), cl_sensitivity(ntrain.scaled), cl_specificity(ntrain.scaled), cl_f1score(ntrain.scaled)),4)
df_1 <- as.data.frame(cbind(Metric, Score))
kable(df_1)
Metric | Score |
---|---|
Accuracy | 0.912 |
Classification Error Rate | 0.088 |
Precision | 0.9159 |
Sensitivity | 0.9039 |
Specificity | 0.9198 |
F1 Score | 0.9099 |
confusionMatrix(data=factor(ntrain.scaled$target), factor(ntrain.scaled$pred.class), positive = "1")
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 218 19
## 1 22 207
##
## Accuracy : 0.912
## 95% CI : (0.8825, 0.9361)
## No Information Rate : 0.515
## P-Value [Acc > NIR] : <2e-16
##
## Kappa : 0.8239
##
## Mcnemar's Test P-Value : 0.7548
##
## Sensitivity : 0.9159
## Specificity : 0.9083
## Pos Pred Value : 0.9039
## Neg Pred Value : 0.9198
## Prevalence : 0.4850
## Detection Rate : 0.4442
## Detection Prevalence : 0.4914
## Balanced Accuracy : 0.9121
##
## 'Positive' Class : 1
##
Compared with the custom functions used, the results are swapped.
Find Source Code on GITHUB