2017-10-01 7 views
0

caretモデルをpurrr::invoke_map()を使用してRのリスト列フォーマット(this blog post参照)内から訓練しようとしています。purrr :: invoke_map()からコンソールに印刷

invoke_map()を呼び出すと、何らかの方法で進捗状況を監視できます。具体的には、行番号またはid列をinvoke_map()としてモデル/データの組み合わせを反復して印刷したいとします。トレーニング機能(下記のlinearRegModel())を変更して、これを行う方法はありますか?

library(tidyverse) 
library(mlbench) 
library(caret) 
data("BostonHousing") # from mlbench 


starter_df <- 
    list(BostonHousing) %>% 
    rep(3) %>% 
    enframe(name = 'id', value = 'rawdata') %>% 
    transmute(
    id 
    , train.X = map(rawdata, ~ .x %>% select(-medv)) 
    , train.Y = map(rawdata, ~ .x$medv) 
) 



# re-write any caret training method as a function. 
# using linear regression here for simplicity 
linearRegModel <- function(X, Y) { 
ctrl <- trainControl(
    method = "repeatedcv", 
    number = 2 
) 
    train(
    x = X, 
    y = Y, 
    method = 'lm', 
    trControl = ctrl, 
    preProc = c('center', 'scale') 
) 
} 


# convert models to tibble 
model_list <- 
    list(linearRegModel = linearRegModel, 
     linearRegModel2 = linearRegModel) %>% 
    enframe(name = 'modelName',value = 'model') 

# combine model tibble with the data tibble 
train_df <- 
    starter_df[rep(1:nrow(starter_df),nrow(model_list)),] %>% 
    bind_cols(
    model_list[rep(1:nrow(model_list),nrow(starter_df)),] %>% arrange(modelName) 
) %>% 
    mutate(id=1:nrow(.)) 

train_df 



# A tibble: 6 x 5 
    id     train.X  train.Y  modelName model 
    <int>     <list>  <list>   <chr> <list> 
1  1 <data.frame [506 x 13]> <dbl [506]> linearRegModel <fun> 
2  2 <data.frame [506 x 13]> <dbl [506]> linearRegModel <fun> 
3  3 <data.frame [506 x 13]> <dbl [506]> linearRegModel <fun> 
4  4 <data.frame [506 x 13]> <dbl [506]> linearRegModel2 <fun> 
5  5 <data.frame [506 x 13]> <dbl [506]> linearRegModel2 <fun> 
6  6 <data.frame [506 x 13]> <dbl [506]> linearRegModel2 <fun> 


# train models by calling invoke_map() 
# (takes a few seconds) 
data_with_model_fits <- 
    train_df %>% 
    mutate(params = map2(train.X, train.Y, ~ list(X = .x, Y = .y)), 
     modelFits = invoke_map(model,params) 
) 

答えて

1

progressパッケージが興味深いかもしれません。私はあなたの問題にそれを統合しました。二つのことに注意してください。あなたはprogress::progress_bar(tick = number_of_ticks)でモデルに合わせて開始する前に

  • あなたはプログレスバーを初期化します。

  • linRegModel()の内部では、モデルがpb$tick()に収まった後、進行状況バーを「チック」します。

pbオブジェクト指向技術を使用してR6オブジェクトであるので、あなたは、引数としてあなたlinRegModel()機能にそれを渡す必要はありません。

希望します。柔軟性のために

library(tidyverse) 
library(mlbench) 
library(caret) 

data("BostonHousing") # from mlbench 

library(progress) 

starter_df <- 
    list(BostonHousing) %>% 
    rep(3) %>% 
    enframe(name = 'id', value = 'rawdata') %>% 
    transmute(
     id 
     , train.X = map(rawdata, ~ .x %>% select(-medv)) 
     , train.Y = map(rawdata, ~ .x$medv) 
    ) 



# re-write any caret training method as a function. 
# using linear regression here for simplicity 
linearRegModel <- function(X, Y) { 
    ctrl <- trainControl(
     method = "repeatedcv", 
     number = 2 
    ) 
    train(
     x = X, 
     y = Y, 
     method = 'lm', 
     trControl = ctrl, 
     preProc = c('center', 'scale') 
    ) 

    # Tick the progress bar forward 1 tick after each completed model fit 
    pb$tick() 
} 


# convert models to tibble 
model_list <- 
    list(linearRegModel = linearRegModel, 
     linearRegModel2 = linearRegModel) %>% 
    enframe(name = 'modelName',value = 'model') 

# combine model tibble with the data tibble 
train_df <- 
    starter_df[rep(1:nrow(starter_df),nrow(model_list)),] %>% 
    bind_cols(
     model_list[rep(1:nrow(model_list),nrow(starter_df)),] %>% arrange(modelName) 
    ) %>% 
    mutate(id=1:nrow(.)) 

train_df 


# initialize progress bar 
ticks <- nrow(train_df) 
pb <- progress::progress_bar$new(total = ticks) 

# train models by calling invoke_map() 
# (takes a few seconds) 
data_with_model_fits <- 
train_df %>% 
mutate(params = map2(train.X, train.Y, ~ list(X = .x, Y = .y)), 
     modelFits = invoke_map(model,params) 
) 

プログレスバーを作成するとき、あなたはformat引数を通じてtokenを使用することができます。現在の繰り返しを表示するために、:currentのようないくつかが組み込まれています。これはあなたの質問に直接答えるかもしれません。この場合、モデルが実行される前にpb$tick()と呼んでいます。また、ドキュメントでは、長時間実行する前にpb$tick(0)を実行してすぐに進行状況バーを表示するように指示しています。

# initialize progress bar 
pb <- progress::progress_bar$new(format = "running model :current", show_after = .01) 
pb$tick(0) 
+0

ありがとう!これは問題を解決し、トークンを使用して、個々のモデルが実行されているときにそれらを印刷することができます。 –

関連する問題