r - 分配损失时如何解释 rpart(方法 ="class")的 xerror

标签 r machine-learning regression cross-validation

我想修剪我的 rpart 分类树,为此我需要了解分配损失时如何计算交叉验证的分类误差(即 xerror)。 为了简单起见,让我们考虑两类分类问题(比如 A 和 B)。那么根据我的理解,错误是

A 类误分类数 x A 类误分类损失 + B 类错误分类数 x B 类错误分类损失

所以我预计 xerror 是交叉验证数据中的错误。 但是,我在 xerror 中看到非常奇怪的结果。这是一个简单的例子

N <- 1000
p <- 50
ilogit <- function(eta){
  1/(1+exp(-eta))
}
dat <- matrix(rnorm(N*p,mean=-3),nrow=N)
coeff <- (1:ncol(dat))*0.001
(x <-rbinom(N,size=1,prob=ilogit(dat%*%coeff))) 
mydat <- data.frame(dat,x=x)
>table(x)
 0   1 
978  22 

请注意,第 1 类是罕见事件,因此第 1 类中只有 22 个观测值。 现在,我对 rpart 进行拟合,将 1 类错误分类到 0 类的损失比将 0 类错误分类到 1 类的损失大 10 倍。

library(rpart)
fit <- rpart(x~.,data=mydat,method="class",
             parm=list(loss=matrix(c(0,1,
                                    10,0),2,2,byrow=TRUE)))
printcp(fit)

输出为:

Classification tree:
rpart(formula = x ~ ., data = mydat, method = "class", parms = list(loss = matrix(c(0, 
    1, 10, 0), 2, 2, byrow = TRUE)))

Variables actually used in tree construction:
 [1] X1  X10 X13 X14 X17 X19 X35 X37 X39 X8  X9 

Root node error: 220/1000 = 0.22

n= 1000 

        CP nsplit rel error xerror     xstd
1 0.061364      0   1.00000 0.1000 0.021084
2 0.050000      9   0.36364 2.4136 0.316196
3 0.018182     11   0.26364 2.7727 0.338565
4 0.010000     13   0.22727 3.4091 0.373655

奇怪的是,初始 xerror 非常小,为 0.1000(我看到这是 1/class 0 的损失),然后 xerror 增加到 2.41、2.77 等等。不知何故,初始节点处的 xerror 比 rel 错误好得多!如果我将 0 类的损失改得更大,则会发生更奇怪的事情:

library(rpart)
fit <- rpart(x~.,data=mydat,method="class",
             parm=list(loss=matrix(c(0,1,
                                    100000,0),2,2,byrow=TRUE)))
printcp(fit)

输出为:

Classification tree:
rpart(formula = x ~ ., data = mydat, method = "class", parms = list(loss = matrix(c(0, 
    1, 100000, 0), 2, 2, byrow = TRUE)))

Variables actually used in tree construction:
 [1] X15 X17 X18 X2  X20 X27 X28 X30 X32 X35 X36 X38 X39 X41 X49 X50 X7  X8 

Root node error: 978/1000 = 0.978

n= 1000 

         CP nsplit rel error xerror    xstd
1  0.182004      0   1.00000 100000  474.29
2  0.116564      1   0.81800  76278 1407.50
3  0.100204      2   0.70143  65031 1555.75
4  0.067485      3   0.60123  58180 1601.24
5  0.057260      4   0.53374  47853 1613.39
6  0.049080      5   0.47648  42945 1595.88
7  0.040900      6   0.42740  37219 1555.75
8  0.033742      7   0.38650  32106 1500.68
9  0.028630      8   0.35276  30368 1477.46
10 0.025562      9   0.32413  27301 1430.44
11 0.021472     10   0.29857  24949 1388.73
12 0.019427     12   0.25562  21779 1323.85
13 0.017382     13   0.23620  20859 1302.96
14 0.014315     14   0.21881  19530 1271.02
15 0.013292     16   0.19018  18916 1255.53
16 0.011247     17   0.17689  16667 1194.31
17 0.010000     20   0.14315  12168 1046.94

所以这一次,xerror 比相对误差要糟糕得多。这次,初始 xerror 似乎是 0 类的丢失(与上次不同,它不是倒数)。而且,当树生长时,xerror 会不断变得更好。

你能告诉我为什么会发生这种情况吗?

最佳答案

我知道这需要很长时间,但在解决了类似的问题后,我得到了这个奇怪结果的(部分)解决方案。

  1. 如果我们仔细观察问题的第一个变体(损失为 10),我们会发现根节点误差的计算如下:

    • [("类别 1 的丢失") * ("实际类别的数量")]/(​​"数据集的大小)

    从概念上讲,这意味着如果我们对大多数数据点进行分类 类我们将有一个加权错误率,如上所述。

虽然 1 类的损失不断增加,但最终会使分数大于 1!在这种情况下,树结构开始假设将所有内容分类为第一类(仅仅因为它在成本方面是最优的)!

重要:如果两个类别的损失值导致根节点误差大于 1,则选择成本较小的类别作为树的初始分类选择。

<小时/>
  • 在所有情况下,初始交叉验证平均误差 (xerror) 通过以下公式计算:

    • (A类损失值)/(B类损失值),

    其中A是每次在根节点中被确定为最佳通用分类器的类。 (例如,如果类别 0 的损失为 2,类别 1 的损失为 3,则根节点上的 xerror 值为 0.66667)

  • 注意:在问题@ThePrincess 的示例中,假设是正确的,因为零类的损失是统一的

    <小时/>
  • 就 xerror 值性能的原因而言,我倾向于认为,在第一个示例中,树遭受了严重的过度拟合,导致只有根节点的树是最优的,而在后一种情况下,我们显然当我们深入研究时,我们会得到更好的解决方案,因为我们将其与初始解决方案进行比较,在初始解决方案中,我们的所有数据基本上从一开始就被错误分类(我们只有 1000 个数据中的 22 个,但我们一开始就把所有数据都分类为一个)。
  • p.s这是我在平台上的第一个答案。我希望它有帮助! (欢迎提出改进我的答案结构的建议!)

    关于r - 分配损失时如何解释 rpart(方法 ="class")的 xerror,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37736868/

    相关文章:

    r - 确定模型公式是否只有截距的最简单方法

    R - 运行函数以从表列表中每个表的现有列计算新列

    r - 在 x,y 散点图中使用直接标签

    python - 如何正确处理tensorflow RNN中的one-hot-encoding和多维数据

    machine-learning - 如何适应神经网络权值的随机性?

    r - 计算非线性回归的 R^2 值

    r - 在 R 中绘制来自不同文件的重叠位置

    r - 模块中的 Xaringan 演示

    python - 时间序列数据的滑动窗口训练/测试分割

    r - 在 r 的 S 形曲线上找到一个点