ESL-chapter9-加法模型和决策树

来源:互联网 发布:网络品牌维护 编辑:程序博客网 时间:2024/05/21 11:01

加法模型就是把特征看成是相互独立的。对每个特征进行各自拟合(如样条,多项式等),然后把他们对Y(预测变量)的影响加起来。前面是理论部分,不解释。直接看示例-预测垃圾邮件。

spam数据集有4601条email信息。我们希望从这些数据中,总结一封邮件是正常的emai还是spam(垃圾邮件)的规律出来。这些数据有57个特征和一个类标签。1代表垃圾邮件spam,0代表email。下面用加法模型来预测垃圾邮件

spam <- read.table("spam.data")
spam.train <- sample(4601,3065) 
spam.x <- spam[,-58]
spam.y <- spam[,58]
spam.x.log <- log(spam.x+0.1)#把长尾分布的数据进行转换。

V.x <- paste(paste("s(V",1:57,",4)",sep = ""), collapse='+')
form<- paste("spam.y~",V.x,sep = "")#处理一下特征,组合成满足需求的形式
form = formula(form)
gam.spam=gam(form,data=data.frame(spam.x.log,spam.y),subset=spam.train,family="binomial")#拟合模型
preds.spam=predict(gam.spam,newdata=data.frame(spam.x.log)[-spam.train,],type="response")#预测
preds.spam.class <- ifelse(preds.spam>=0.5,1,0)
spam.t <- table(preds.spam.class,spam.y[-spam.train])
(spam.t[2]+spam.t[3])/1536#最后得到错误率0.052,和书上大致一致。

#然后用逻辑回归来拟合模型

logistic.spam <- glm(spam.y~.,data=data.frame(spam.x.log,spam.y),subset=spam.train,family="binomial")
preds.logistic.spam=predict(logistic.spam,newdata=data.frame(spam.x.log)[-spam.train,],type="response")
preds.logistic.spam.class <- ifelse(preds.logistic.spam>=0.5,1,0)
logistic.spam.t <- table(preds.logistic.spam.class,spam.y[-spam.train])
(logistic.spam.t[2]+logistic.spam.t[3])/1536# 结果为0.058

我用上面的算法多次运行,比较逻辑回归和加法模型,发现加法模型略好,但差别并不是很大,而书上声称加法模型能更好滴表现非线性的关系。先这样吧。

下面介绍分类树,同样,我们不介绍概念,直接上例子。还是垃圾邮件的例子。

代码如下:

tree.spam.y <- as.factor(spam.y)
tree.spam=tree(tree.spam.y~.,data.frame(spam.x,tree.spam.y),subset=spam.train,mindev=0)
#用训练数据拟合模型
cv.spam =cv.tree(tree.spam ,FUN=prune.misclass,K=10 )#十层交叉验证。
#plot(cv.spam$k ,cv.spam$dev ,type="b")
tree.size <- sort(cv.spam$size)[-1]
misclass.rate <- max(cv.spam$dev)/3065#收集在测试集上的误分类率,由于size=1不能创建模型,所以把第一个元素赋值为交叉验证的第一个数据。
for(i in tree.size)
    {
        prune.spam=prune.misclass(tree.spam,best=i)
        tree.pred=predict(prune.spam,spam.x[-spam.train,],type="class")
        pred.table=table(tree.pred ,tree.spam.y[-spam.train])
        misclass.rate <- c(misclass.rate,(pred.table[2]+pred.table[3])/1536)
    }
plot(sort(cv.spam$size) ,misclass.rate,type="b",col="green",ylim=c(0,0.5))#最后画图
lines(sort(cv.spam$size),sort(cv.spam$dev/3065,decreasing=TRUE),type="b",col="orange")


结果表明测试数据的结果略低一点,这和书上也不太一样。不过大致趋势差不多。

0 0
原创粉丝点击