mlr package - Попытка интегрировать новый ученик кластеризации. Значения по умолчанию в par.vals игнорируются (в методе makeRLearnerCluster)

Я пытаюсь интегрировать функцию MiniBatchKmeans пакета ClusterR в mlr. Согласно документам, я внес следующие изменения:

  1. Создан makeRLearner.cluster.MiniBatchKmeans
  2. Создан trainLearner.cluster.MiniBatchKmeans
  3. Создан predictLearner.cluster.MiniBatchKmeans
  4. Зарегистрированы вышеуказанные методы S3 (как описано здесь)

На данный момент я могу создать ученика, вызвать его обучение и предсказать его. Однако проблема возникает при попытке создать учащегося без какого-либо значения «кластеров».

Базовый пакет (в ClusterR) не имеет значения по умолчанию. значение, определенное для аргумента «кластеры». В соответствии с подходом mlr я попытался указать значение по умолчанию для «кластеров», используя аргумент par.vals. Однако этот аргумент по умолчанию игнорируется.

Мой код:

#' @export
makeRLearner.cluster.MiniBatchKmeans = function() {
  makeRLearnerCluster(
    cl = "cluster.MiniBatchKmeans",
    package = "ClusterR",
    par.set = makeParamSet(
      makeIntegerLearnerParam(id = "clusters", lower = 1L),
      makeIntegerLearnerParam(id = "batch_size", default = 10L, lower = 1L),
      makeIntegerLearnerParam(id = "num_init", default = 1L, lower = 1L),
      makeIntegerLearnerParam(id = "max_iters", default = 100L, lower = 1L),
      makeNumericLearnerParam(id = "init_fraction", default = 1, lower = 0),
      makeDiscreteLearnerParam(id = "initializer", default = "kmeans++",
        values = c("optimal_init", "quantile_init", "kmeans++", "random")),
      makeIntegerLearnerParam(id = "early_stop_iter", default = 10L, lower = 1L),
      makeLogicalLearnerParam(id = "verbose", default = FALSE,
        tunable = FALSE),
      makeUntypedLearnerParam(id = "CENTROIDS", default = NULL),
      makeNumericLearnerParam(id = "tol", default = 1e-04, lower = 0),
      makeNumericLearnerParam(id = "tol_optimal_init", default = 0.3, lower = 0),
      makeIntegerLearnerParam(id = "seed", default = 1L)
    ),
    par.vals = list(clusters = 2L),
    properties = c("numerics", "prob"),
    name = "MiniBatchKmeans",
    note = "Note",
    short.name = "MBatchKmeans",
    callees = c("MiniBatchKmeans", "predict_MBatchKMeans")
  )
}

#' @export
trainLearner.cluster.MiniBatchKmeans = function(.learner, .task, .subset, .weights = NULL, ...) {
  ClusterR::MiniBatchKmeans(getTaskData(.task, .subset), ...)
}

#' @export
predictLearner.cluster.MiniBatchKmeans = function(.learner, .model, .newdata, ...) {
  if (.learner$predict.type == "prob") {
    pred = ClusterR::predict_MBatchKMeans(data = .newdata,
      CENTROIDS = .model$learner.model$centroids,
      fuzzy = TRUE, ...)

    res = pred$fuzzy_clusters

    return(res)
  } else {
    pred = ClusterR::predict_MBatchKMeans(data = .newdata,
      CENTROIDS = .model$learner.model$centroids,
      fuzzy = FALSE, ...)

    res = as.integer(pred)

    return(res)
  }
}

Проблема (значение кластеров по умолчанию в par.vals выше игнорируется):

## When defining a value of clusters, it works as expected
lrn <- makeLearner("cluster.MiniBatchKmeans", clusters = 3L)
getLearnerParVals(lrn)
# The below commented lines are printed
# $clusters
# [1] 3

## When not providing a value for clusters, default is not used
lrn <- makeLearner("cluster.MiniBatchKmeans")
getLearnerParVals(lrn)
# The below commented lines are printed
# named list()

