首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >时间序列.数据分割和模型评估

时间序列.数据分割和模型评估
EN

Stack Overflow用户
提问于 2014-07-15 12:27:32
回答 3查看 32.3K关注 0票数 20

我试着用机器学习来做基于时间序列数据的预测。在堆栈溢出问题(R中CARET包中的createTimeSlices函数)中,有一个使用createTimeSlices进行模型培训和参数优化的交叉验证示例:

代码语言:javascript
复制
    library(caret)
    library(ggplot2)
    library(pls)
    data(economics)
    myTimeControl <- trainControl(method = "timeslice",
                                  initialWindow = 36,
                                  horizon = 12,
                                  fixedWindow = TRUE)

    plsFitTime <- train(unemploy ~ pce + pop + psavert,
                        data = economics,
                        method = "pls",
                        preProc = c("center", "scale"),
                        trControl = myTimeControl)

我的理解是:

  1. 我需要分割可能的数据到培训和测试集。
  2. 使用参数调整的培训集。
  3. 在测试集上评估得到的模型(使用R2、RMSE等)

因为我的数据是时间序列的,我想我不能使用引导来将数据分割成训练和测试集。所以,我的问题是:我是对的吗?如果是这样的话-如何使用createTimeSlices进行模型评估?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-08-02 06:58:28

请注意,您发布的原始问题处理了timeSlicing,您不必手工创建timeSlices。

但是,这里是如何使用createTimeSlices来分割数据,然后使用它来训练和测试模型。

步骤0:设置数据和trainControl:(来自您的问题)

代码语言:javascript
复制
library(caret)
library(ggplot2)
library(pls)

data(economics)

步骤1:为数据索引创建timeSlices:

代码语言:javascript
复制
timeSlices <- createTimeSlices(1:nrow(economics), 
                   initialWindow = 36, horizon = 12, fixedWindow = TRUE)

这将创建一个培训和测试timeSlices的列表。

代码语言:javascript
复制
> str(timeSlices,max.level = 1)
## List of 2
## $ train:List of 431
##   .. [list output truncated]
## $ test :List of 431
##   .. [list output truncated]

为了便于理解,我将它们保存在单独的变量中:

代码语言:javascript
复制
trainSlices <- timeSlices[[1]]
testSlices <- timeSlices[[2]]

第2步:关于第一个trainSlices的培训

代码语言:javascript
复制
plsFitTime <- train(unemploy ~ pce + pop + psavert,
                    data = economics[trainSlices[[1]],],
                    method = "pls",
                    preProc = c("center", "scale"))

步骤3:在第一个testSlices上进行测试

代码语言:javascript
复制
pred <- predict(plsFitTime,economics[testSlices[[1]],])

第4步:策划:

代码语言:javascript
复制
true <- economics$unemploy[testSlices[[1]]]

plot(true, col = "red", ylab = "true (red) , pred (blue)", ylim = range(c(pred,true)))
points(pred, col = "blue") 

然后,您可以对所有切片执行以下操作:

代码语言:javascript
复制
for(i in 1:length(trainSlices)){
  plsFitTime <- train(unemploy ~ pce + pop + psavert,
                      data = economics[trainSlices[[i]],],
                      method = "pls",
                      preProc = c("center", "scale"))
  pred <- predict(plsFitTime,economics[testSlices[[i]],])
  
  
  true <- economics$unemploy[testSlices[[i]]]
  plot(true, col = "red", ylab = "true (red) , pred (blue)", 
            main = i, ylim = range(c(pred,true)))
  points(pred, col = "blue") 
}

如前所述,这种timeSlicing是由原始函数在一个步骤中完成的:

代码语言:javascript
复制
> myTimeControl <- trainControl(method = "timeslice",
+                               initialWindow = 36,
+                               horizon = 12,
+                               fixedWindow = TRUE)
> 
> plsFitTime <- train(unemploy ~ pce + pop + psavert,
+                     data = economics,
+                     method = "pls",
+                     preProc = c("center", "scale"),
+                     trControl = myTimeControl)
> plsFitTime
Partial Least Squares 

478 samples
  5 predictors

