Вызовите R на Java для ARIMA - PullRequest
0 голосов
/ 05 июня 2018

Я пытаюсь вызвать R в JAVA для функции ARIMA.Первый пример запускает arima ().Это работает хорошо.

Rengine rengine = new Rengine(new String[]{"--vanilla"},false,null);
System.out.println("  *BEGIN*  ");
rengine.eval("library(forecast)");
double[] trainingData = = {10930,10318,10595,10972,7706,6756,9092,10551,9722,10913,11151,8186,6422,
            + 6337,11649,11652,10310,12043,7937,6476,9662,9570,9981,9331,9449,6773,6304,9355,10477,
            + 10148,10395,11261,8713,7299,10424,10795,11069,11602,11427,9095,7707,10767,12136,12812,
            + 12006,12528,10329,7818,11719,11683,12603,11495,13670,11337,10232,13261,13230,15535,
            + 16837,19598,14823,11622,19391,18177,19994,14723,15694,13248,9543,12872,13101,15053,
            + 12619,13749,10228,9725,14729,12518,14564,15085,14722,11999,9390,13481,14795,15845,
            + 15271,14686,11054,10395,14775,14618,16029,15231,14246,12095,10473,15323,15381,14947};
rengine.assign("value", trainingData);
rengine.eval("traindatats<-ts(value)");
rengine.eval("loopMinLag<-0");
rengine.eval("loopMaxLag<-8");
rengine.eval("best.order <- c(loopMinLag, 1, loopMinLag)");
rengine.eval("best.aic = Inf");
rengine.eval("for(P in loopMinLag:loopMaxLag) { for(Q in loopMinLag:loopMaxLag) { myModel <- arima(traindatats, order=c(P,1,Q), method='ML'); fit.aic <- myModel$aic;  if(fit.aic < best.aic) { best.order <- c(P, 1, Q);  best.aic <- fit.aic; }  } }");
rengine.eval("model <- list()");
rengine.eval("model$P <- best.order[1]");
rengine.eval("model$D <- 1");
rengine.eval("model$Q <- best.order[3]");
rengine.eval("ar<-arima(traindatats,order=c(model$P,model$D,model$Q))");
rengine.eval("f<-predict(ar,n.ahead=7)");
System.out.println("  *RESULT*  ");
double forecast[] = new double[7];
for (int i = 0,j=1; i < 7; i++,j++) {
          forecast[i] = rengine.eval("f$pred[" + j + "]").asDouble();
          System.out.print(" "+forecast[i]);
      }
System.out.println("\r\n  *DONE* ");

В результате получается значения прогноза для следующих 7 чисел .Для arima () в JAVA проблем не возникает.Второй пример запускает auto.arima ().Тем не менее, это не работает.Кто-нибудь знает, почему он не может работать?

Rengine rengine = new Rengine(new String[]{"--vanilla"},false,null);
System.out.println("  *BEGIN*  ");
rengine.eval("library(forecast)");
double[] trainingData =  {10930,10318,10595,10972,7706,6756,9092,10551,9722,10913,11151,8186,6422,
            + 6337,11649,11652,10310,12043,7937,6476,9662,9570,9981,9331,9449,6773,6304,9355,10477,
            + 10148,10395,11261,8713,7299,10424,10795,11069,11602,11427,9095,7707,10767,12136,12812,
            + 12006,12528,10329,7818,11719,11683,12603,11495,13670,11337,10232,13261,13230,15535,
            + 16837,19598,14823,11622,19391,18177,19994,14723,15694,13248,9543,12872,13101,15053,
            + 12619,13749,10228,9725,14729,12518,14564,15085,14722,11999,9390,13481,14795,15845,
            + 15271,14686,11054,10395,14775,14618,16029,15231,14246,12095,10473,15323,15381,14947};
Rengine rengine = new Rengine(new String[]{"--vanilla"},false,null);
System.out.println("  *BEGIN*  ");
rengine.assign("value", trainingData);
rengine.eval("traindatats<-ts(value)");
rengine.eval("ar<-auto.arima(traindatats)");
rengine.eval("f<-predict(ar,n.ahead=" + 7 + ")");
double forecast[] = new double[7];
for (int i = 0,j=1; i < forcastSize; i++,j++) {
          forecast[i] = rengine.eval("f$pred[" + j + "]").asDouble();
          System.out.print(" "+forecast[i]);
}
System.out.println("  *DONE*  ");

