【问题标题】:How to use mlr to customize classification model如何使用mlr自定义分类模型
【发布时间】:2017-08-14 04:01:21
【问题描述】:

我正在研究 mlr 并尝试自定义我自己的分类模型。我正在使用来自https://mlr-org.github.io/mlr-tutorial/release/html/create_learner/index.html#classification 的示例。这是我的代码:

library(mlr)
library(MASS)
makeRLearner.classif.lda = function() {
  makeRLearnerClassif(
    cl = "classif.lda",
    package = "MASS",
    par.set = makeParamSet(
      makeDiscreteLearnerParam(id = "method", default = "moment", values = c("moment", "mle", "mve", "t")),
      makeNumericLearnerParam(id = "nu", lower = 2, requires = quote(method == "t")),
      makeNumericLearnerParam(id = "tol", default = 1e-4, lower = 0),
      makeDiscreteLearnerParam(id = "predict.method", values = c("plug-in", "predictive", "debiased"),
                               default = "plug-in", when = "predict"),
      makeLogicalLearnerParam(id = "CV", default = FALSE, tunable = FALSE)
),
    properties = c("twoclass", "multiclass", "numerics", "factors", "prob"),
    name = "Linear Discriminant Analysis",
    short.name = "lda",
    note = "Learner param 'predict.method' maps to 'method' in predict.lda."
  )
}
trainLearner.classif.lda = function(.learner, .task, .subset, .weights = NULL, ...) {
  f = getTaskFormula(.task)
  MASS::lda(f, data = getTaskData(.task, .subset), ...)
}
predictLearner.classif.lda = function(.learner, .model, .newdata,   predict.method = "plug-in", ...) {
  p = predict(.model$learner.model, newdata = .newdata, method = predict.method, ...)
  if (.learner$predict.type == "response") 
    return(p$class) else return(p$posterior)
}
data(iris)
train = sample(1:nrow(iris), nrow(iris) / 1.5)
test = sample(1:nrow(iris), nrow(iris) / 6)
task <- makeClassifTask(data=iris,target='Species')
lrn <- makeRLearner.classif.lda()
tr <- trainLearner.classif.lda(.learner=lrn,.task=task,.subset=train)
pred <- predictLearner.classif.lda(.learner=lrn,.model=tr,.newdata=test)

我只是从网站上复制并粘贴了三个功能。但我收到以下错误:

Error in UseMethod("predict") : 
  no applicable method for 'predict' applied to an object of class "NULL"

我发现我的tr中没有$learner.model,它应该在那里并被转移到预测函数中。我的 tr 有:

