用支持向量机预测月销售数据的两种方法

5
我有一个关于时间序列和SVM的问题。我已经向强大的互联网提问,但不幸的是信息很少,大部分与交易数据有关。
我的情况如下: 目前我正在尝试从Arima预测转换为更复杂的模型。目前我正在尝试理解和实施SVM模型。我找到了一些关于美国市场上亚洲汽车月销售量的数据。现在我正在使用这些数据进行实验。
首先,我用两种不同的例程使用SVR / SVM进行时间序列预测。 接下来,我在相同的数据上实现了一个绝对简单的auto.arima。 最后,我比较这3种方法的残差。
我的问题是: 我这样实现是朝着正确的方向前进吗? 我如何改进SVM模型? 除了金融数据之外,是否还有更多关于预测的信息?
让我们从一个小的解决方法开始构建我的输入矩阵(来自goodcarbadcar.net的数据):
library(zoo)
library(e1071)
library(quantmod)
library(kernlab)
library(caret)
library(forecast)

Date <-c( "2010-01-01", "2010-02-01", "2010-03-01", "2010-04-01", "2010-05-01", "2010-06-01", "2010-07-01", "2010-08-01", "2010-09-01",
    "2010-10-01", "2010-11-01", "2010-12-01", "2011-01-01", "2011-02-01", "2011-03-01", "2011-04-01", "2011-05-01", "2011-06-01",
    "2011-07-01", "2011-08-01", "2011-09-01", "2011-10-01", "2011-11-01", "2011-12-01", "2012-01-01", "2012-02-01", "2012-03-01",
    "2012-04-01", "2012-05-01", "2012-06-01", "2012-07-01", "2012-08-01", "2012-09-01", "2012-10-01", "2012-11-01", "2012-12-01",
    "2013-01-01", "2013-02-01", "2013-03-01", "2013-04-01", "2013-05-01", "2013-06-01", "2013-07-01", "2013-08-01", "2013-09-01",
    "2013-10-01", "2013-11-01", "2013-12-01", "2014-01-01", "2014-02-01", "2014-03-01", "2014-04-01", "2014-05-01", "2014-06-01",
    "2014-07-01", "2014-08-01", "2014-09-01", "2014-10-01", "2014-11-01", "2014-12-01", "2015-01-01", "2015-02-01", "2015-03-01",
    "2015-04-01", "2015-05-01", "2015-06-01", "2015-07-01", "2015-08-01", "2015-09-01", "2015-10-01", "2015-11-01", "2015-12-01",
    "2016-01-01", "2016-02-01", "2016-03-01")

Nissan <- c( 55861, 63148, 85526, 56558, 75673, 56266, 72573, 67399, 65900, 61843, 63184, 81228, 64442, 83226, 109854, 64765, 69759,
            65659, 77191, 82517, 84485, 75484, 76754, 89937, 72517, 97492, 126132, 64200, 81202, 81801, 86722, 87360, 82462, 70928,
            84300, 86663, 73793, 90489, 126623, 80003, 106558, 95010, 101279, 108614, 77828, 81866, 93376, 96526, 81472, 105631, 136642,
            94764, 125558, 101069, 112914, 125224, 95118, 94072, 91790, 105311, 94449, 106777, 132560, 99869, 124305, 114243, 120439,
            122716, 111562, 104904, 95389, 124207, 97220, 120540, 149784,)

Mitsubishi <- c( 4170, 4019, 5434, 3932, 4737, 4198, 5648, 4293, 4961, 5111, 4306, 4874, 5714, 6893, 7560, 8081, 7568, 8299, 7972,
                7985, 5803, 4378, 3735, 5032, 4711, 4736, 7160, 5280, 5575, 5411, 4194, 4249, 4806, 3981, 3574, 4113, 4659, 6051,
                5286, 4461, 4715, 5297, 5230, 5281, 4001, 4752, 6071, 6423, 4867, 5977, 8996, 6542, 7269, 6021, 6349, 6786, 5558,
                6199, 6534, 6545, 1112, 1184, 1715, 1933, 1996, 1982, 2052, 2320, 2066, 1984, 1637, 1403, 1288, 1547, 2123)

mydata <- data.frame(Date, Nissan, Mitsubishi)
mydata$Date <- as.Date(mydata$Date, format = "%Y-%m-%d")
mydata <- xts(mydata[,-1], order.by = mydata[,1])

因此,我有与.csv导入相同的输入。 下一步是定义一个数据框作为进一步分析的基础。
假设Nissan在时间 t 的销售依赖于时间 t-1 , t-2 和 t-3 的销售。此外,假设Nissan在时间 t 的销售也依赖于Mitsubishi在 t-3 的销售。
现在我们来讨论第一种方法。这里使用时间切片。
####################
#Use SVR  technique#
####################

Nissan <- data$Nissan
Mitsubishi <- data$Mitsubishi

#Assume dependency on Nissan Lag1 + Lag2 and Mitsubishi Lag1
feature = merge(lag(Nissan,1),lag(Nissan,2), lag(Nissan,3),
             lag(Mitsubishi,3),
             all=FALSE)