Pre-processing: centered, scaled 
Resampling: Rolling Forecasting Origin Resampling (12 held-out with a fixed window) 

Summary of sample sizes: 36, 36, 36, 36, 36, 36, ... 

Resampling results across tuning parameters:

  ncomp  RMSE  Rsquared  RMSE SD  Rsquared SD
  1      1080  0.443     796      0.297      
  2      1090  0.43      845      0.295      

RMSE was used to select the optimal model using  the smallest value.
The final value used for the model was ncomp = 1. 

希望这能帮上忙!

票数 43
EN

Stack Overflow用户

发布于 2015-02-20 06:58:42

Shambho的回答提供了一个很好的例子,说明如何在TimeSlices中使用插入符号包,但是,它在建模技术方面可能会产生误导。因此,为了避免误导未来的读者,他们希望使用插入符号包对时间序列进行预测建模(这里我并不是指自回归模型),我想强调几点。

时间序列数据的问题是,如果不小心的话,前瞻性的偏见是容易的。在这种情况下,经济数据集在其经济报告日期而不是发布日期对齐数据,而在实际应用中则从未如此(经济数据点有不同的时间戳)。就发布日期而言,失业数据可能落后于其他指标两个月,这将在Shambho的例子中引入一个模型偏差。

接下来,这个示例只是描述性统计,而不是预测(预测),因为我们想要预测(未使用)的数据没有被正确地延迟。它只是训练了一个模型来最好地解释失业的变化(在这种情况下,这也是一个固定的时间序列,在建模过程中产生了各种各样的问题),基于预测变量在同一经济报告日期。

最后,这个例子中的12个月的时间范围并不像Hyndman在他的例子中所做的那样是一个真正的多周期预测。

关于时间序列交叉验证的Hyndman

票数 5
EN

Stack Overflow用户

发布于 2014-07-31 19:09:52

事实上,你可以!

首先,让我给你关于这一主题的学术文章

在R:

使用包caretcreateResample可以用于制作简单的引导示例,createFolds可以用于从一组数据生成平衡的交叉验证分组。因此,您可能希望使用createResample。下面是它的用法的一个例子:

代码语言:javascript
复制
data(oil)
createDataPartition(oilType, 2)

x <- rgamma(50, 3, .5)
inA <- createDataPartition(x, list = FALSE)

plot(density(x[inA]))
rug(x[inA])

points(density(x[-inA]), type = "l", col = 4)
rug(x[-inA], col = 4)

createResample(oilType, 2)

createFolds(oilType, 10)
createFolds(oilType, 5, FALSE)

createFolds(rnorm(21))

createTimeSlices(1:9, 5, 1, fixedWindow = FALSE)
createTimeSlices(1:9, 5, 1, fixedWindow = TRUE)
createTimeSlices(1:9, 5, 3, fixedWindow = TRUE)
createTimeSlices(1:9, 5, 3, fixedWindow = FALSE)

createResample函数中看到的值是要创建的数据和分区数,在本例中是2。您还可以指定结果是否应该存储为带有list = TRUElist = FALSE的列表。

此外,caret包含一个名为createTimeSlices的函数,它可以为这种类型的拆分创建索引。

这类分裂的三个参数是:

  • initialWindow:每个训练集样本中连续值的初始值
  • horizon:测试集示例中的连续值数
  • fixedWindow:一个逻辑:如果错误,训练集总是从第一个样本开始,并且训练集的大小会随着数据的分割而变化。

用法:

代码语言:javascript
复制
createDataPartition(y, 
                    times = 1,
                    p = 0.5,
                    list = TRUE,
                    groups = min(5, length(y)))
createResample(y, times = 10, list = TRUE)
createFolds(y, k = 10, list = TRUE, returnTrain = FALSE)
createMultiFolds(y, k = 10, times = 5)
createTimeSlices(y, initialWindow, horizon = 1, fixedWindow = TRUE)

资料来源:

http://caret.r-forge.r-project.org/splitting.html

http://eranraviv.com/blog/bootstrapping-time-series-r-code/

抄送

卡雷特。数据分割与trainControl的关系

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24758218

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档