Любые советы о том, почему я вижу это поведение? Я проверил код других учащихся (например, cluster.kmeans, cluster.kkmeans и т. д.) и вижу, что они могут успешно определять значения по умолчанию в том же формате, что и я. Кроме того, вот документация, что это правильный путь.

Вот мой код на github, если он поможет воспроизвести проблему. Есть добавленный тестовый файл (в тестах/testthat), но у него есть свои проблемы.

Редактировать 1 – Фактическое сообщение об ошибке Вот фактическое сообщение об ошибке, которое я вижу, когда пытаюсь обучить учащегося без явного указания значения по умолчанию для «кластеров»:

lrn <- makeLearner("cluster.MiniBatchKmeans")
train(lrn, cluster_task)
 Error in ClusterR::MiniBatchKmeans(getTaskData(.task, .subset), ...) : 
  argument "clusters" is missing, with no default 
10.
ClusterR::MiniBatchKmeans(getTaskData(.task, .subset), ...) at RLearner_cluster_MiniBatchKmeans.R#32
9.
trainLearner.cluster.MiniBatchKmeans(.learner = structure(list(
    id = "cluster.MiniBatchKmeans", type = "cluster", package = "ClusterR", 
    properties = c("numerics", "prob"), par.set = structure(list(
        pars = list(clusters = structure(list(id = "clusters",  ... at trainLearner.R#24
8.
(function (.learner, .task, .subset, .weights = NULL, ...) 
{
    UseMethod("trainLearner")
})(.learner = structure(list(id = "cluster.MiniBatchKmeans",  ... 
7.
do.call(trainLearner, pars) at train.R#96
6.
fun3(do.call(trainLearner, pars)) at train.R#96
5.
fun2(fun3(do.call(trainLearner, pars))) at train.R#96
4.
fun1({
    learner.model = fun2(fun3(do.call(trainLearner, pars)))
}) at train.R#96
3.
force(expr) at helpers.R#93
2.
measureTime(fun1({
    learner.model = fun2(fun3(do.call(trainLearner, pars)))
})) at train.R#96
1.
train(lrn, cluster_task) 

person prasiddhi    schedule 09.03.2019    source источник


Ответы (1)


Код в вашем репозитории работает для меня - вы действительно получаете сообщение об ошибке при его запуске? То, как вы закодировали значение по умолчанию, на самом деле является скорее переопределением, а не значением по умолчанию. Вы, вероятно, хотите сделать

makeIntegerLearnerParam(id = "clusters", lower = 1L, default = 2L),

и удалите par.vals.

person Lars Kotthoff    schedule 09.03.2019
comment
Да, я получаю сообщение об ошибке при попытке вызвать обучение для этого учащегося (без явного указания аргумента кластера). Я обновил трассировку ошибок в деталях моего вопроса. - person prasiddhi; 09.03.2019
comment
У меня работает без ошибок: > train(lrn, makeClusterTask(id = "foo", iris[,-5])) Model for learner.id=cluster.MiniBatchKmeans; learner.class=cluster.MiniBatchKmeans Trained on: task.id = foo; obs = 150; features = 4 Hyperparameters: clusters=2 - person Lars Kotthoff; 09.03.2019
comment
Ладно, это сводит меня с ума. Я взял свежую копию, и она работала для меня. Я попытался изменить код, который вы предложили в своем ответе, и он перестал работать (та же ошибка). Это как-то связано с вызовом registerS3Method? - person prasiddhi; 09.03.2019
comment
Может быть, в зависимости от того, как именно вы его тестируете. Самый безопасный способ — каждый раз начинать новый сеанс R. - person Lars Kotthoff; 10.03.2019
comment
Поскольку в пакете нет значения по умолчанию для аргумента clusters, определенно правильно указать значение в par.vals. Значение по умолчанию в описании параметра просто косметическое. При разработке используйте devtools:load_all(), чтобы избежать проблем (без гарантии). - person jakob-r; 11.03.2019
comment
@ jakob-r Спасибо, я смог заставить это работать. Я наткнулся на объяснение, связанное с devtools, на основе r-pkgs.had.co.nz/ package.html, который я взял, потому что думал, что это связано с махинациями с пространством имен. - person prasiddhi; 12.03.2019