#分类
#有监督机器学习
#基于一组包含许多可用于分类的方法,
#基于一组包含预测变量值和输出变量值的样本单元
#将全部数据分成一个训练集和一个验证集,其中训练集用于建立预测模型,验证集用于测试模型的准确性
#如逻辑回归,决策树,随机森林,支持向量机,神经网络等
#用训练集建立模型并测试模型会使得模型的有效性被过分夸大
#而用单独的验证集来测试基于训练集得到的模型则可使得估计更准确,更切合实际
#得到一个有效的预测模型后,就可以预测那些只知道预测变量值的样本单元对应的输出值了
#相关包批量安装
pkgs <- c("rpart","rpart.plot","party","randomForest","e1071")
install.packages(pkgs,depend=TRUE)
#范例一 乳腺癌数据准备
#文档路径:http://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/
#文件名: breast-cancer-wisconsin.data
#文件路径长字符串,分开处理
loc <- "http://archive.ics.uci.edu/ml/machine-learning-databases/"
ds <- "breast-cancer-wisconsin/breast-cancer-wisconsin.data"
url <- paste(loc,ds,sep="")
#读取文本文件breast-cancer-wisconsin.data
#data文件中,以逗号分隔
#na.string="?",问号形式的缺失值处理成NA
breast <- read.table(url,sep=",",header=FALSE,na.string="?")
class(breast) #返回 "data.frame"
rownames(breast) #返回1-699的数字编号
colnames(breast) #返回v1~v11的混合编号
#重新命名列名
#1 ID
#2 肿块厚度 clumpThickness
#3 细胞大小的均匀性 sizeUniformity
#4 细胞形状的均匀性 shapeUniformity
#5 边际附着力 maginalAdhesion
#6 单个上皮细胞大小 singleEpithelialCellSize
#7 裸核 bareNuclei
#8 乏味染色体 blandChromatin
#9 正常核 normalNucleoli
#10 有丝分类 mitosis
#11 类别 class
names(breast) <- c("ID","clumpThickness","sizeUniformity",
"shapeUniformity","maginalAdhesion",
"singleEpithelialCellSize","bareNuclei",
"blandChromatin","normalNucleoli","mitosis","class")
head(breast) #查看前六行数据
df <- breast[-1] #删除ID列,其余所有列,行,赋值给df数据框
#类别列,从数值列转换成因子列
#levels 对应原始数值
#labels 对应后续字符
df$class <- factor(df$class,levels=c(2,4),labels=c("benign","malignant"))
#为了保证结果的可复制性,需要设定随机种子
#70% 训练集 30% 测试集
set.seed(1234)
train <- sample(nrow(df),0.7*nrow(df))
df.train <- df[train,] #测试集
df.validate <- df[-train,] #训练集
table(df.train$class) #总样本量:329+160=489
table(df.validate$class) #总样本量:129+81=210
dim(na.omit(df.validate)) #去除缺失值所在行后剩余200行有效数据
#范例一 逻辑回归
#利用训练数据,生成logistic模型
fit.logit <- glm(class~.,data=df.train,family=binomial())
summary(fit.logit)
#结果解读:
#sizeUniformity -0.04805 0.25706 -0.187 0.85171
#shapeUniformity 0.42309 0.26775 1.580 0.11407
#singleEpithelialCellSize 0.11053 0.17980 0.615 0.53871
#P < alpha,落入拒绝域,系数显著为0,可放弃
#利用逐步逻辑回归生成一个包含更少解释变量的模型,其目的是通过增加或移除变量
#来得到一个更小的AIC值
fit.logit <- step(fit.logit)
#利用测试数据,来检验模型
#type="response" 计算概率
prob <- predict(fit.logit,df.validate,type="response")
#将预测值,加条件判断是否大于0.5,
#小于0.5的认定为benign,levels的值对应FALSE,良性的
#大于0.5的认定为malignant,levels的值对应TRUE,恶性的
logit.preb <- factor(prob>0.5,levels=c(FALSE,TRUE),
labels=c("benign","malignant"))
#对评估预测准确性
#基于混淆矩阵(confusion matrix),即预测和实际情况对比的交叉表,来检查正确性
logit.perf <- table(df.validate$class,logit.preb,dnn=c("Actual","Predicted"))
#logit 全变量时的准确率:
#118+76=194
#118+2+4+76=200
#正确率=194/200=0.97=97%
#logit 非全变量时的准确率:
#118+77=195
#118+2+3+77=200
#正确率=195/200=0.97.5=97.5%
#结论:
#精简后的模型在验证集上的误差相对全变量模型更小
#决策树
#决策树是数据挖掘领域中的常用模型
#其基本思想是对预测变量进行二元分离,从而构造一棵可用于预测新样本单元所属类别的树
#其一:经典决策树
#1:选定一个最佳预测变量将全部样本单元分成两类,实现两类中的纯度最大化,即一类中
#良性样本单元尽可能多,另一类中恶性样本单元尽可能多;如果预测变量连续,则选定一个
#分割点进行分类,使得两类纯度最大化
#2:对每一个子类别继续执行步骤
#3:重复步骤1~2,直到子类别中所含的样本单元数过少,或者没有分类法能将不纯度下降
#到一个给定阈值一下,最终集中的子类别即终端节点,根据每一个终端节点中样本单元的类别众数
#来判别这一终端节点的所属类别
#4: 对任一样本单元执行决策树,得到其终端节点
#5:上述算法会得到一颗过大的树,从而出现过拟合现象。结果就是,对于训练集外单元的分类性能较差
#可采用10折交叉验证法选择预测误差最小的树,这一剪枝后的树即可用于预测
#范例二 使用rpart()函数创建分类决策树
library(rpart)
set.seed(1234)
#rpart(formula, data, weights, sub.set, na.action = narpart, method,
#model = FALSE, x = FALSE, y = TRUE, parms, control, cost, ...)
#formula,公式