Ошибка при попытке передать пользовательскую метрику в пакете Caret - PullRequest
0 голосов
/ 12 ноября 2018

Смежный вопрос - 1

У меня есть такой набор данных:

> head(training_data)
  year     month channelGrouping visitStartTime visitNumber timeSinceLastVisit browser
1 2016   October          Social     1477775021           1                  0  Chrome
2 2016 September          Social     1473037945           1                  0  Safari
3 2017      July  Organic Search     1500305542           1                  0  Chrome
4 2017      July  Organic Search     1500322111           2              16569  Chrome
5 2016    August          Social     1471890172           1                  0  Safari
6 2017       May          Direct     1495146428           1                  0  Chrome         
  operatingSystem isMobile continent     subContinent       country      source   medium
1         Windows        0  Americas    South America        Brazil youtube.com referral
2       Macintosh        0  Americas Northern America United States youtube.com referral
3         Windows        0  Americas Northern America        Canada      google  organic
4         Windows        0  Americas Northern America        Canada      google  organic
5       Macintosh        0    Africa   Eastern Africa        Zambia youtube.com referral
6         Android        1  Americas Northern America United States    (direct)         
  isTrueDirect hits pageviews positiveTransaction
1            0    1         1                  No
2            0    1         1                  No
3            0    5         5                  No
4            1    3         3                  No
5            0    1         1                  No
6            1    6         6                  No

> str(training_data)
'data.frame':   1000 obs. of  18 variables:
 $ year               : int  2016 2016 2017 2017 2016 2017 2016 2017 2017 2016 ...
 $ month              : Factor w/ 12 levels "January","February",..: 10 9 7 7 8 5 10 3 3 12 ...
 $ channelGrouping    : chr  "Social" "Social" "Organic Search" "Organic Search" ...
 $ visitStartTime     : int  1477775021 1473037945 1500305542 1500322111 1471890172 1495146428 1476003570 1488556031 1490323225 1480696262 ...
 $ visitNumber        : int  1 1 1 2 1 1 1 1 1 1 ...
 $ timeSinceLastVisit : int  0 0 0 16569 0 0 0 0 0 0 ...
 $ browser            : chr  "Chrome" "Safari" "Chrome" "Chrome" ...
 $ operatingSystem    : chr  "Windows" "Macintosh" "Windows" "Windows" ...
 $ isMobile           : int  0 0 0 0 0 1 0 1 0 0 ...
 $ continent          : Factor w/ 5 levels "Africa","Americas",..: 2 2 2 2 1 2 3 3 2 4 ...
 $ subContinent       : chr  "South America" "Northern America" "Northern America" "Northern America" ...
 $ country            : chr  "Brazil" "United States" "Canada" "Canada" ...
 $ source             : chr  "youtube.com" "youtube.com" "google" "google" ...
 $ medium             : chr  "referral" "referral" "organic" "organic" ...
 $ isTrueDirect       : int  0 0 0 1 0 1 0 0 0 0 ...
 $ hits               : int  1 1 5 3 1 6 1 1 2 1 ...
 $ pageviews          : int  1 1 5 3 1 6 1 1 2 1 ...
 $ positiveTransaction: Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 1 1 …

Затем я определяю свою пользовательскую функцию RMSLE, используя пакет Metrics:

rmsleMetric <- function(data, lev = NULL, model = NULL){
    out <- Metrics::rmsle(data$obs, data$pred)
    names(out) <- c("rmsle")
    return (out)
}

Затем я определяю trainControl:

tc <- trainControl(method = "repeatedcv",
   number = 5,
   repeats = 5,
   summaryFunction = rmsleMetric,
   classProbs = TRUE)

Мой поиск по сетке:

tg <- expand.grid(alpha = 0, lambda = seq(0, 1, by = 0.1))

Наконец, моя модель:

penalizedLogit_ridge <- train(positiveTransaction ~ .,
    data = training_data,
    metric="rmsle",
    method = "glmnet",
    family = "binomial",
    trControl = tc,
    tuneGrid = tg
)

Когда я пытаюсь выполнить указанную выше команду, я получаю сообщение об ошибке:

Something is wrong; all the rmsle metric values are missing:
     rmsle
 Min.   : NA
 1st Qu.: NA
 Median : NA
 Mean   :NaN
 3rd Qu.: NA
 Max.   : NA
 NA's   :11
Error: Stopping
In addition: There were 50 or more warnings (use warnings() to see the first 50)

Глядя на предупреждения, я нахожу:

1: In Ops.factor(1, actual) : ‘+’ not meaningful for factors
2: In Ops.factor(1, predicted) : ‘+’ not meaningful for factors

повторяется 25 раз

Поскольку то же самое работает нормально, если я изменяю метрику на AUC, используя prSummary в качестве моей сводной функции, я не верю, что есть какие-либо проблемы с моими данными.

Итак, я считаю, что моифункция неправильная, но я не знаю, как выяснить, почему она неправильная.

Любая помощь высоко ценится.

1 Ответ

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

Ваш пользовательский показатель не определен правильно. Если вы используете classProbs = TRUE и savePredictions = "final" с trainControl, вы поймете, что есть два столбца, названных в соответствии с вашими целевыми классами, которые содержат предсказанные вероятности, в то время как столбец data$pred содержит предсказанный класс, который не может использоваться для вычисления желаемый показатель.

Правильный способ определить функцию - получить возможные уровни и использовать их для извлечения вероятностей для одного из классов:

rmsleMetric <- function(data, lev = NULL, model = NULL){
  lvls <- levels(data$obs)
  out <- Metrics::rmsle(ifelse(data$obs == lev[2], 0, 1),
                        data[, lvls[1]])
  names(out) <- c("rmsle")
  return (out)
}

это работает:

library(caret)
library(mlbench)
data(Sonar)
tc <- trainControl(method = "repeatedcv",
                   number = 2,
                   repeats = 2,
                   summaryFunction = rmsleMetric,
                   classProbs = TRUE,
                   savePredictions = "final")
tg <- expand.grid(alpha = 0, lambda = seq(0, 1, by = 0.1))

penalizedLogit_ridge <- train(Class ~ .,
                              data = Sonar,
                              metric="rmsle",
                              method = "glmnet",
                              family = "binomial",
                              trControl = tc,
                              tuneGrid = tg)

#output
glmnet 

208 samples
 60 predictor
  2 classes: 'M', 'R' 

No pre-processing
Resampling: Cross-Validated (2 fold, repeated 2 times) 
Summary of sample sizes: 105, 103, 104, 104 
Resampling results across tuning parameters:

  lambda  rmsle    
  0.0     0.2835407
  0.1     0.2753197
  0.2     0.2768288
  0.3     0.2797847
  0.4     0.2827953
  0.5     0.2856088
  0.6     0.2881894
  0.7     0.2905501
  0.8     0.2927171
  0.9     0.2947169
  1.0     0.2965505

Tuning parameter 'alpha' was held constant at a value of 0
rmsle was used to select the optimal model using the largest value.
The final values used for the model were alpha = 0 and lambda = 1.

Вы можете проверить caret::twoClassSummary - он определен аналогично.

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