利用机器学习算法进行汽车接受程度预测
分类算法
分类算法是基于有类标号的训练集数据建立分类模型并使用其对新观测值(测试数据集)进行分类的算法,属于有监督学习。
对于有监督学习,主要需要建立合适的分类器,对不同类型的数据集进行恰当的分类,达到较高的准确率或召回率或F-score值。
同时不同方法,对于不同问题带来的效果是不同的,比如决策树算法有明确的规则输出而使得模型通俗易懂,能得到一些维度的重要性程度等,或许准确率有待提高,但是也是一种很有价值的算法。
汽车满意度数据集
汽车已经成为了人们出行必不可少的工具之一。现在各个汽车销售商也是想方设法提高汽车的销售量。但汽车的销售量是由什么决定的呢?
换而言之,汽车的销售量是由客户的满意度来决定的。我们又想问,汽车的满意度是主要由什么决定的呢?汽车的价格,质量,舒服度哪个因素起的作用更大呢?
有这样一份数据集:
- buy: buying price(购买价格,分为low, med, high, vhigh)
- main: price of the maintenance(保养价格,分为low, med, high, vhigh)
- doors: number of doors(门的个数,分为2, 3, 4, 5more)
- capacity: capacity in terms of persons to carry(载人个数)
- lug_boot: the size of luggage boot(车身的大小,分为small, med, big)
- safety: estimated safety of the car(安全程度,分为low, med, high)
- accept: car acceptability(被接受程度,四个等级:unacc, acc, good, vgood)
> head(car)
buy main doors capacity lug_boot safety accept
1 vhigh vhigh 2 2 small low unacc
2 vhigh vhigh 2 2 small med unacc
3 vhigh vhigh 2 2 small high unacc
4 vhigh vhigh 2 2 med low unacc
5 vhigh vhigh 2 2 med med unacc
6 vhigh vhigh 2 2 med high unacc
我们根据buy, main,doors, capacity, lug_boot, safety来预测accept的值 ,其中自变量和因变量为均为有序变量。
朴素贝叶斯分类
朴素贝叶斯分类是一种十分简单的分类算法,是一个基于概率的分类器,源于贝叶斯理论。
它的前提假设是:样本属性之间相互独立。
思路: 对于给出的待分类项,求解在此项出现的条件下的各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。
导入相应数据,划分训练测试集
# 朴素贝叶斯分类
# 导入car数据集
car <- read.table("car.data",sep = ",")
# 对变量重命名
colnames(car) <- c("buy","main","doors","capacity",
"lug_boot","safety","accept")
# 随机选取75%的数据作为训练集建立模型,25%的数据作为测试集用来验证模型
library(caret)
# 构建训练集的下标集
ind <- createDataPartition(car$accept,times=1,p=0.75,list=FALSE)
# 构建测试集数据好训练集数据
carTR <- car[ind,]
carTE <- car[-ind,]
建立分类器
# 使用naiveBayes函数建立朴素贝叶斯分类器
library(e1071)
naiveBayes.model <- naiveBayes(accept~.,data=carTR)
# 预测结果
carTR_predict <- predict(naiveBayes.model,newdata=carTR) # 训练集数据
carTE_predict <- predict(naiveBayes.model,newdata=carTE) # 测试集数据
# 构建混淆矩阵
tableTR <- table(actual=carTR$accept,predict=carTR_predict)
tableTE <- table(actual=carTE$accept,predict=carTE_predict)
# 计算误差率
errTR <- paste0(round((sum(tableTR)-sum(diag(tableTR)))*100/sum(tableTR),2),"%")
errTE <- paste0(round((sum(tableTE)-sum(diag(tableTE)))*100/sum(tableTE),2),"%")
errTR;errTE
结果如下:
> tableTR
predict
actual acc good unacc vgood
acc 201 8 79 0
good 34 16 0 2
unacc 27 2 879 0
vgood 18 1 0 30
> tableTE
predict
actual acc good unacc vgood
acc 71 2 23 0
good 11 6 0 0
unacc 7 0 295 0
vgood 7 1 0 8
> errTR;errTE
[1] "13.18%"
[1] "11.83%"
朴素贝叶斯算法优缺点
主要优点有:
- 朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率。
- 对小规模的数据表现很好,能个处理多分类任务,适合增量式训练,尤其是数据量超出内存时,我们可以一批批的去增量训练。
- 对缺失数据不太敏感,算法也比较简单,常用于文本分类 (如新闻文本分类,政务留言分类)。
主要缺点有:
- 理论上,朴素贝叶斯模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为朴素贝叶斯模型假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比较多或者属性之间相关性较大时,分类效果不好。而在属性相关性较小时,朴素贝叶斯性能最为良好。对于这一点,有半朴素贝叶斯之类的算法通过考虑部分关联性适度改进。
- 需要知道先验概率,且先验概率很多时候取决于假设,假设的模型可以有很多种,因此在某些时候会由于假设的先验模型的原因导致预测效果不佳。
- 由于我们是通过先验和数据来决定后验的概率从而决定分类,所以分类决策存在一定的错误率。
- 对输入数据的表达形式很敏感。
决策树算法建立分类树
决策树是一种树状分类结构模型。它是一种通过拆分变量值建立分类规则,又利用树形图分割形成概念路径的数据分析技术。
决策树的基本思想:
- 对特征空间按变量对分类效果影响大小选择变量和变量值。
- 用选出的变量和变量值对数据区域进行矩阵划分,在不同的划分区间比较效果和模型复杂度,从而确定最合适的划分,分类结果由最终划分区域的优势类决定。
决策树主要用于分类,也可以用于回归,与分类的主要差异在于选择变量的标准不是分类的效果,而是预测误差。
当决策树的输出变量是分类变量时,叫分类树,当决策树的输出变量为连续变量时,称为回归树。
虽然回归树的因变量是连续变量,但是叶节点数据是有穷的。
且回归树不用假定经典回归中的诸如独立性,正态性,线性等特性,无论自变量是定性还是定量数据都适用。
建立分类树
# 使用决策树算法建立分类树
# 使用C50函数实现C5.0算法
library(C50)
C5.0.model <- C5.0(accept~.,data=carTR)
# 使用rpart函数实现CART算法
library(rpart)
rpart.model <- rpart(accept~.,data=carTR)
# 使用ctree函数实现条件推理决策树算法
library(party)
ctree.model <- ctree(accept~.,data=carTR)
# 预测结果,并构建混淆矩阵,查看准确率
# 构建result,存放预测结果
result <- data.frame(arithmetic=c("C5.0","CART","ctree"),
errTR=rep(0,3),errTE=rep(0,3))
for(i in 1:3){
# 预测结果
carTR_predict <- predict(switch(i,C5.0.model,rpart.model,ctree.model),
newdata=carTR,
type=switch(i,"class","class","response")) # 训练集数据
carTE_predict <- predict(switch(i,C5.0.model,rpart.model,ctree.model),
newdata=carTE,
type=switch(i,"class","class","response")) # 测试集数据
# 构建混淆矩阵
tableTR <- table(actual=carTR$accept,predict=carTR_predict)
tableTE <- table(actual=carTE$accept,predict=carTE_predict)
# 计算误差率
result[i,2] <- paste0(round((sum(tableTR)-sum(diag(tableTR)))*100/sum(tableTR),
2),"%")
result[i,3] <- paste0(round((sum(tableTE)-sum(diag(tableTE)))*100/sum(tableTE),
2),"%")
}
# 查看结果
result
结果如下:
> result
arithmetic errTR errTE
1 C5.0 1.16% 1.86%
2 CART 6.09% 4.18%
3 ctree 5.09% 3.94%
可得:决策树算法优于前面的朴素贝叶斯算法,而C5.0算法优于其他两种决策树算法。
对分类器进行可视化
library(sparkline)
library(visNetwork)
## 通过可视化参数复杂性图像进行参数选择
plotcp(rpart.model)
visTree(rpart.model,main = "决策树模型",height = "400px",
colorY = c("red","blue","green"))
每一个深度的决策树(图的上横坐标)都对应着一个复杂性程度的阈值(图的横坐标),而且每个cp取值会对一个相对误差(图的纵坐标),所以可以通过设置参数cp的取值对决策树模型进行剪枝优化。根据图中曲线的变化情况,可发现当cp取值为0.013时,模型的相对误差最低,所以可以根据该参数的取值训练新的决策树分类器。
放大到局部便可观察:
library(ggplot2)
## 可视化每个变量的重要性
varimp <- rpart.model$variable.importance
varimpdf <- data.frame(var = names(varimp),
impor = varimp)
ggplot(varimpdf,aes(x = reorder(var,-impor), y = impor))+
geom_col(colour = "lightblue",fill = "lightblue")+
labs(x = "变量", y = "重要性")
可根据可视化图形,判断节点的重要性。
决策树的优缺点
优点:
- 速度快: 计算量相对较小, 且容易转化成分类规则. 只要沿着树根向下一直走到叶, 沿途的分裂条件就能够唯一确定一条分类的谓词.
- 确性高: 挖掘出来的分类规则准确性高, 便于理解, 决策树可以清晰的显示哪些字段比较重要, 即可以生成可以理解的规则.(如泰坦尼克号生存预测)
- 可以处理定性和定量字段
- 不需要参数假设
- 适合高维数据
缺点:
- 对于各类别样本数量不一致的数据, 信息增益偏向于那些更多数值的特征
- 容易过拟合
- 忽略属性之间的相关性
预测结果可视化
library(ggpol)
ggplot() + geom_confmat(aes(x = carTE$accept, y = carTE_predict),
normalize = TRUE, text.perc = TRUE)+
labs(x = "Reference",y = "Prediction")+
scale_fill_gradient2(low="darkblue", high="lightgreen")