R中启动库的cv.glm中的代价函数
我试图使用R中启动库中的crossvalidation cv.glm函数来确定应用glm逻辑回归时的错误分类数 该函数具有以下签名:R中启动库的cv.glm中的代价函数,r,glm,cross-validation,R,Glm,Cross Validation,我试图使用R中启动库中的crossvalidation cv.glm函数来确定应用glm逻辑回归时的错误分类数 该函数具有以下签名: cv.glm(data, glmfit, cost, K) 前两个表示数据和模型,K表示K倍。 我的问题是成本参数,其定义如下: 成本:由两个向量参数组成的函数,指定成本函数 用于交叉验证。成本的第一个论点应该是一致的 对于观察到的响应,第二个参数应与 广义线性模型的预测或拟合响应。 成本必须返回非负的标量值。默认值是 平均平方误差函数。 我想对于分类来说,有一
cv.glm(data, glmfit, cost, K)
前两个表示数据和模型,K表示K倍。
我的问题是成本参数,其定义如下:
成本:由两个向量参数组成的函数,指定成本函数
用于交叉验证。成本的第一个论点应该是一致的
对于观察到的响应,第二个参数应与
广义线性模型的预测或拟合响应。
成本必须返回非负的标量值。默认值是
平均平方误差函数。
我想对于分类来说,有一个函数返回误分类率是有意义的,比如:
nrow(subset(data, (predict >= 0.5 & data$response == "no") |
(predict < 0.5 & data$response == "yes")))
nrow(子集(数据,(预测>=0.5和数据$response==“否”)|
(预测值<0.5,数据$response==“是”))
当然,这在语法上是不正确的
不幸的是,我有限的R知识让我浪费了很多时间,我想知道是否有人能给我指出正确的方向 听起来,您最好只使用
?cv.glm
的“示例”部分中进一步定义的成本函数(即名为cost
)。引述该节:
# [...] Since the response is a binary variable an
# appropriate cost function is
cost <- function(r, pi = 0) mean(abs(r-pi) > 0.5)
我猜这其中最棘手的一点就是让你的思想完全围绕着把一个函数作为参数传入的想法。(至少对我来说,在最长的一段时间里,这是使用boot软件包最困难的部分,它需要在相当多的地方移动。)
于2016年3月22日添加: 我认为上面给出的函数
cost()
,是不必要的混淆;以下备选方案的作用完全相同,但更具表现力:
cost <- function(r, pi = 0) {
mean((pi < 0.5) & r==1 | (pi > 0.5) & r==0)
}
成本(0.5)&r==0)
}
如果存在一个优于默认平均平方误差的函数,则可以选择定义成本函数。如果您想这样做,那么您将编写一个函数,使用两个输入返回您希望最小化的成本:(1)您正在预测的已知标签的向量,以及(2)这些对应标签的模型预测概率的向量。因此,对于(我认为)您在文章中描述的成本函数,您正在寻找一个函数,该函数将返回准确分类的平均数量,如下所示:
cost <- function(labels,pred){
mean(labels==ifelse(pred > 0.5, 1, 0))
}
我将尝试用简单的语言解释成本函数。让我们坐飞机吧
cv.glm(数据、glmfit、成本、K)
参数逐步:
数据
这些数据包括许多观察结果。把它想象成一系列的数字,甚至是数字glmfit
它是广义线性模型,运行在上述序列上。但是有一个陷阱,它将数据分成几个等于K的部分,并分别对每个部分(测试集)运行glmfit
,将其余部分作为训练集。glmfit
的输出是一个系列,由与传递的拆分输入相同数量的元素组成成本
成本函数。它接受两个参数,第一个是分割输入序列(测试集),第二个是测试输入上的glmfit
的输出。默认值为均方误差函数。
.
它将观测数据点和预测数据点之间的差值平方相加。在函数内部,循环在测试集上运行(输出和输入应具有相同数量的元素),计算差异,将其平方并添加到输出变量K
输入应拆分到的编号。默认情况下,不进行交叉验证cost<- function(x, y){
e=0
for (i in 1:length(x)){
if(x[i]>0.5)
{
if( y[i]=='yes') {e=0}
else {e=x[i]-0.5}
}else
{
if( y[i]=='no') {e=0}
else {e=0.5-x[i]}
}
e=e*e #square error
}
e=e/i #mean square error
return (e)
}
cost0.5)
{
如果(y[i]=='yes'){e=0}
else{e=x[i]-0.5}
}否则
{
如果(y[i]=='no'){e=0}
else{e=0.5-x[i]}
}
e=e*e#平方误差
}
e=e/i#均方误差
返回(e)
}
来源:示例中为
cv.glm
定义的成本函数明确假设预测是概率,这将需要predict
函数中的type=“response”
参数。库中的文档(boot)应该明确说明这一点。否则,我将被迫假设默认的type=“link”
是在cv.glm
函数中使用的,在这种情况下,成本函数将无法按预期工作。要查看提供给成本=
参数的函数如何在调用cv.glm()
中使用,执行调试(cv.glm)
,然后在?cv.glm
中运行第二个示例,在浏览器中逐步完成其计算,直到到达实际调用的点,这可能会很有帮助。祝你好运;)
> library(boot)
>
> cost <- function(labels,pred){
+ mean(labels==ifelse(pred > 0.5, 1, 0))
+ }
>
> #make model
> nodal.glm <- glm(r ~ stage+xray+acid, binomial, data = nodal)
> #run cv with your cost function
> (nodal.glm.err <- cv.glm(nodal, nodal.glm, cost, nrow(nodal)))
$call
cv.glm(data = nodal, glmfit = nodal.glm, cost = cost, K = nrow(nodal))
$K
[1] 53
$delta
[1] 0.8113208 0.8113208
$seed
[1] 403 213 -2068233650 1849869992 -1836368725 -1035813431 1075589592 -782251898
...
cost<- function(x, y){
e=0
for (i in 1:length(x)){
if(x[i]>0.5)
{
if( y[i]=='yes') {e=0}
else {e=x[i]-0.5}
}else
{
if( y[i]=='no') {e=0}
else {e=0.5-x[i]}
}
e=e*e #square error
}
e=e/i #mean square error
return (e)
}