0

在过去的几个小时里,我有一个问题一直让我发疯。

我在 R 中使用以下包:forecast、、、fracdiff等。我也有以下功能。doParallelforeach

doparPredictions <- function(train, test, cl){
    training = train
    pred = foreach (i = 1:length(test), .combine=c) %dopar% {
        if (i > 1) {
            training = c(train,test[1:i-1])
        }
        fit = nnetar(training, 8, P=1, 5)
        forecast(fit, 1)$mean
    }
}

...并且上述功能有效!

但是,如果我nnetar(training, 8, P=1, 5)fracdiff(training, 3, 1, h=0.00001)函数替换开始失败并出现以下错误。

Error in { : task 1 failed - "object 'training' not found"

这就是有趣的地方。它实际上并没有在编辑的行上失败。它实际上在下一行失败:forecast(fit, 1)$mean

换句话说,以下确实有效。

fits = foreach (i = 1:length(test)) %dopar% {
    if (i > 1) {
        training = c(train,test[1:i-1])
    }
    fracdiff(training, p, q, h=0.00001)
}

但是之后...

pred = foreach (i = 1:length(test), .combine=c) %dopar% {
    forecast(fits[[i]], 1)$mean
}

抛出前面提到的关于"object 'training' not found"

编辑:根据要求......一个可重现的例子......

require(quantmod)
require(forecast)
require(fracdiff)
require(doParallel)
require(foreach)

cl <- makeCluster((detectCores() - 1), type="FORK")
registerDoParallel(cl)

predictionsThatWork <- function(train, test, cl){
    training = train
    pred = foreach (i = 1:length(test), .combine=c) %dopar% {
        if (i > 1) {
            training = c(train,test[1:i-1])
        }
        fit = nnetar(training, 8, P=1, 5)
        forecast(fit, 1)$mean
    }
    return(pred)
}

predictionsThatDoNotWork <- function(train, test, cl){
    training = train
    pred = foreach (i = 1:length(test), .combine=c) %dopar% {
        if (i > 1) {
            training = c(train,test[1:i-1])
        }
        fit = fracdiff(training, 3, 1, h=0.00001)
        forecast(fit, 1)$mean
    }
    return(pred)
}

ticker = 'IBM' #feel free to replace with ticker of your choice
getSymbols(ticker, from='2010-01-01', to='2016-08-31')
fullts = get(ticker)
returnTS = diff(log(fullts[,4]),lag=1)[-1]
returnTS = returnTS - mean(returnTS)
numObs = length(returnTS)
cutOff = ceiling(numObs*.85)
train = returnTS[1:cutOff-1]
test = returnTS[cutOff:numObs]

predictionsThatWork(train, test, cl)
predictionsThatDoNotWork(train, test, cl)

stopCluster(cl)

编辑2:好的,这个问题与并行性无关。fracdiff这与和之间的交互有关forecast。以下功能也不起作用

anotherBrokenFunction <- function(train, test) {
    training = train
    print(exists('training'))
    predictions = test
    for (i in 1:length(test)){
        print(exists('training'))
        arf = fracdiff(x=training, nar=3, nma=1, h=0.00001)
        print(exists('training'))
        predictions[i] = forecast(arf, 1)$mean
        print(exists('training'))
        training = c(training, test[i])
    }
    return(predictions)
}

它评估为以下

> anotherBrokenFunction(train, test)
[1] TRUE
[1] TRUE
[1] TRUE
Error in eval(expr, envir, enclos) : object 'training' not found
4

1 回答 1

1

这是一个 hacky 修复,但一个建议是添加arf$x <- training到函数中:

anotherBrokenFunction <- function(train, test) {
    training = train
    predictions = test
    for (i in 1:length(test)){
        arf = fracdiff(x=training, nar=3, nma=1, h=0.00001)
        arf$x <- training # add this
        predictions[i] = forecast(arf, 1)$mean
        training = c(training, test[i])
    }
    return(predictions)
}

out <- anotherBrokenFunction(train, test)
str(out)
# An ‘xts’ object on 2015-09-02/2016-08-31 containing:
#   Data: num [1:252, 1] -0.000312 -0.000534 0.001913 0.000513 -0.000467 ...
#  - attr(*, "dimnames")=List of 2
#   ..$ : NULL
#   ..$ : chr "IBM.Close"
#   Indexed by objects of class: [Date] TZ: UTC
#   xts Attributes:  
# List of 2
#  $ src    : chr "yahoo"
#  $ updated: POSIXct[1:1], format: "2016-09-15 09:56:46"

详情:forecast.fracdiff调用getResponsefracdiff方法getResponse如下:

getAnywhere("getResponse.fracdiff")
# A single object matching ‘getResponse.fracdiff’ was found
# It was found in the following places
#   registered S3 method for getResponse from namespace forecast
#   namespace:forecast
# with value

# function (object, ...) 
# {
#     if (is.element("x", names(object))) 
#         x <- object$x
#     else x <- eval.parent(parse(text = as.character(object$call)[2]))
#     if (is.null(tsp(x))) 
#         x <- ts(x, frequency = 1, start = 1)
#     return(x)
# }
# <bytecode: 0x7fd64bd8b698>
# <environment: namespace:forecast>

所以它首先在对象中寻找一个名为“x”的元素fracdiff,如果失败,它将寻找as.character(object$call)[2](在这种情况下恰好是training),这会产生错误。这个想法是training作为元素插入xfracdiff对象中来抢占这个错误。

于 2016-09-15T01:59:19.983 回答