Prever o Day-Ahead em ambiente paralelizado e escalável – Pacote H2O – R ou Python

Seguindo minha pergunta respondida: R ou Python – faça o loop dos dados de teste – Validação de previsão nas próximas 24 horas (96 valores por dia)

Eu quero prever o próximo dia usando o pacote H2o. Você pode encontrar explicações detalhadas para o meu dataset no mesmo link acima .

A dimensão de dados no H2o é diferente.

Então, depois de fazer a previsão, eu quero calcular o MAPE

Eu tenho que mudar o treinamento e testar dados para o formato H2o

train_h2o <- as.h2o(train_data) test_h2o <- as.h2o(test_data) mape_calc <- function(sub_df) { pred <- predict.glm(glm_model, sub_df) actual <- sub_df$Ptot mape <- 100 * mean(abs((actual - pred)/actual)) new_df <- data.frame(date = sub_df$date[[1]], mape = mape) return(new_df) } # LIST OF ONE-ROW DATAFRAMES df_list <- by(test_data, test_data$date, map_calc) # FINAL DATAFRAME final_df <- do.call(rbind, df_list) 

O código superior funciona bem para a validação de previsão ” Não-H2o ” para o dia seguinte e calcula o MAPE para todos os dias.

Eu tentei converter o modelo H2O previsto para o formato normal, mas de acordo com: https://stackoverflow.com/a/39221269/9341589 , não é possível.

Para fazer uma previsão no H2O:

por exemplo, digamos que queremos criar um modelo random de floresta

 y <- "RealPtot" #target x % setdiff(y) #features rforest.model <- h2o.randomForest(y=y, x=x, training_frame = train_h2o, ntrees = 2000, mtries = 3, max_depth = 4, seed = 1122) 

