1、读入数据
library(pacman)
p_load(dplyr, readr, DataExplorer)
glass <- read_csv("data_set/glass.data", col_names = F)
str(glass)
## tibble [214 × 11] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ X1 : num [1:214] 1 2 3 4 5 6 7 8 9 10 ...
## $ X2 : num [1:214] 1.52 1.52 1.52 1.52 1.52 ...
## $ X3 : num [1:214] 13.6 13.9 13.5 13.2 13.3 ...
## $ X4 : num [1:214] 4.49 3.6 3.55 3.69 3.62 3.61 3.6 3.61 3.58 3.6 ...
## $ X5 : num [1:214] 1.1 1.36 1.54 1.29 1.24 1.62 1.14 1.05 1.37 1.36 ...
## $ X6 : num [1:214] 71.8 72.7 73 72.6 73.1 ...
## $ X7 : num [1:214] 0.06 0.48 0.39 0.57 0.55 0.64 0.58 0.57 0.56 0.57 ...
## $ X8 : num [1:214] 8.75 7.83 7.78 8.22 8.07 8.07 8.17 8.24 8.3 8.4 ...
## $ X9 : num [1:214] 0 0 0 0 0 0 0 0 0 0 ...
## $ X10: num [1:214] 0 0 0 0 0 0.26 0 0 0 0.11 ...
## $ X11: num [1:214] 1 1 1 1 1 1 1 1 1 1 ...
## - attr(*, "spec")=
## .. cols(
## .. X1 = col_double(),
## .. X2 = col_double(),
## .. X3 = col_double(),
## .. X4 = col_double(),
## .. X5 = col_double(),
## .. X6 = col_double(),
## .. X7 = col_double(),
## .. X8 = col_double(),
## .. X9 = col_double(),
## .. X10 = col_double(),
## .. X11 = col_double()
## .. )
# 设置列名
names(glass) <- c('Id', 'RI', 'Na', 'Mg', 'Al', 'Si',
'K', 'Ca', 'Ba', 'Fe', 'Type')
# 使用train函数时对levels命名有要求
glass$Type <- paste0("C", glass$Type) %>%
factor(levels = paste0("C", unique(glass$Type)))
2、探索性数据分析
# 检查缺失值
profile_missing(glass)
## # A tibble: 11 x 3
## feature num_missing pct_missing
## <fct> <int> <dbl>
## 1 Id 0 0
## 2 RI 0 0
## 3 Na 0 0
## 4 Mg 0 0
## 5 Al 0 0
## 6 Si 0 0
## 7 K 0 0
## 8 Ca 0 0
## 9 Ba 0 0
## 10 Fe 0 0
## 11 Type 0 0
数据集无缺失值。
# 数据描述
summary(glass)
## Id RI Na
## Min. : 1.00 Min. :1.511 Min. :10.73
## 1st Qu.: 54.25 1st Qu.:1.517 1st Qu.:12.91
## Median :107.50 Median :1.518 Median :13.30
## Mean :107.50 Mean :1.518 Mean :13.41
## 3rd Qu.:160.75 3rd Qu.:1.519 3rd Qu.:13.82
## Max. :214.00 Max. :1.534 Max. :17.38
## Mg Al Si
## Min. :0.000 Min. :0.290 Min. :69.81
## 1st Qu.:2.115 1st Qu.:1.190 1st Qu.:72.28
## Median :3.480 Median :1.360 Median :72.79
## Mean :2.685 Mean :1.445 Mean :72.65
## 3rd Qu.:3.600 3rd Qu.:1.630 3rd Qu.:73.09
## Max. :4.490 Max. :3.500 Max. :75.41
## K Ca Ba
## Min. :0.0000 Min. : 5.430 Min. :0.000
## 1st Qu.:0.1225 1st Qu.: 8.240 1st Qu.:0.000
## Median :0.5550 Median : 8.600 Median :0.000
## Mean :0.4971 Mean : 8.957 Mean :0.175
## 3rd Qu.:0.6100 3rd Qu.: 9.172 3rd Qu.:0.000
## Max. :6.2100 Max. :16.190 Max. :3.150
## Fe Type
## Min. :0.00000 C1:70
## 1st Qu.:0.00000 C2:76
## Median :0.00000 C3:17
## Mean :0.05701 C5:13
## 3rd Qu.:0.10000 C6: 9
## Max. :0.51000 C7:29
查看1分位和3分位数值,发现数据存在偏斜。
# 检查相关性
cor(glass[, -11]) %>%
as.data.frame() %>%
GGally::ggpairs(progress = F)
相关性
存在相关性超过0.9的特征。(显示器分辨率太低,将就着看吧。。)
3、预处理
Z-评分归一化(center,scale):当输入特征接近正态分布的时候使用,原理是对特征减去其均值然后除以其标准差。
极差归一化(range):当输入特征均匀分布时使用,按比例缩放所有的特征和输出,让它们处于某个区间内,通常是[0, 1]。
博克斯-考克斯变换(BoxCox):当输入特征出现高度偏斜(不对称),而模型要求输入特征服从正态分布或至少是对称分布的情况。
findCorrelation():corr,剔除高相关性的特征,默认值为相关性的绝对值大于等于0.9。
findLinearCombos():剔除相互为严格的线性组合的特征。
nearZeroVar():nzv,剔除常数特征或方差几乎为0的特征。
pca:主成分分析。pca是一种无监督的降维方法,它不需要利用输出变量,即使输出结果能够获得。相反,它是从几何的角度去看待特征空间里的数据的,这意味着我们不能确保pca给出的新的特征空间一定能在预测问题里有良好表现,它只能带来更少特征空间的计算优势。
采用三种不同的预处理方式:
p_load(caret)
# 需要转换为dataframe
glass.num <- glass[, 1:10] %>% as.data.frame()
pre.boxcox <- preProcess(glass.num, method = c("BoxCox"))
pre.scale <- preProcess(glass.num, method = c("center", "scale"))
pre.pca <- preProcess(glass.num, method = c("pca"), thresh = 0.95)
glass.boxcox <- predict(pre.boxcox, glass.num) %>%
cbind(Type = glass$Type)
glass.scale <- predict(pre.scale, glass.num) %>%
cbind(Type = glass$Type)
glass.pca <- predict(pre.pca, glass.num) %>%
cbind(Type = glass$Type)
4、拆分训练集和测试集
set.seed(123)
ind1 <- createDataPartition(glass.boxcox$Type, p = 0.85, list = F)
dtrain1 <- glass.boxcox[ind1, ]
dtest1 <- glass.boxcox[-ind1, ]
set.seed(123)
ind2 <- createDataPartition(glass.scale$Type, p = 0.85, list = F)
dtrain2 <- glass.scale[ind2, ]
dtest2 <- glass.scale[-ind2, ]
set.seed(123)
ind3 <- createDataPartition(glass.pca$Type, p = 0.85, list = F)
dtrain3 <- glass.pca[ind3, ]
dtest3 <- glass.pca[-ind3, ]
5、设置K折(十折)交叉验证
ct <- trainControl(method = "CV", number = 10, classProbs = T,
allowParallel = T)
6、设置多线程运行
p_load(parallel)
# linux系统才能设置type = "FORK"
cl <- makeCluster(detectCores(), type = "FORK")
# 注册集群
doParallel::registerDoParallel(cl)
8、K近邻模型
在原始训练数据中查找K个和新数据点最相似的观测,然后针对已知的这K个邻居的目标函数值,利用某种求均值的技术来计算出一个预测值。
knn1 <- train(Type ~ ., data = dtrain1,
method = "knn", trControl = ct)
knn2 <- train(Type ~ ., data = dtrain2,
method = "knn", trControl = ct)
knn3 <- train(Type ~ ., data = dtrain3,
method = "knn", trControl = ct)
# 停止多线程
stopCluster(cl)
9、模型对比
res <- resamples(list(knn1, knn2, knn3))
summary(res)
##
## Call:
## summary.resamples(object = res)
##
## Models: Model1, Model2, Model3
## Number of resamples: 10
##
## Accuracy
## Min. 1st Qu. Median Mean 3rd Qu.
## Model1 0.6315789 0.7136223 0.7836257 0.7683557 0.8250000
## Model2 0.6842105 0.7291667 0.7697368 0.8080775 0.8888889
## Model3 0.6666667 0.7401316 0.8065015 0.8008858 0.8421053
## Max. NA's
## Model1 0.8823529 0
## Model2 0.9473684 0
## Model3 0.9411765 0
##
## Kappa
## Min. 1st Qu. Median Mean 3rd Qu.
## Model1 0.5145985 0.6017082 0.7016542 0.6838013 0.7613493
## Model2 0.5564202 0.6373818 0.6859553 0.7351986 0.8474493
## Model3 0.5443038 0.6376223 0.7241926 0.7250081 0.7920889
## Max. NA's
## Model1 0.8373206 0
## Model2 0.9296296 0
## Model3 0.9174757 0
bwplot(res, main = "不同预处理方式模型性能对比")
模型对比
最终选择模型3,使用主成分分析后的模型。
10、测试集验证
knn.pred3 <- predict(knn3, newdata = dtest3, type = "raw")
11、测试集上的精确度指标
卡巴统计量(Kappa)是用来抵消随机因素的,计算公式为:
kappa=(观测到的精确度-期望精确度)/(1-期望精确度)
它的取值范围为[-1, 1],其中1代表完全精确,-1代表完全不精确,而0是在精确度切好等于随机猜测时出现的。
查准率(precision):准确预测的阳性类例数占总阳性类例数的比例。
查全率(recall):阳性类正确预测的例数在数据集里所有阳性类例数中的占比。
F1分数:查准率和查全率之间的调和平均数。
F1=2(precision*recall)/(precision+recall)
postResample(knn.pred3, dtest3$Type)
## Accuracy Kappa
## 0.8965517 0.8479021
confusionMatrix(knn.pred3, dtest3$Type)
## Confusion Matrix and Statistics
##
## Reference
## Prediction C1 C2 C3 C5 C6 C7
## C1 10 0 0 0 0 0
## C2 0 11 1 0 1 1
## C3 0 0 1 0 0 0
## C5 0 0 0 1 0 0
## C6 0 0 0 0 0 0
## C7 0 0 0 0 0 3
##
## Overall Statistics
##
## Accuracy : 0.8966
## 95% CI : (0.7265, 0.9781)
## No Information Rate : 0.3793
## P-Value [Acc > NIR] : 1.059e-08
##
## Kappa : 0.8479
##
## Mcnemar's Test P-Value : NA
##
## Statistics by Class:
##
## Class: C1 Class: C2 Class: C3
## Sensitivity 1.0000 1.0000 0.50000
## Specificity 1.0000 0.8333 1.00000
## Pos Pred Value 1.0000 0.7857 1.00000
## Neg Pred Value 1.0000 1.0000 0.96429
## Prevalence 0.3448 0.3793 0.06897
## Detection Rate 0.3448 0.3793 0.03448
## Detection Prevalence 0.3448 0.4828 0.03448
## Balanced Accuracy 1.0000 0.9167 0.75000
## Class: C5 Class: C6 Class: C7
## Sensitivity 1.00000 0.00000 0.7500
## Specificity 1.00000 1.00000 1.0000
## Pos Pred Value 1.00000 NaN 1.0000
## Neg Pred Value 1.00000 0.96552 0.9615
## Prevalence 0.03448 0.03448 0.1379
## Detection Rate 0.03448 0.00000 0.1034
## Detection Prevalence 0.03448 0.00000 0.1034
## Balanced Accuracy 1.00000 0.50000 0.8750
Accuracy为0.8965517,Kappa值为0.8479021。
网友评论