R 的 MLR 中的预测函数产生与预测不一致的结果
Predict function in R's MLR yielding results inconsistent with predict
我正在使用 mlr 包的框架构建 svm 模型来预测图像中的土地覆盖 类。我使用栅格包的预测函数并将栅格转换为数据帧,然后使用 "learner.model" 作为输入对该数据帧进行预测。这些方法给了我真实的结果。
工作顺利:
> predict(raster, mod$learner.model)
或
> xy <- as.data.frame(raster, xy = T)
> C <- predict(mod$learner.model, xy)
但是,如果我在未指定 learner.model 的情况下对从栅格派生的数据帧进行预测,结果就不一样了。
> C2 <- predict(mod, newdata=xy)
C2$data$response 与 C 不同。为什么?
这里有一个可重现的例子来说明这个问题:
> library(mlr)
> library(kernlab)
> x1 <- rnorm(50)
> x2 <- rnorm(50, 3)
> x3 <- rnorm(50, -20, 3)
> C <- sample(c("a","b","c"), 50, T)
> d <- data.frame(x1, x2, x3, C)
> classif <- makeClassifTask(id = "example", data = d, target = "C")
> lrn <- makeLearner("classif.ksvm", predict.type = "prob", fix.factors.prediction = T)
> t <- train(lrn, classif)
Using automatic sigma estimation (sigest) for RBF or laplace kernel
> res1 <- predict(t, newdata = data.frame(x2,x1,x3))
> res1
Prediction: 50 observations
predict.type: prob
threshold: a=0.33,b=0.33,c=0.33
time: 0.01
prob.a prob.b prob.c response
1 0.2110131 0.3817773 0.4072095 c
2 0.1551583 0.4066868 0.4381549 c
3 0.4305353 0.3092737 0.2601910 a
4 0.2160050 0.4142465 0.3697485 b
5 0.1852491 0.3789849 0.4357659 c
6 0.5879579 0.2269832 0.1850589 a
> res2 <- predict(t$learner.model, data.frame(x2,x1,x3))
> res2
[1] c c a b c a b a c c b c b a c b c a a b c b c c a b b b a a b a c b a c c c
[39] c a a b c b b b b a b b
Levels: a b c
!> res1$data$response == res2
[1] TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE FALSE
[13] TRUE TRUE TRUE FALSE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE
[25] TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE
[37] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[49] TRUE FALSE
预测不一致。按照 mlr 关于预测的教程页面,我不明白为什么结果会有所不同。感谢您的帮助。
-----
更新:
当我对随机森林模型执行相同操作时,两个向量相等。这是因为 SVM 依赖于尺度而随机森林不是吗?
> library(randomForest)
> classif <- makeClassifTask(id = "example", data = d, target = "C")
> lrn <- makeLearner("classif.randomForest", predict.type = "prob", fix.factors.prediction = T)
> t <- train(lrn, classif)
>
> res1 <- predict(t, newdata = data.frame(x2,x1,x3))
> res1
Prediction: 50 observations
predict.type: prob
threshold: a=0.33,b=0.33,c=0.33
time: 0.00
prob.a prob.b prob.c response
1 0.654 0.228 0.118 a
2 0.742 0.090 0.168 a
3 0.152 0.094 0.754 c
4 0.092 0.832 0.076 b
5 0.748 0.100 0.152 a
6 0.680 0.098 0.222 a
>
> res2 <- predict(t$learner.model, data.frame(x2,x1,x3))
> res2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
a a c b a a a c a b b b b c c a b b a c b a c c b c
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
a a b a c c c b c b c a b c c b c b c a c c b b
Levels: a b c
>
> res1$data$response == res2
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[16] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[31] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[46] TRUE TRUE TRUE TRUE TRUE
----
另一个更新:如果我将 predict.type 从 "prob" 更改为 "response",则两个 svm 预测向量彼此一致。我将研究这些类型的差异,我曾认为 "prob" 给出了相同的结果,但也给出了概率。也许不是这样?
答案就在这里:
Why are probabilities and response in ksvm in R not consistent?
简而言之,ksvm type = "probabilities" 给出的结果与 type = "response".
不同
如果我运行
> res2 <- predict(t$learner.model, data.frame(x2,x1,x3), type = "probabilities")
> res2
然后我得到与上面的 res1 相同的结果(默认类型 = "response")。
不幸的是,根据概率对图像进行分类似乎不如使用 "response"。也许这仍然是估计分类确定性的最佳方法?
如您所见,"error" 的来源是 mlr
和 kernlab
对预测类型有不同的默认值。
mlr
维护相当多的内部 "state" 并检查每个学习者的参数以及如何处理培训和测试。您可以使用 lrn$predict.type
获得学习者将做出的预测类型,在您的情况下会给出 "prob"
。如果您想了解所有细节,请查看 the implementation of classif.ksvm
。
不建议混合使用 mlr
-wrapped 学习器和 "raw" 学习器,就像您在示例中所做的那样,并且没有必要这样做。如果你混合使用它们,就会发生你发现的事情——所以当使用 mlr
时,仅使用 mlr
构造来训练模型,进行预测等
mlr
确实有测试以确保 "raw" 和包装的学习器产生相同的输出,参见例如the one for classif.ksvm
.
我正在使用 mlr 包的框架构建 svm 模型来预测图像中的土地覆盖 类。我使用栅格包的预测函数并将栅格转换为数据帧,然后使用 "learner.model" 作为输入对该数据帧进行预测。这些方法给了我真实的结果。
工作顺利:
> predict(raster, mod$learner.model)
或
> xy <- as.data.frame(raster, xy = T)
> C <- predict(mod$learner.model, xy)
但是,如果我在未指定 learner.model 的情况下对从栅格派生的数据帧进行预测,结果就不一样了。
> C2 <- predict(mod, newdata=xy)
C2$data$response 与 C 不同。为什么?
这里有一个可重现的例子来说明这个问题:
> library(mlr)
> library(kernlab)
> x1 <- rnorm(50)
> x2 <- rnorm(50, 3)
> x3 <- rnorm(50, -20, 3)
> C <- sample(c("a","b","c"), 50, T)
> d <- data.frame(x1, x2, x3, C)
> classif <- makeClassifTask(id = "example", data = d, target = "C")
> lrn <- makeLearner("classif.ksvm", predict.type = "prob", fix.factors.prediction = T)
> t <- train(lrn, classif)
Using automatic sigma estimation (sigest) for RBF or laplace kernel
> res1 <- predict(t, newdata = data.frame(x2,x1,x3))
> res1
Prediction: 50 observations
predict.type: prob
threshold: a=0.33,b=0.33,c=0.33
time: 0.01
prob.a prob.b prob.c response
1 0.2110131 0.3817773 0.4072095 c
2 0.1551583 0.4066868 0.4381549 c
3 0.4305353 0.3092737 0.2601910 a
4 0.2160050 0.4142465 0.3697485 b
5 0.1852491 0.3789849 0.4357659 c
6 0.5879579 0.2269832 0.1850589 a
> res2 <- predict(t$learner.model, data.frame(x2,x1,x3))
> res2
[1] c c a b c a b a c c b c b a c b c a a b c b c c a b b b a a b a c b a c c c
[39] c a a b c b b b b a b b
Levels: a b c
!> res1$data$response == res2
[1] TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE FALSE
[13] TRUE TRUE TRUE FALSE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE
[25] TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE
[37] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[49] TRUE FALSE
预测不一致。按照 mlr 关于预测的教程页面,我不明白为什么结果会有所不同。感谢您的帮助。
-----
更新: 当我对随机森林模型执行相同操作时,两个向量相等。这是因为 SVM 依赖于尺度而随机森林不是吗?
> library(randomForest)
> classif <- makeClassifTask(id = "example", data = d, target = "C")
> lrn <- makeLearner("classif.randomForest", predict.type = "prob", fix.factors.prediction = T)
> t <- train(lrn, classif)
>
> res1 <- predict(t, newdata = data.frame(x2,x1,x3))
> res1
Prediction: 50 observations
predict.type: prob
threshold: a=0.33,b=0.33,c=0.33
time: 0.00
prob.a prob.b prob.c response
1 0.654 0.228 0.118 a
2 0.742 0.090 0.168 a
3 0.152 0.094 0.754 c
4 0.092 0.832 0.076 b
5 0.748 0.100 0.152 a
6 0.680 0.098 0.222 a
>
> res2 <- predict(t$learner.model, data.frame(x2,x1,x3))
> res2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
a a c b a a a c a b b b b c c a b b a c b a c c b c
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
a a b a c c c b c b c a b c c b c b c a c c b b
Levels: a b c
>
> res1$data$response == res2
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[16] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[31] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[46] TRUE TRUE TRUE TRUE TRUE
----
另一个更新:如果我将 predict.type 从 "prob" 更改为 "response",则两个 svm 预测向量彼此一致。我将研究这些类型的差异,我曾认为 "prob" 给出了相同的结果,但也给出了概率。也许不是这样?
答案就在这里:
Why are probabilities and response in ksvm in R not consistent?
简而言之,ksvm type = "probabilities" 给出的结果与 type = "response".
不同如果我运行
> res2 <- predict(t$learner.model, data.frame(x2,x1,x3), type = "probabilities")
> res2
然后我得到与上面的 res1 相同的结果(默认类型 = "response")。
不幸的是,根据概率对图像进行分类似乎不如使用 "response"。也许这仍然是估计分类确定性的最佳方法?
如您所见,"error" 的来源是 mlr
和 kernlab
对预测类型有不同的默认值。
mlr
维护相当多的内部 "state" 并检查每个学习者的参数以及如何处理培训和测试。您可以使用 lrn$predict.type
获得学习者将做出的预测类型,在您的情况下会给出 "prob"
。如果您想了解所有细节,请查看 the implementation of classif.ksvm
。
不建议混合使用 mlr
-wrapped 学习器和 "raw" 学习器,就像您在示例中所做的那样,并且没有必要这样做。如果你混合使用它们,就会发生你发现的事情——所以当使用 mlr
时,仅使用 mlr
构造来训练模型,进行预测等
mlr
确实有测试以确保 "raw" 和包装的学习器产生相同的输出,参见例如the one for classif.ksvm
.