简体   繁体   English

如何使用mlr自定义分类模型

[英]How to use mlr to customize classification model

I am studying mlr and try to customize my own classification model.我正在学习 mlr 并尝试自定义我自己的分类模型。 I am using the example from https://mlr-org.github.io/mlr-tutorial/release/html/create_learner/index.html#classification .我正在使用https://mlr-org.github.io/mlr-tutorial/release/html/create_learner/index.html#classification 中的示例。 Here is my code:这是我的代码:

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)

I just copied and pasted the three functions from the website.我只是从网站上复制并粘贴了三个功能。 But I have got the following error:但我有以下错误:

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

I found that there is no $learner.model in my tr, which is supposed to be there and be transfered into prediction function.我发现我的 tr 中没有 $learner.model,它应该在那里并被转移到预测函数中。 my tr has:我的 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"

I tried register learners, but I guess my way is not right.我试过注册学习者,但我想我的方式不对。 Here is my code:这是我的代码:

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>)

Probably I should not just copy the code from the website.可能我不应该只是从网站上复制代码。 But I do not know how to do it.但我不知道该怎么做。 I am really new to mlr package.我对 mlr 包真的很陌生。

Here's a complete example, using the iris task that comes with mlr.这是一个完整的示例,使用 mlr 附带的 iris 任务。 In addition to a closer look at the mlr documentation, you might find a general introduction to programming in R useful, in particular with respect to parameter names -- the cause of the error you're seeing is that you didn't pass a model to predict() ( .model is not the name of that parameter, it's what you called the variable in your definition).除了仔细查看 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM