记录Coursera的“可重复研究”课程中的回归代码说明

问题描述 投票:1回答:2

在参加Coursera的“可重复研究”课程时,我无法理解教师用于对数回归的代码。

此代码使用kernlab库的垃圾数据集中的数据。此数据将4601封电子邮件归类为垃圾邮件或非垃圾邮件。除了这个类标签外,还有57个变量表示电子邮件中某些单词和字符的频率。数据已在测试和训练数据集之间分配。

该代码特别是采用训练数据集(“trainSpam”)。它应该做的是遍历数据集中的每个变量并尝试拟合一般化模型,在这种情况下是逻辑回归,通过仅使用单个变量来预测电子邮件是否是垃圾邮件。

我真的不明白代码中的某些行正在做什么。有人可以向我解释一下。谢谢。

trainSpam$numType = as.numeric(trainSpam$type) - 1 ## here a new column is just being created assigning 0 and 1 for spam and nonspam emails

costFunction = function(x,y) sum(x != (y > 0.5)) ## I understand a function is being created but I really don't understand what the function "costFunction" is supposed to do. I could really use and explanation for this

cvError = rep(NA,55)
library(boot)
for (i in 1:55){
    lmFormula = reformulate(names(trainSpam)[i], response = "numType") ## I really don't understand this line of code either

    glmFit = glm(lmFormula, family = "binomial", data = trainSpam)

    cvError[i] = cv.glm(trainSpam, glmFit, costFunction, 2)$delta[2]
}
names(trainSpam)[which.min(cvError)]
r logistic-regression
2个回答
0
投票

在演讲的7:13,数据分析第2部分的结构,彭教授解释说他将循环遍历来自spam包的kernlab数据集中的所有自变量。然后,他在预测数据集中的特定电子邮件是否为垃圾邮件时运行一组线性模型,以查看哪个变量具有最低的交叉验证错误率。

costFunction()中使用cv.glm()函数来比较numType的实际值与预测值。它总结了实际值不等于predicted> 0.5的逻辑比较结果的计数。

lmformula = reformulate(...)线创建一个线性模型公式,随着for()循环的每次迭代而变化,将因变量设置为numType

for()循环的输出是一个计数向量,其中来自每个numTypeglm()的实际值与垃圾邮件与非垃圾邮件的实际分类不匹配。代码names(trainSpam)[which.min(cvError)]的最后一行计算cvError向量中的索引具有最低值,并使用它从trainSpam数据帧中提取独立变量名。

此示例的完整代码是:

library(kernlab)

data(spam)
set.seed(3435)
trainIndicator = rbinom(4601,size=1,prob=0.5)
table(trainIndicator)
trainSpam = spam[trainIndicator==1,]
testSpam = spam[trainIndicator==0,]

trainSpam$numType = as.numeric(trainSpam$type)-1
costFunction = function(x,y) sum(x!=(y > 0.5)) 
cvError = rep(NA,55)
library(boot)
for(i in 1:55){
     lmFormula = reformulate(names(trainSpam)[i], response = "numType")
     glmFit = glm(lmFormula,family="binomial",data=trainSpam)
     cvError[i] = cv.glm(trainSpam,glmFit,costFunction,2)$delta[2]
}

## Which predictor has minimum cross-validated error?
names(trainSpam)[which.min(cvError)]

......和输出:

> names(trainSpam)[which.min(cvError)]
[1] "charDollar"
>

...意味着电子邮件中的美元符号数是在预测测试数据集中的垃圾邮件时具有最低交叉验证错误率的自变量。


1
投票

解释如下。我花了大约2-3个小时将整个东西包裹在我的脑袋里,但这是我的解释。

目标

目标:找一个“简单模型” (二项式回归) 最少“错误” (交叉验证错误) ,当我们使用“简单模型”进行预测时。

数据集我们仅使用trainSpam数据集来制作预测模型。每个单元格具有表示给定电子邮件(行)的单词(由列给出)的出现的数值。例如,charDollar列的第2行的f为0.054。这意味着第二封邮件在邮件中有0.054个$符号。

数据本质上是二项式的,即非垃圾邮件为0,垃圾邮件为1。这是用数字表示的:

trainSpam$numType = as.numeric(trainSpam$type)-1

曲线拟合

二项式回归由于数据是二项式的,我们拟合一条曲线,~~二项式回归~~根据值预测邮件是垃圾邮件的概率。例如,查看列charDollar

png(filename="glm.png")
lmFormula=numType~charDollar
plot(lmFormula,data=trainSpam, ylab="probability")
g=glm(lmFormula,family=binomial, data=trainSpam)
curve(predict(g,data.frame(charDollar=x),type="resp"),add=TRUE)
dev.off()

GLM

在这里,您可以看到,对于charDollar值> 0.5,几乎有100%的可能性是垃圾邮件。这就是二项式回归的使用方法。

作者查看每一列,使二项式回归拟合。这是通过for loop完成的。所以作者现在有55个型号。

Error Estimation

作者希望看到这55个模型中的哪一个预测“最佳”。为此,我们使用交叉验证...

cv.glm或交叉验证

交叉验证的工作原理如下:它将trainData进一步划分为TRAIN和TEST。 TRAIN数据用于计算glm,该glm用于预测TEST数据的结果。这是多次完成“in a particular way”,结果是平均的。

CV使用成本函数来计算错误。

cost function(在这种情况下)计算失败预测的数量。 TEST数据用于此目的。它需要两个参数,即X(观察到的TEST数据)和Y(基于glm的预测数据),并检查在这种情况下失败的次数:

costFunction = function(x,y) sum(x!=(y > 0.5))

Y>0.5提供了一个截止值来判断某个值是否为垃圾邮件。因此,如果预测值是0.6,则预测是SPAM(或1)。如果预测值是<=0.5那么它不是垃圾邮件(或0)。

使用for循环,我们在每一列上循环,最后在pic中循环预测错误最小的列:

which.min(cvError)

P.S看看glm binomial fitting (including timestamp)是如何完成的,以及coefficients that come from glm的解释以及获得cross-validated error意味着什么是非常有益的。然而,我同意这个课程在这方面做了大幅度的跳跃,没有费心去解释与此相关的任何事情。希望这是有帮助的。

© www.soinside.com 2019 - 2024. All rights reserved.