2
votes

I have a code which predict the change in the sign of future returns.

library(quantmod)
library(PerformanceAnalytics)
library(forecast)
library(e1071)
library(caret)
library(kernlab)
library(dplyr)
library(roll)
# get data yahoo finance
getSymbols("^GSPC", from = "1990-01-01", to = "2017-12-01") 
# take logreturns
rnull <- CalculateReturns(prices = GSPC$GSPC.Adjusted ,method ="log")
# lags 1, 2, 3, 4, 5 as features
feat <- merge(na.trim(lag(rnull,1)),na.trim(lag(rnull,2)),na.trim(lag(rnull,3)),na.trim(lag(rnull,4)),na.trim(lag(rnull,5)),all=FALSE)
# create dataset. 6th column is actural. Previous is lagged
dataset <- merge(feat,rnull,all=FALSE)
# set columns' names
colnames(dataset) = c("lag.1", "lag.2", "lag.3","lag.4","lag.5","TARGET")
# get signs and make a data.frame
x <- sign(dataset)%>%as.data.frame
# exclude 0 sign and assume that these values are positive
x[x==0] <- 1
# for svm purposes we need to set dependent variable as factor and make levels to interpretation
x$TARGET <- as.factor(as.character(x$TARGET))
levels(x$TARGET) <- list(positive = "1", negative = "-1")
# divide sample to training and test subsamples
trainindex <- x[1:5792,]
testindex <- x[5792:7030,]
# run svm
svmFit <- ksvm(TARGET~.,data=trainindex,type="C-svc",kernel= "rbfdot")
# prediction
predsvm <- predict(svmFit, newdata=testindex)
# results
confusionMatrix(predsvm, testindex$TARGET)

The next thing I am going to do is add a rolling window (1 step forecast) to my model. However the basic methods as rollapply does not work with dataframe. Commom methods of one step forecast for time-series are also not valid for data.frame used in e1071 package. I wrote the following function:

svm_next_day_prediction <- function(x){
      svmFit <- svm(TARGET~., data=x)
      prediction <- predict(object = svmFit, newdata = tail(x,1) )
      return(prediction) 
    }  


    apl = rollapplyr(data = x, width = 180, FUN = svm_next_day_prediction, by.column = TRUE)

but recieved a error because rollapply does not understand data.frames:

Error in terms.formula(formula, data = data) : '.' in formula and no 'data' argument

Can you please explain how to apply rolling window for svm classification model with dataframe?

2

2 Answers

0
votes

A few points

  • rollapply works with data frames that can be coerced to a matrix so be sure that your input is entirely numeric -- not a mix of numeric and factor. For example, this works using the built-in data frame BOD which has two numeric columns. Note that x passed to pred is a matrix here.

    pred <- function(x) predict(svm(demand ~ Time, x))
    rollapplyr(BOD, 3, FUN = pred, by.column = FALSE)
    

    giving

    ##              1        2        3
    ## [1,]  8.868888 10.86889 17.25474
    ## [2,] 11.661666 17.24870 16.00000
    ## [3,] 18.328435 16.18583 15.78583
    ## [4,] 16.230474 15.83247 19.56886
    
  • I can't reproduce the error you get. I get a different error.

  • the code in the question has by.column = TRUE (which is the default anyways) but that has the result of passing only a single vector to the function which is not what you want. You want by.column = FALSE.

Try this:

x0 <- data.matrix(x)
rollapplyr(data = x0, width = 180, FUN = svm_next_day_prediction, by.column = FALSE)
0
votes

you can create a list with the individual data frames and then apply your function. I rename x to df to avoid confusion:

df=x
rowwindow=179
dfList=lapply(1:(nrow(df)-rowwindow),function(x) df[x:(rowwindow+x),])
result=sapply(dfList,svm_next_day_prediction)