> str(tr)
List of 10
 $ prior  : Named num [1:3] 0.38 0.3 0.32
  ..- attr(*, "names")= chr [1:3] "setosa" "versicolor" "virginica"
 $ counts : Named int [1:3] 38 30 32
  ..- attr(*, "names")= chr [1:3] "setosa" "versicolor" "virginica"
 $ means  : num [1:3, 1:4] 5.02 5.94 6.65 3.47 2.83 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:3] "setosa" "versicolor" "virginica"
  .. ..$ : chr   [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
 $ scaling: num [1:4, 1:2] 0.869 1.384 -2.214 -2.954 0.157 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
  .. ..$ : chr [1:2] "LD1" "LD2"
 $ lev    : chr [1:3] "setosa" "versicolor" "virginica"
 $ svd    : num [1:2] 41.78 2.91
 $ N      : int 100
 $ call   : language lda(formula = f, data = getTaskData(.task, .subset))
 $ terms  :Classes 'terms', 'formula'  language Species ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width
  .. ..- attr(*, "variables")= language list(Species, Sepal.Length, Sepal.Width, Petal.Length, Petal.Width)
  .. ..- attr(*, "factors")= int [1:5, 1:4] 0 1 0 0 0 0 0 1 0 0 ...
  .. .. ..- attr(*, "dimnames")=List of 2
  .. .. .. ..$ : chr [1:5] "Species" "Sepal.Length" "Sepal.Width" "Petal.Length" ...
  .. .. .. ..$ : chr [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
  .. ..- attr(*, "term.labels")= chr [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
  .. ..- attr(*, "order")= int [1:4] 1 1 1 1
  .. ..- attr(*, "intercept")= int 1
  .. ..- attr(*, "response")= int 1
  .. ..- attr(*, ".Environment")=<environment: 0x00000000213a8150> 
  .. ..- attr(*, "predvars")= language list(Species, Sepal.Length, Sepal.Width, Petal.Length, Petal.Width)
  .. ..- attr(*, "dataClasses")= Named chr [1:5] "factor" "numeric" "numeric" "numeric" ...
  .. .. ..- attr(*, "names")= chr [1:5] "Species" "Sepal.Length" "Sepal.Width" "Petal.Length" ...
 $ xlevels: Named list()
 - attr(*, "class")= chr "lda"

我尝试注册学习者,但我想我的方式不对。这是我的代码:

registerS3method("makeRLearner.classif.lda", "<awesome_new_learner_class>", makeRLearner.classif.lda.<awesome_new_learner_class>)
registerS3method("trainLearner.classif.lda", "<awesome_new_learner_class>", trainLearner.classif.lda.<awesome_new_learner_class>)
registerS3method("predictLearner.classif.lda", "<awesome_new_learner_class>", predictLearner.classif.lda.<awesome_new_learner_class>)

也许我不应该只是从网站上复制代码。但我不知道该怎么做。我对 mlr 包真的很陌生。

【问题讨论】:

  • 您是否阅读了您链接的整个页面?您需要注册学习者。
  • 感谢您提及这一点。但我确实知道如何使用它来注册。我稍微改变了我的问题。你能不能给我一个真实的例子。谢谢

标签: r mlr


【解决方案1】:

这是一个完整的例子,使用了 mlr 自带的 iris 任务。除了仔细查看 mlr 文档之外,您可能会发现 R 编程的一般介绍很有用,特别是在参数名称方面——您看到的错误原因是您没有传递模型到predict().model 不是该参数的名称,它是您在定义中调用的变量)。

library(mlr)
library(MASS)
makeRLearner.classif.lda1 = function() {
  makeRLearnerClassif(
    cl = "classif.lda1",
    package = "MASS",
    par.set = makeParamSet(
      makeDiscreteLearnerParam(id = "method", default = "moment", values = c("moment", "mle", "mve", "t")),
      makeNumericLearnerParam(id = "nu", lower = 2, requires = quote(method == "t")),
      makeNumericLearnerParam(id = "tol", default = 1e-4, lower = 0),
      makeDiscreteLearnerParam(id = "predict.method", values = c("plug-in", "predictive", "debiased"),
                               default = "plug-in", when = "predict"),
      makeLogicalLearnerParam(id = "CV", default = FALSE, tunable = FALSE)
),
    properties = c("twoclass", "multiclass", "numerics", "factors", "prob"),
    name = "Linear Discriminant Analysis",
    short.name = "lda",
    note = "Learner param 'predict.method' maps to 'method' in predict.lda."
  )
}
trainLearner.classif.lda1 = function(.learner, .task, .subset, .weights = NULL, ...) {
  f = getTaskFormula(.task)
  MASS::lda(f, data = getTaskData(.task, .subset), ...)
}
predictLearner.classif.lda1 = function(.learner, .model, .newdata,   predict.method = "plug-in", ...) {
  p = predict(.model$learner.model, newdata = .newdata, method = predict.method, ...)
  if (.learner$predict.type == "response") 
    return(p$class) else return(p$posterior)
}


registerS3method("makeRLearner", "classif.lda1", makeRLearner.classif.lda1)
registerS3method("trainLearner", "classif.lda1", trainLearner.classif.lda1)
registerS3method("predictLearner", "classif.lda1", predictLearner.classif.lda1)

lrn = makeLearner("classif.lda1")
mod = train(lrn, iris.task)
pred = predict(mod, iris.task)

【讨论】:

    猜你喜欢
    • 2020-08-11
    • 2014-09-01
    • 2020-09-07
    • 2018-04-12
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    • 2011-02-08
    相关资源
    最近更新 更多