Então, podemos obter a previsão para o dataset completo, conforme mostrado abaixo.

 predict.rforest <- as.data.frame(h2o.predict(rforest.model, test_h2o) 

Mas no meu caso eu estou tentando obter uma previsão de um dia usando o mape_calc


NOTA: Qualquer pensamento em R ou Python será apreciado.

UPDATE2 (exemplo reprodutível ): ** Seguindo as etapas do @Darren Cook:

Eu forneci um exemplo mais simples – dataset de habitação de Boston.

 library(tidyverse) library(h2o) h2o.init(ip="localhost",port=54322,max_mem_size = "128g") data(Boston, package = "MASS") names(Boston) [1] "crim" "zn" "indus" "chas" "nox" "rm" "age" "dis" "rad" "tax" "ptratio" [12] "black" "lstat" "medv" set.seed(4984) #Added 15 minute Time and date interval Boston$date<- seq(as.POSIXct("01-09-2017 03:00", format = "%d-%m-%Y %H:%M",tz=""), by = "15 min", length = 506) #select first 333 values to be trained and the rest to be test data train = Boston[1:333,] test = Boston[334:506,] #Dropped the date and time train_data_finialized <- subset(train, select=-c(date)) test_data_finialized <- test #Converted the dataset to h2o object. train_h2o<- as.h2o(train_data_finialized) #test_h2o<- as.h2o(test) #Select the target and feature variables for h2o model y <- "medv" #target x % setdiff(y) #feature variables # Number of CV folds (to generate level-one data for stacking) nfolds <- 5 #Replaced RF model by GBM because GBM run faster # Train & Cross-validate a GBM my_gbm <- h2o.gbm(x = x, y = y, training_frame = train_h2o, nfolds = nfolds, fold_assignment = "Modulo", keep_cross_validation_predictions = TRUE, seed = 1) mape_calc <- function(sub_df) { p <- h2o.predict(my_gbm, as.h2o(sub_df)) pred <- as.vector(p) actual <- sub_df$medv mape <- 100 * mean(abs((actual - pred)/actual)) new_df <- data.frame(date = sub_df$date[[1]], mape = mape) return(new_df) } # LIST OF ONE-ROW DATAFRAMES df_list <- by(test_data_finialized, test_data_finialized$date, mape_calc) final_df <- do.call(rbind, df_list) 

Este é o erro que estou recebendo agora:

Erro em .h2o.doSafeREST (h2oRestApiVersion = h2oRestApiVersion, urlSuffix = page,:

MENSAGEM DE ERRO:

Tipo de coluna fornecido POSIXct é desconhecido. Não é possível prosseguir com a análise devido ao argumento inválido.

H2O está sendo executado em um processo separado para R (se o H2O está no servidor local ou em um data center distante). Os dados de H2O e os modelos de H2O são mantidos nesse processo de H2O e não podem ser vistos por R.

O que dH <- as.h2o(dR) faz é copiar um quadro de dados R, dR , para o espaço de memory do H2O. O dH é então uma variável R que descreve o quadro de dados de H2O. Ou seja, é um ponteiro ou uma alça; não são os dados em si.

O que dR <- as.data.frame(dH) faz é copiar os dados da memory do processo H2O para a memory do processo R. ( as.vector(dH) faz o mesmo para quando dH descreve uma única coluna)

Portanto, a maneira mais simples de modificar seu mape_calc() , supondo que sub_df seja um quadro de dados R, é alterar as duas primeiras linhas da seguinte maneira:

 mape_calc <- function(sub_df) { p <- h2o.predict(rforest.model, as.h2o(sub_df)) pred <- as.vector(p) actual <- sub_df$Ptot mape <- 100 * mean(abs((actual - pred)/actual)) new_df <- data.frame(date = sub_df$date[[1]], mape = mape) return(new_df) } 

sub_df seja, envie sub_df para H2O e dê isso para h2o.predict() . Em seguida, use as.vector() para baixar a previsão que foi feita.

Isso foi relativo ao seu código original. Portanto, mantenha a versão original disso:

 # LIST OF ONE-ROW DATAFRAMES df_list <- by(test_data, test_data$date, map_calc) 

test_h2o seja, não use by() diretamente no test_h2o .

h2o.predict() : h2o.predict() é mais eficiente ao trabalhar em um lote de dados para fazer previsões. Colocar h2o.predict() dentro de um loop é um cheiro de código. Seria melhor chamar h2o.predict(rforest.model, test_h2o) uma vez, fora do loop, fazer o download das predições em R e cbind las a test_data e, em seguida, usar esses dados combinados.

ASIDE 2: Você obteria melhores respostas se fizesse o infame exemplo mínimo . Então as pessoas podem executar seu código e elas podem testar suas respostas. Também é sempre melhor usar um dataset simples que todos tenham, por exemplo, iris, em vez de seus próprios dados. (Você pode fazer regressão em qualquer um dos primeiros 4 campos; usar íris não tem que ser sempre sobre a previsão da espécie.)

ASIDE 3 : Você pode fazer o MAPE completamente dentro do H2O, já que as funções abs() e mean() funcionarão diretamente nos frameworks de dados H2O (assim como muitas outras coisas - veja o manual do H2O): https://stackoverflow.com/ a / 43103229/841830 (Eu não estou marcando isso como uma duplicata, como sua pergunta foi como adaptar by() para uso com frames de dados H2O, não como calcular o MAPE de forma eficiente!)

Parece que você está misturando tipos de dados R e H2O. Lembre-se de R de H2O é simplesmente uma API R e não é o mesmo que R. nativo Isso significa que você não pode aplicar uma function R que espera um dataframe R para um H2OFrame. E da mesma forma você não pode aplicar uma function H2O a um dataframe R quando ele espera um H2OFrame.

Como você pode ver na documentação do R by ele, é uma function que espera “um object R, normalmente um quadro de dados, possivelmente uma matriz”, para que você não possa passar em um quadro de H2O.

Da mesma forma você está passando date = H2OFrame para data.frame() .

No entanto, você pode usar o as.data.frame() para converter um H2OFrame em um dataframe R e depois realizar seus cálculos totalmente em R.

    Intereting Posts