这是一个简单的问题,可以在时间序列数据上使用随机森林模型吗?我问这个是因为,在随机森林模型中,我们执行自举观察,我们从训练集中随机抽样并替换。这不会破坏模型中的“观察顺序”,因为它是时间序列数据。我是在金融数据的背景下问这个问题的,比如说我正在做一个分类类型的问题来购买/不购买资产,并且我收集了一些功能的日常数据来预测这个变量。
对时间序列数据使用随机森林
机器算法验证
时间序列
随机森林
2022-02-08 11:55:54
2个回答
它工作得很好,但前提是功能准备得当,这样行的顺序就不再重要了。
例如对于单变量时间序列,你会使用作为响应,例如以下功能:
滞后版本,,等等
适当顺序的差异,例如 ,(如果预计每周有季节性并且每天都会进行观察)等。
整数或虚拟编码的周期性时间信息,例如一年中的月份、星期几、一天中的小时、小时中的分钟等。
相同的方法适用于不同的建模技术,包括线性回归、神经网络、增强树等。
下面是一个示例(使用二进制目标“温度升高”(y/n)):
library(tidyverse)
library(lubridate)
library(ranger)
library(MetricsWeighted) # AUC
# Import
raw <- read.csv("https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-min-temperatures.csv")
# Explore
str(raw)
head(raw)
summary(raw)
hist(raw$Temp, breaks = "FD")
# Prepare and add binary response
prep <- raw %>%
mutate(Date = ymd(Date),
y = year(Date),
m = month(Date),
d = day(Date),
increase = 0 + (Temp > lag(Temp)))
with(prep, table(y))
summary(prep)
# Plot full data -> year as seasonality
ggplot(data = prep, aes(x = Date, y = Temp))+
geom_line(color = "#00AFBB", size = 2) +
scale_x_date()
# No visible within year seasonality
prep %>%
filter(y == 1987) %>%
ggplot(aes(x = Date, y = Temp))+
geom_line(color = "#00AFBB", size = 2) +
scale_x_date()
# Add some lags and diffs & remove incomplete rows
prep <- prep %>%
mutate(lag1 = lag(Temp),
lag2 = lag(Temp, 2L),
lag3 = lag(Temp, 3L),
dif1 = lag1 - lag2,
dif2 = lag2 - lag3) %>%
filter(complete.cases(.))
# Train/valid split in blocks
valid <- prep %>%
filter(y == 1990)
train <- prep %>%
filter(y < 1990)
# Models
y <- "increase" # response
x <- c("lag1", "lag2", "lag3", "dif1", "dif2", "y", "m", "d") # covariables
form <- reformulate(x, y)
# Logistic model: Linear dependence between difs and lags
fit_glm <- glm(form,
data = train,
family = binomial())
summary(fit_glm)
# Random forest
fit_rf <- ranger(form,
data = train,
seed = 345345,
importance = "impurity",
probability = TRUE)
fit_rf
barplot(-sort(-importance(fit_rf))) # Variable importance
# Evaluate on 1990 for glm by looking at ROC AUC
pred_glm <- predict(fit_glm, valid, type = "response")
AUC(valid[[y]], pred_glm) # 0.684 ROC AUC
# Then for rf
pred_rf <- predict(fit_rf, valid)$predictions[, 2]
AUC(valid[[y]], pred_rf) # 0.702 ROC AUC
# view OOB residuals of rf within one month to see if structure is left over
random_month <- train %>%
mutate(residuals = increase - fit_rf$predictions[, 2]) %>%
filter(y == 1987, m == 3)
ggplot(random_month, aes(x = Date, y = residuals))+
geom_line(color = "#00AFBB", size = 2) +
scale_x_date()
用因子替换变量“y”和“m”可能会改善逻辑回归。但由于问题是关于随机森林的,我把这个留给读者。
由于各种原因,随机森林不会在时间序列数据上表现良好。然而,在我看来,最大的陷阱与引导无关,也不是随机森林所独有的:
- 时间序列在观察之间具有相互依赖性,模型将忽略这一点。
- 底层学习器通常是基于树的算法,它不会推断趋势。如果数据中有真正的时间趋势,则不会向前预测。