Использование аргументов bit.names и bits.to.features для makeFeatSelWrapper (mlr) для выбора оболочки над группами функций - PullRequest
0 голосов
/ 25 октября 2018

Я хотел бы выполнить выбор объекта методом обертки для набора данных радужной оболочки, используя пакет mlr, однако я хотел бы посмотреть только на группы объектов, связанных с Petal и / или Sepal.Таким образом, вместо того, чтобы рассматривать 4 объекта в разных комбинациях, процедура-оболочка будет рассматривать две группы объектов в разных комбинациях.

В документации mlr говорится, что это можно выполнить с использованием двух аргументов bit.names и bit.to.feature:

bit.names [символ] Имена битов, кодирующих решения.Также определяет общее количество бит в кодировке.По умолчанию это имена элементов задачи.

bits.to.features [function (x, task)] Функция, которая преобразует вектор целого числа 0-1 в вектор символов выбранных объектов.По умолчанию значение 1 в i-м бите выбирает i-ую функцию для решения-кандидата.

Я не смог найти никаких примеров использования этих двух аргументов в учебниках по mlr или где-либо еще.

Я буду использовать пример, приведенный в ?mlr::selectFeatures.

Сначала включите все функции

library(mlr)
rdesc <- makeResampleDesc("Holdout")
ctrl <- makeFeatSelControlSequential(method = "sfs",
                                    maxit = NA)
res <- selectFeatures("classif.rpart",
                     iris.task,
                     rdesc,
                     control = ctrl)
analyzeFeatSelResult(res)

Это работает, как и ожидалось

Для запусканад группами объектов я проектирую матрицу 0/1 для сопоставления объектов с группами (я не уверен, что это путь, это просто логично):

mati <- rbind(
  c(0,0,1,1),
  c(1,1,0,0))

rownames(mati) <- c("Petal", "Sepal")
colnames(mati) <- getTaskFeatureNames(iris.task)

матрица выглядит так:

      Sepal.Length Sepal.Width Petal.Length Petal.Width
Petal            0           0            1           1
Sepal            1           1            0           0

и теперь я запускаю:

res <- selectFeatures("classif.rpart",
                     iris.task,
                     rdesc,
                     control = ctrl,
                     bit.names = c("Petal", "Sepal"),
                     bits.to.features = function(x = mati, task) mlr:::binaryToFeatures(x, getTaskFeatureNames(task)))

analyzeFeatSelResult(res)
#output
Features         : 1
Performance      : mmce.test.mean=0.0200000
Sepal

Path to optimum:
- Features:    0  Init   :                       Perf = 0.66  Diff: NA  *
- Features:    1  Add    : Sepal                 Perf = 0.02  Diff: 0.64  *

Stopped, because no improving feature was found.

Это, кажется, выполняет то, что мне нужно, но я не совсем уверен, что правильно определил аргумент bits.to.features.

Но когда я пытаюсь использовать тот же подход в оболочке:

outer <- makeResampleDesc("CV", iters = 2L)
inner <- makeResampleDesc("Holdout")
ctrl <- makeFeatSelControlSequential(method = "sfs",
                                     maxit = NA)


lrn <- makeFeatSelWrapper("classif.rpart",
                          resampling = inner,
                          control = ctrl,
                          bit.names = c("Petal", "Sepal"),
                          bits.to.features = function(x = mati, task) mlr:::binaryToFeatures(x, getTaskFeatureNames(task)))


r <- resample(lrn, iris.task, outer, extract = getFeatSelResult)

я получаю сообщение об ошибке:

Resampling: cross-validation
Measures:             mmce      
[FeatSel] Started selecting features for learner 'classif.rpart'
With control class: FeatSelControlSequential
Imputation value: 1
[FeatSel-x] 1: 00 (0 bits)
[FeatSel-y] 1: mmce.test.mean=0.7200000; time: 0.0 min
[FeatSel-x] 2: 10 (1 bits)
[FeatSel-y] 2: mmce.test.mean=0.0800000; time: 0.0 min
[FeatSel-x] 2: 01 (1 bits)
[FeatSel-y] 2: mmce.test.mean=0.0000000; time: 0.0 min
[FeatSel-x] 3: 11 (2 bits)
[FeatSel-y] 3: mmce.test.mean=0.0800000; time: 0.0 min
[FeatSel] Result: Sepal (1 bits)
Error in `[.data.frame`(df, , j, drop = drop) : 
  undefined columns selected

Что я делаю неправильно и чтоправильное использование аргументов bit.names и bit.to.feature?

Спасибо

РЕДАКТИРОВАТЬ: я разместил вопрос на mlr github: https://github.com/mlr-org/mlr/issues/2468

1 Ответ

0 голосов
/ 05 ноября 2018

Полагаю, вы нашли две ошибки.Во-первых, ваш код даже выполняется, а во-вторых, он не будет работать с вложенной повторной выборкой.

Ошибка 1: Ваш код не должен запускаться

Прежде всего mati делаетне имеет никакого эффекта, потому что он будет перезаписываться при каждом внутреннем вызове bits.to.features.В конце концов, вы просто определили аргумент по умолчанию.

То, что вы определили bit.names "Petal" и "Sepal", вы в основном просто сказали mlr использовать два бита.Таким образом, выбор функции будет работать с векторами 00, 01, 10, 11. К сожалению, R теперь автоматически перезагружает эти векторы до длины 4, поэтому 10 становится 1010:

mlr:::binaryToFeatures(c(1,0), getTaskFeatureNames(iris.task))
# [1] "Sepal.Length" "Petal.Length"

Там у нас есть первая ошибка,что в mlr следует избегать повторного использования вектора.

Чтобы код работал так, как задумано, вы можете определить функцию bits.to.features следующим образом:

bitnames = c("Sepal", "Petal")
btf = function(x, task) {
  sets = list(
    c("Sepal.Length", "Sepal.Width"), 
    c("Petal.Length", "Petal.Width")
  )
  res = unlist(sets[as.logical(x)])
  if (is.null(res)) {
    return(character(0L))
  } else {
    return(res)  
  }
}

res <- selectFeatures("classif.rpart", iris.task, rdesc, 
  control = ctrl, bits.to.features = btf, bit.names = bitnames)

Объяснение bts

Цитирование страницы справки selectFeatures:

[function(x, task)] Функция, которая преобразует вектор целого числа 0-1 в вектор символов выбранных объектов.По умолчанию значение 1 в i-м бите выбирает i-ую функцию для решения-кандидата.

Так что x - это вектор, содержащий 0 и 1 (например, c(0,0,1,0)).Если вы не измените эту функцию, она вернет имя третьей функции (например, "Petal.Length" для радужной оболочки).Вектор x всегда будет иметь ту же длину, что и определенный bit.names.Результирующий вектор символов, однако, может иметь любую длину.Он просто должен вернуть действительные имена объектов для задачи.

В примере я жестко закодировал названия функций в функцию bts.Это плохая практика, если вы хотите применить функцию для множества различных задач.Таким образом, mlr дает вам доступ к объекту task и, следовательно, также к именам элементов через getTaskFeatureNames(task), так что вы можете генерировать имена элементов программно, а не в жестком коде.

Ошибка 2: bit.names должны быть именами элементов

Выбор функции возвращает имена битов в результате.Затем mlr пытается выбрать эти битовые имена в наборе данных, но, очевидно, их нет, так как они совершенно не связаны (в вашем случае). Эта ошибка теперь устранена в версии mlr для github.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...