colnames(feature) = c("n.lag.1", "n.lag.2", "n.lag.3",
                      "m.lag.3")

#TARGET to predict: Nissan
dataset = na.trim(merge(feature,Nissan,all=FALSE))

#Label columns of dataset
colnames(dataset) = c("n.lag.1", "n.lag.2", "n.lag.3",
                      "m.lag.3",
                      "TARGET")

#################
#Use Time Slices#
#################

myTimeControl <- trainControl(method = "timeslice",
                              initialWindow = 48,
                              horizon = 6,
                              fixedWindow = TRUE)

TimeModel <- train(TARGET ~ .,
                     data = dataset,
                     method = "pls",
                     preProc = c("center", "scale"),
                     trControl = myTimeControl)
TimeModel

####################################
#Predict with control data set 2016#
####################################

#Define the test set
control.feature <- merge(lag(mydata$Nissan["2010/2016"],1), lag(mydata$Nissan["2010/2016"],2), lag(mydata$Nissan["2010/2016"],3),
                         lag(mydata$Mitsubishi["2010/2016"],3),
                         all = FALSE)

colnames(control.feature) = c("n.lag.1", "n.lag.2", "n.lag.3",
                      "m.lag.3")

#Make a prediction
svr.fc <- predict(TimeModel, control.feature["2016"])

#Show SVR Residuals

现在我想展示我的第二种方法,依赖于e1071包

####################
#Use  Package e1071#
####################

#initialize svm model
nissan.model <- svm(TARGET ~ ., dataset)

#test model on the existing set
nissanY <- predict(nissan.model, dataset)
plot(index(dataset),dataset[,ncol(dataset)], pch=16)
points(index(dataset),nissanY, col="red", pch=4)

#predict 2016 values and compare with actuals
predictY <- predict(nissan.model, control.feature["2016"])
mydata$Nissan["2016"] - predictY

#tune the existing model with grid search
nissan.tuneResult <- tune(svm, TARGET ~ ., data = dataset,
                     ranges = list(epsilon = seq(0,1, 0.01), cost=2^(2:9)))
print(nissan.tuneResult)
plot(nissan.tuneResult)

#initialize tuned model
tuned.nissan.model <- nissan.tuneResult$best.model
tuned.nissanY <- predict(tuned.nissan.model, dataset)

plot(index(dataset),dataset[,ncol(dataset)], pch=16)
points(index(dataset),tuned.nissanY, col="red", pch=4)

#compare 2016 forecast and actual values
tuned.predictY <- predict(tuned.nissan.model, control.feature["2016"])

最后,我呈现我的基础自动ARIMA模型。
############################
#Use time series techniques#
############################

#Define time series which should be forecasted
nissan.ts <- ts(data$Nissan, frequency = 12, start = c(2010,1))

#Assume that Nissan depends on Mitsubishi
xreg <- data.frame(data$Mitsubishi)

#auto.arima on Nissan with XREG = Mitsubishi
arima.fit <- auto.arima(nissan.ts, D = 1, xreg = xreg)
arima.fc <- forecast(arima.fit, xreg = xreg)

#How did the ARIMA forecast perform in the first quarter of 2016
comparison.arima <- actual$Nissan - arima.fc$mean[1:3]
rmse.arima <- sqrt(sum((actual$Nissan - arima.fc$mean[1:3])^2/3))

最后,对这三种方法的残差进行比较。
#Print the details ARIMA
comparison.arima
#Print details e1071
mydata$Nissan["2016"] - tuned.predictY
#Print details Time Slices
mydata$Nissan["2016"] - svr.fc

我的结论如下:
  1. auto.arima使用(2,1,0)模型。SVM模型中有3个滞后项。因此,存在差异。
  2. auto.arima不使用lag(mitsubishi,3),而只是使用xreg(mitsubishi)
  3. 两个SVM模型都只使用一些假设,没有进一步的说明
  4. 最终,数据量对SVM来说还不够高
如果您能就我的问题给我一些提示,甚至更深入地讨论这些模型,我将不胜感激。最好的问候,
Alex

这里有很多文字。是否有一个问题,具体来说是一个编程问题? - cory
“e1071和kernlab这两个库被正确地使用了吗?” 这将是“唯一”的问题。 - Alex
2个回答

1
Alex,你为什么假设三菱对Y有影响?当你强制将不相关的数据放在一起时,会发生不好的事情。我用一个归一化散点图绘制了Y和X,其中X向下移动了3个周期(即失去了前3个观测值)。这看起来不相关,这可能是你问题的一部分。

enter image description here

三菱的数据在第61个时期有了显著下降,而日产则没有受到影响。这证明二者之间不存在关联。你可能想先尝试许多真正好的因果关系例子(如Lydia Pinkham或Box-Jenkins的气体炉与甲烷)。

0

我不太清楚你选择训练SVM的时间跨度。我原本期望训练测试应该结束于2015年12月,这样你就可以使用剩余的3个月来测试模型。然而,似乎TimeModel是在整个时间跨度上进行估计的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接