Сообщение об ошибке «Исключение в потоке» main «java.lang.NullPointerException» для строки forecast[i] = rengine.eval("f$pred[" + j + "]").asDouble();

PS.Оба примера для arima () и auto.arima () могут работать в R правильно.Соответствующий код R для auto.arima () может корректно работать в R, как показано в примере auto.arima R .

1 Ответ

0 голосов
/ 06 июня 2018

Здесь:

rengine.eval("f$pred[" + j + "]").asDouble();

rengine.eval("f$pred[" + j + "]") это значение равно нулю.

Согласно: http://www.rforge.net/org/doc/org/rosuda/JRI/Rengine.html#eval(java.lang.String)

eval

public REXP eval (java.lang.String s)

Parses and evaluates an R expression and returns the result. Has the same effect as calling eval(s, true).

Parameters:

    s - expression (as string) to parse and evaluate
Returns:
    resulting expression or null if something wnet wrong

Похоже, что-то не так на стороне R.

Ну, возможно, у вас есть какие-то проблемыс библиотеками и т. д.

Если я устанавливаю прогноз

install.packages('forecast')

внутри R, и я называю код следующим образом:

javac -cp /Library/Frameworks/R.framework/Versions/3.5/Resources/library/rJava/jri/JRI.jar SimpleR.java
java -Djava.library.path=/Library/Frameworks/R.framework/Versions/3.5/Resources/library/rJava/jri -cp .:/Library/Frameworks/R.framework/Versions/3.5/Resources/library/rJava/jri/JRI.jar SimpleR
  *BEGIN*
Forecast: 0
Result: 14436.670778092368
Forecast: 1
Result: 14104.789779948998
Forecast: 2
Result: 14104.789779948998
Forecast: 3
Result: 14104.789779948998
Forecast: 4
Result: 14104.789779948998
  *DONE*

Я получаю правильный вывод.Мой SimpleR.java выглядит следующим образом:

import org.rosuda.JRI.*;

public class SimpleR {

  public static void main(String [] arg) {
    Rengine rengine = new Rengine(new String[]{"--vanilla"},false,null);
    System.out.println("  *BEGIN*  ");
    // enable R log
    rengine.eval("log<-file('/tmp/file.log')");
    rengine.eval("sink(log, append=TRUE)");
    rengine.eval("sink(log, append=TRUE, type='message')");
    rengine.eval("library(forecast)");
    double[] trainingData =  {10930,10318,10595,10972,7706,6756,9092,10551,9722,10913,11151,8186,6422,
            + 6337,11649,11652,10310,12043,7937,6476,9662,9570,9981,9331,9449,6773,6304,9355,10477,
            + 10148,10395,11261,8713,7299,10424,10795,11069,11602,11427,9095,7707,10767,12136,12812,
            + 12006,12528,10329,7818,11719,11683,12603,11495,13670,11337,10232,13261,13230,15535,
            + 16837,19598,14823,11622,19391,18177,19994,14723,15694,13248,9543,12872,13101,15053,
            + 12619,13749,10228,9725,14729,12518,14564,15085,14722,11999,9390,13481,14795,15845,
            + 15271,14686,11054,10395,14775,14618,16029,15231,14246,12095,10473,15323,15381,14947};
    rengine.assign("value", trainingData);
    rengine.eval("traindatats<-ts(value)");
    rengine.eval("ar<-auto.arima(traindatats)");
    REXP result = rengine.eval("f<-predict(ar,n.ahead=" + 5 + ")");
    if(result == null) {
      System.out.println("Error");
    }
    double forecast[] = new double[5];
    for (int i = 0;i < 5;i++) {
      System.out.println("Forecast: " + i);
      forecast[i] = rengine.eval("f$pred[" + (i+1) + "]").asDouble();
      System.out.println("Result: " + forecast[i]);
    }
    System.out.println("  *DONE*  ");
  }
}

Кажется, он работает нормально.

При входе я ссылаюсь на код:

rengine.eval("log<-file('/tmp/file.log')");
rengine.eval("sink(log, append=TRUE)");
rengine.eval("sink(log, append=TRUE, type='message')");
...