randomForest 使用因子变量作为连续变量?
randomForest using factor variables as continuous?
我正在使用包 randomForest
来生成物种的栖息地适宜性模型。在我开始用 getTree()
查看单个树之前,我认为一切正常。文档 (see page 4 of the randomForest vignette) 指出对于分类变量,分割点将是一个整数,这是有道理的。但是,在我查看结果的树中,情况并非如此。
我用来构建模型的数据框被格式化为分类变量作为因素:
> str(df.full)
'data.frame': 27087 obs. of 23 variables:
$ sciname : Factor w/ 2 levels "Laterallus jamaicensis",..: 1 1 1 1 1 1 1 1 1 1 ...
$ estid : Factor w/ 2 levels "7694","psabs": 1 1 1 1 1 1 1 1 1 1 ...
$ pres : Factor w/ 2 levels "1","0": 1 1 1 1 1 1 1 1 1 1 ...
$ stratum : Factor w/ 89 levels "poly_0","poly_1",..: 1 1 1 1 1 1 1 1 1 1 ...
$ ra : Factor w/ 3 levels "high","low","medium": 3 3 3 3 3 3 3 3 3 3 ...
$ eoid : Factor w/ 2 levels "0","psabs": 1 1 1 1 1 1 1 1 1 1 ...
$ avd3200 : num 0.1167 0.0953 0.349 0.1024 0.3765 ...
$ biocl05 : num 330 330 330 330 330 ...
$ biocl06 : num 66 65.8 66 65.8 66 ...
$ biocl08 : num 277 277 277 277 277 ...
$ biocl09 : num 170 170 170 170 170 ...
$ biocl13 : num 186 186 185 186 185 ...
$ cti : num 19.7 19 10.4 16.4 14.7 ...
$ dtnhdwat : num 168 240 39 206 309 ...
$ dtwtlnd : num 0 0 0 0 0 0 0 0 0 0 ...
$ e2em1n99 : num 0 0 0 0 0 0 0 0 0 0 ...
$ ems30_53 : Factor w/ 53 levels "0","602","2206",..: 19 4 17 4 19 19 4 4 19 19 ...
$ ems5607_46: num 0 0 1 0 0.4 ...
$ ksat : num 0.21 0.21 0.21 0.21 0.21 ...
$ lfevh_53 : Factor w/ 53 levels "0","11","16",..: 38 38 38 38 38 38 38 38 38 38 ...
$ ned : num 1.46 1.48 1.54 1.48 1.47 ...
$ soilec : num 14.8 14.8 19.7 14.8 14.8 ...
$ wtlnd_53 : Factor w/ 50 levels "0","3","7","11",..: 4 31 7 31 7 31 7 7 31 31 ...
这是函数调用:
# rfStratum and sampSizeVec were previously defined
> rf.full$call
randomForest(x = df.full[, c(7:23)], y = df.full[, 3],
ntree = 2000, mtry = 7, replace = TRUE, strata = rfStratum,
sampsize = sampSizeVec, importance = TRUE, norm.votes = TRUE)
这是示例树的前 15 行(请注意,第 1、5 和 15 行中的变量应该是分类变量,即它们应该具有整数拆分值):
> tree100
left daughter right daughter split var split point status prediction
1 2 3 ems30_53 9.007198e+15 1 <NA>
2 4 5 biocl08 2.753206e+02 1 <NA>
3 6 7 biocl06 6.110518e+01 1 <NA>
4 8 9 biocl06 1.002722e+02 1 <NA>
5 10 11 lfevh_53 9.006718e+15 1 <NA>
6 0 0 <NA> 0.000000e+00 -1 0
7 12 13 biocl05 3.310025e+02 1 <NA>
8 14 15 ned 2.814818e+00 1 <NA>
9 0 0 <NA> 0.000000e+00 -1 1
10 16 17 avd3200 4.199712e-01 1 <NA>
11 18 19 e2em1n99 1.724138e-02 1 <NA>
12 20 21 biocl09 1.738916e+02 1 <NA>
13 22 23 ned 8.837864e-01 1 <NA>
14 24 25 biocl05 3.442437e+02 1 <NA>
15 26 27 lfevh_53 9.007199e+15 1 <NA>
其他信息:我遇到这个问题是因为我正在调查将结果预测回研究区域时遇到的错误,指出新数据中的预测变量类型与训练数据不匹配。我已经使用相同的数据框和脚本(只是使用不同的预测变量子集)对该模型进行了 6 次其他迭代,并且之前从未收到过此消息。我发现这个 运行 中的随机森林对象与另一个 运行 中的随机森林对象唯一不同的是 the rf.full$forest$ncat
组件存储为双精度而不是整数
> for(i in 1:length(rf.full$forest$ncat)){
+ cat(names(rf.full$forest$ncat)[[i]], ": ", class(rf.full$forest$ncat[[i]]), "\n")
+ }
avd12800 : numeric
cti : numeric
dtnhdwat : numeric
dtwtlnd : numeric
ems2207_99 : numeric
ems30_53 : numeric
ems5807_99 : numeric
hydgrp : numeric
ksat : numeric
lfevh_53 : numeric
ned : numeric
soilec : numeric
wtlnd_53 : numeric
>
> rf.full$forest$ncat
avd12800 cti dtnhdwat dtwtlnd ems2207_99 ems30_53 ems5807_99 hydgrp ksat lfevh_53
1 1 1 1 1 53 1 1 1 53
ned soilec wtlnd_53
1 1 50
但是,xlevels(似乎是所用预测变量及其类型的列表)都显示了每个预测变量的正确数据类型。
> for(i in 1:length(rf.full$forest$xlevels)){
+ cat(names(rf.full$forest$xlevels)[[i]], ": ", class(rf.full$forest$xlevels[[i]]),"\n")
+ }
avd12800 : numeric
cti : numeric
dtnhdwat : numeric
dtwtlnd : numeric
ems2207_99 : numeric
ems30_53 : character
ems5807_99 : numeric
hydgrp : character
ksat : numeric
lfevh_53 : character
ned : numeric
soilec : numeric
wtlnd_53 : character
# example continuous predictor
> rf.full$forest$xlevels$avd12800
[1] 0
# example categorical predictor
> rf.full$forest$xlevels$ems30_53
[1] "0" "602" "2206" "2207" "4504" "4507" "4702" "4704" "4705" "4706" "4707" "4717" "5207" "5307" "5600"
[16] "5605" "5607" "5616" "5617" "5707" "5717" "5807" "5907" "6306" "6307" "6507" "6600" "7002" "7004" "9107"
[31] "9116" "9214" "9307" "9410" "9411" "9600" "4607" "4703" "6402" "6405" "6407" "6610" "7005" "7102" "7104"
[46] "7107" "9000" "9104" "9106" "9124" "9187" "9301" "9505"
ncat 分量只是每个变量类别数的向量,其中 1 表示连续变量 (as noted here),因此将其存储为整数或一个双,但似乎这可能都是相关的。
问题
1) randomForest 森林的任何给定树中的分类预测变量的分割点不应该是整数,如果是,关于为什么将数据框中的因素用作 randomForest 调用的输入的任何想法没有被这样使用?
2) randomForest 对象的 ncat 组件的数字类型(双精度与整数)是否与模型构建有任何关系,以及关于什么可能导致它在前 6 个中从整数切换的任何想法运行 在最后一个 运行 中加倍(每个 运行 包含相同数据的不同子集)?
randomforest::randomForest
算法对低基数(最多 32 个类别)和高基数(32 到 64 个?类别)分类拆分进行不同的编码。注意 - 你的所有 "problematic" 特征都属于后者 class,并且使用 64 位浮点值编码。
虽然控制台输出对人类观察者没有意义,但 randomForest
模型 object/algorithm 本身是正确的(即,将这些变量视为分类变量),并且正在做出正确的预测。
如果您想研究决策树的结构和决策树集成模型,那么您可以考虑将它们导出为 PMML 数据格式。例如,您可以为此使用 R2PMML 包:
library("r2pmml")
r2pmml(rf.full, "MyRandomForest.pmml")
然后,在文本编辑器中打开 MyRandomForest.pmml,您将对模型的内部结构(分支、拆分条件、叶值等)有一个很好的了解。
我正在使用包 randomForest
来生成物种的栖息地适宜性模型。在我开始用 getTree()
查看单个树之前,我认为一切正常。文档 (see page 4 of the randomForest vignette) 指出对于分类变量,分割点将是一个整数,这是有道理的。但是,在我查看结果的树中,情况并非如此。
我用来构建模型的数据框被格式化为分类变量作为因素:
> str(df.full)
'data.frame': 27087 obs. of 23 variables:
$ sciname : Factor w/ 2 levels "Laterallus jamaicensis",..: 1 1 1 1 1 1 1 1 1 1 ...
$ estid : Factor w/ 2 levels "7694","psabs": 1 1 1 1 1 1 1 1 1 1 ...
$ pres : Factor w/ 2 levels "1","0": 1 1 1 1 1 1 1 1 1 1 ...
$ stratum : Factor w/ 89 levels "poly_0","poly_1",..: 1 1 1 1 1 1 1 1 1 1 ...
$ ra : Factor w/ 3 levels "high","low","medium": 3 3 3 3 3 3 3 3 3 3 ...
$ eoid : Factor w/ 2 levels "0","psabs": 1 1 1 1 1 1 1 1 1 1 ...
$ avd3200 : num 0.1167 0.0953 0.349 0.1024 0.3765 ...
$ biocl05 : num 330 330 330 330 330 ...
$ biocl06 : num 66 65.8 66 65.8 66 ...
$ biocl08 : num 277 277 277 277 277 ...
$ biocl09 : num 170 170 170 170 170 ...
$ biocl13 : num 186 186 185 186 185 ...
$ cti : num 19.7 19 10.4 16.4 14.7 ...
$ dtnhdwat : num 168 240 39 206 309 ...
$ dtwtlnd : num 0 0 0 0 0 0 0 0 0 0 ...
$ e2em1n99 : num 0 0 0 0 0 0 0 0 0 0 ...
$ ems30_53 : Factor w/ 53 levels "0","602","2206",..: 19 4 17 4 19 19 4 4 19 19 ...
$ ems5607_46: num 0 0 1 0 0.4 ...
$ ksat : num 0.21 0.21 0.21 0.21 0.21 ...
$ lfevh_53 : Factor w/ 53 levels "0","11","16",..: 38 38 38 38 38 38 38 38 38 38 ...
$ ned : num 1.46 1.48 1.54 1.48 1.47 ...
$ soilec : num 14.8 14.8 19.7 14.8 14.8 ...
$ wtlnd_53 : Factor w/ 50 levels "0","3","7","11",..: 4 31 7 31 7 31 7 7 31 31 ...
这是函数调用:
# rfStratum and sampSizeVec were previously defined
> rf.full$call
randomForest(x = df.full[, c(7:23)], y = df.full[, 3],
ntree = 2000, mtry = 7, replace = TRUE, strata = rfStratum,
sampsize = sampSizeVec, importance = TRUE, norm.votes = TRUE)
这是示例树的前 15 行(请注意,第 1、5 和 15 行中的变量应该是分类变量,即它们应该具有整数拆分值):
> tree100
left daughter right daughter split var split point status prediction
1 2 3 ems30_53 9.007198e+15 1 <NA>
2 4 5 biocl08 2.753206e+02 1 <NA>
3 6 7 biocl06 6.110518e+01 1 <NA>
4 8 9 biocl06 1.002722e+02 1 <NA>
5 10 11 lfevh_53 9.006718e+15 1 <NA>
6 0 0 <NA> 0.000000e+00 -1 0
7 12 13 biocl05 3.310025e+02 1 <NA>
8 14 15 ned 2.814818e+00 1 <NA>
9 0 0 <NA> 0.000000e+00 -1 1
10 16 17 avd3200 4.199712e-01 1 <NA>
11 18 19 e2em1n99 1.724138e-02 1 <NA>
12 20 21 biocl09 1.738916e+02 1 <NA>
13 22 23 ned 8.837864e-01 1 <NA>
14 24 25 biocl05 3.442437e+02 1 <NA>
15 26 27 lfevh_53 9.007199e+15 1 <NA>
其他信息:我遇到这个问题是因为我正在调查将结果预测回研究区域时遇到的错误,指出新数据中的预测变量类型与训练数据不匹配。我已经使用相同的数据框和脚本(只是使用不同的预测变量子集)对该模型进行了 6 次其他迭代,并且之前从未收到过此消息。我发现这个 运行 中的随机森林对象与另一个 运行 中的随机森林对象唯一不同的是 the rf.full$forest$ncat
组件存储为双精度而不是整数
> for(i in 1:length(rf.full$forest$ncat)){
+ cat(names(rf.full$forest$ncat)[[i]], ": ", class(rf.full$forest$ncat[[i]]), "\n")
+ }
avd12800 : numeric
cti : numeric
dtnhdwat : numeric
dtwtlnd : numeric
ems2207_99 : numeric
ems30_53 : numeric
ems5807_99 : numeric
hydgrp : numeric
ksat : numeric
lfevh_53 : numeric
ned : numeric
soilec : numeric
wtlnd_53 : numeric
>
> rf.full$forest$ncat
avd12800 cti dtnhdwat dtwtlnd ems2207_99 ems30_53 ems5807_99 hydgrp ksat lfevh_53
1 1 1 1 1 53 1 1 1 53
ned soilec wtlnd_53
1 1 50
但是,xlevels(似乎是所用预测变量及其类型的列表)都显示了每个预测变量的正确数据类型。
> for(i in 1:length(rf.full$forest$xlevels)){
+ cat(names(rf.full$forest$xlevels)[[i]], ": ", class(rf.full$forest$xlevels[[i]]),"\n")
+ }
avd12800 : numeric
cti : numeric
dtnhdwat : numeric
dtwtlnd : numeric
ems2207_99 : numeric
ems30_53 : character
ems5807_99 : numeric
hydgrp : character
ksat : numeric
lfevh_53 : character
ned : numeric
soilec : numeric
wtlnd_53 : character
# example continuous predictor
> rf.full$forest$xlevels$avd12800
[1] 0
# example categorical predictor
> rf.full$forest$xlevels$ems30_53
[1] "0" "602" "2206" "2207" "4504" "4507" "4702" "4704" "4705" "4706" "4707" "4717" "5207" "5307" "5600"
[16] "5605" "5607" "5616" "5617" "5707" "5717" "5807" "5907" "6306" "6307" "6507" "6600" "7002" "7004" "9107"
[31] "9116" "9214" "9307" "9410" "9411" "9600" "4607" "4703" "6402" "6405" "6407" "6610" "7005" "7102" "7104"
[46] "7107" "9000" "9104" "9106" "9124" "9187" "9301" "9505"
ncat 分量只是每个变量类别数的向量,其中 1 表示连续变量 (as noted here),因此将其存储为整数或一个双,但似乎这可能都是相关的。
问题
1) randomForest 森林的任何给定树中的分类预测变量的分割点不应该是整数,如果是,关于为什么将数据框中的因素用作 randomForest 调用的输入的任何想法没有被这样使用?
2) randomForest 对象的 ncat 组件的数字类型(双精度与整数)是否与模型构建有任何关系,以及关于什么可能导致它在前 6 个中从整数切换的任何想法运行 在最后一个 运行 中加倍(每个 运行 包含相同数据的不同子集)?
randomforest::randomForest
算法对低基数(最多 32 个类别)和高基数(32 到 64 个?类别)分类拆分进行不同的编码。注意 - 你的所有 "problematic" 特征都属于后者 class,并且使用 64 位浮点值编码。
虽然控制台输出对人类观察者没有意义,但 randomForest
模型 object/algorithm 本身是正确的(即,将这些变量视为分类变量),并且正在做出正确的预测。
如果您想研究决策树的结构和决策树集成模型,那么您可以考虑将它们导出为 PMML 数据格式。例如,您可以为此使用 R2PMML 包:
library("r2pmml")
r2pmml(rf.full, "MyRandomForest.pmml")
然后,在文本编辑器中打开 MyRandomForest.pmml,您将对模型的内部结构(分支、拆分条件、叶值等)有一个很好的了解。