R 中时间序列数据的机器学习
介绍
时间序列算法广泛用于分析和预测基于时间的数据。然而,考虑到除时间之外的其他因素的复杂性,机器学习已成为一种强大的方法,可用于理解时间序列数据中隐藏的复杂性并生成良好的预测。
在本指南中,您将从时间序列角度学习特征工程和机器学习的概念以及在 R 中实现它的技术。
数据
首先,您需要了解数据。在本指南中,您将使用超市的虚构每日销售数据,其中包含 3,533 个观测值和四个变量,如下所述:
日期: 每日销售日期
销售额:超市当天的销售额,以千美元计
库存:超市库存总单位数
Class:用于建模的训练和测试数据类
首先加载所需的库和数据。
library(plyr)
library(readr)
library(dplyr)
library(caret)
library(ggplot2)
library(repr)
library(data.table)
library(TTR)
library(forecast)
library(lubridate)
dat <- read_csv("data.csv")
glimpse(dat)
输出:
Observations: 3,533
Variables: 4
$ Date <chr> "29-04-2010", "30-04-2010", "01-05-2010", "02-05-2010", "03-...
$ Sales <int> 51, 56, 93, 86, 57, 45, 50, 52, 61, 73, 115, 67, 37, 60, 48,...
$ Inventory <int> 711, 552, 923, 648, 714, 758, 573, 404, 487, 977, 1047, 508,...
$ class <chr> "Train", "Train", "Train", "Train", "Train", "Train", "Train...
输出显示日期是字符格式,需要将其更改为日期格式。此外,类变量应更改为因子。这可以通过以下代码行完成。
dat$Date = as.Date(dat$Date,format = '%d-%m-%Y')
dat$class = as.factor(dat$class)
glimpse(dat)
输出:
Observations: 3,533
Variables: 4
$ Date <date> 2010-04-29, 2010-04-30, 2010-05-01, 2010-05-02, 2010-05-03,...
$ Sales <int> 51, 56, 93, 86, 57, 45, 50, 52, 61, 73, 115, 67, 37, 60, 48,...
$ Inventory <int> 711, 552, 923, 648, 714, 758, 573, 404, 487, 977, 1047, 508,...
$ class <fct> Train, Train, Train, Train, Train, Train, Train, Train, Trai...
上述输出表明已做出所需的更改。
日期特征
有时,经典的时间序列算法不足以做出有力的预测。在这种情况下,通过从时间变量创建特征将时间序列数据转换为机器学习数据是明智的。在下面的代码中,您将使用 lubridate ()包来创建时间特征,如年份、一年中的某一天、季度、月份、天、工作日等。
dat$year = lubridate::year(dat$Date)
dat$yday = yday(dat$Date)
dat$quarter = quarter(dat$Date)
dat$month = lubridate::month(dat$Date)
dat$day = lubridate::day(dat$Date)
dat$weekdays = weekdays(dat$Date)
glimpse(dat)
输出:
Observations: 3,533
Variables: 10
$ Date <date> 2010-04-29, 2010-04-30, 2010-05-01, 2010-05-02, 2010-05-03,...
$ Sales <int> 51, 56, 93, 86, 57, 45, 50, 52, 61, 73, 115, 67, 37, 60, 48,...
$ Inventory <int> 711, 552, 923, 648, 714, 758, 573, 404, 487, 977, 1047, 508,...
$ class <fct> Train, Train, Train, Train, Train, Train, Train, Train, Trai...
$ year <dbl> 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, ...
$ yday <dbl> 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, ...
$ quarter <int> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ...
$ month <dbl> 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, ...
$ day <int> 29, 30, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1...
$ weekdays <chr> "Thursday", "Friday", "Saturday", "Sunday", "Monday", "Tuesd...
创建时间特征后,将它们转换为所需的数据类型。您还将创建周末变量,因为假设周末的销售额会更高。
dat = as.data.table(dat)
dat$month = as.factor(dat$month)
dat$weekdays = factor(dat$weekdays,levels = c("Monday", "Tuesday", "Wednesday","Thursday","Friday","Saturday",'Sunday'))
dat[weekdays %in% c("Saturday",'Sunday'),weekend:=1]
dat[!(weekdays %in% c("Saturday",'Sunday')),weekend:=0]
dat$weekend = as.factor(dat$weekend)
dat$year = as.factor(dat$year)
dat$quarter = as.factor(dat$quarter)
dat$week = format(dat$Date, "%V")
dat = as.data.frame(dat)
dat$week = as.integer(dat$week)
glimpse(dat)
输出:
Observations: 3,533
Variables: 12
$ Date <date> 2010-04-29, 2010-04-30, 2010-05-01, 2010-05-02, 2010-05-03,...
$ Sales <int> 51, 56, 93, 86, 57, 45, 50, 52, 61, 73, 115, 67, 37, 60, 48,...
$ Inventory <int> 711, 552, 923, 648, 714, 758, 573, 404, 487, 977, 1047, 508,...
$ class <fct> Train, Train, Train, Train, Train, Train, Train, Train, Trai...
$ year <fct> 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, ...
$ yday <dbl> 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, ...
$ quarter <fct> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ...
$ month <fct> 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, ...
$ day <int> 29, 30, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1...
$ weekdays <fct> Thursday, Friday, Saturday, Sunday, Monday, Tuesday, Wednesd...
$ weekend <fct> 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, ...
$ week <int> 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, ...
数据分区
数据现在已经准备好了。接下来,在训练集上构建模型,并在测试集上评估其性能。这称为用于评估模型性能的保留验证方法。
下面的第一行代码设置了随机种子,以确保结果的可重复性。接下来的两行代码创建了训练集和测试集,而最后两行则打印了训练集和测试集的尺寸。
set.seed(100)
train = dat[dat$class == 'Train',]
test = dat[dat$class == 'Test',]
dim(train)
dim(test)
输出:
1] 3450 12
[1] 83 12
模型评估指标
创建训练和测试集后,构建机器学习模型。在此之前,确定评估指标很重要。要使用的评估指标是平均绝对百分比误差(或 MAPE) 。 MAPE值越低,预测模型越好。下面的代码创建了一个用于计算 MAPE 的效用函数,它将用于评估模型的性能。
mape <- function(actual,pred){
mape <- mean(abs((actual - pred)/actual))*100
return (mape)
}
随机森林
随机森林是一种用于分类、回归和其他机器学习任务的集成机器学习算法。该算法通过在训练过程中构建大量决策树并根据多数投票或平均预测生成结果来运行。它是袋装决策树的扩展,其中构建树的目的是减少各个决策树之间的相关性。
下面的第一行代码设置了可重复性的种子。第二行使用所有变量在训练数据集上构建随机森林模型。第三行打印模型摘要。
set.seed(100)
library(randomForest)
rf = randomForest(Sales ~ Inventory + year + yday + quarter + month + day + weekdays + weekend + week, data = train)
print(rf)
输出:
Call:
randomForest(formula = Sales ~ Inventory + year + yday + quarter + month + day + weekdays + weekend + week, data = train)
Type of random forest: regression
Number of trees: 500
No. of variables tried at each split: 3
Mean of squared residuals: 198.8628
% Var explained: 62.19
上面的输出显示了模型的重要组成部分。现在您将评估模型在训练集和测试集上的性能。下面的前两行代码评估模型在训练集上的性能,而后两行代码则评估测试数据的性能。
predictions = predict(rf, newdata = train)
mape(train$Sales, predictions)
predictions = predict(rf, newdata = test)
mape(test$Sales, predictions)
输出:
1] 10.36581
[1] 21.28251
上面的输出显示,训练数据的 MAPE 为 10.3%,而测试数据的 MAPE 上升到 21.2%。这是模型过度拟合训练数据且在测试数据上泛化不佳的典型案例。此类模型不够稳健,因此您需要构建一个修订的随机森林模型。一种实现此目的的方法是仅使用重要变量来构建算法。为此,您将使用如下所示的varImpPlot()函数。
varImpPlot(rf)
输出:
从上面的输出可以看出,最重要的变量是weekend、weekdays、Inventory、year和yday。下一步是仅使用这些变量构建修订后的随机森林模型。这是通过下面的代码完成的。
set.seed(100)
rf_revised = randomForest(Sales ~ Inventory + year + yday + weekdays + weekend, data = train)
print(rf_revised)
输出:
Call:
randomForest(formula = Sales ~ Inventory + year + yday + weekdays + weekend, data = train)
Type of random forest: regression
Number of trees: 500
No. of variables tried at each split: 1
Mean of squared residuals: 190.5796
% Var explained: 63.77
下一步是使用下面的代码评估训练和测试数据上的模型性能。
predictions = predict(rf_revised, newdata = train)
mape(train$Sales, predictions)
predictions = predict(rf_revised, newdata = test)
mape(test$Sales, predictions)
输出:
1] 20.06139
[1] 20.14089
上面的输出显示,训练和测试数据的 MAPE 为 20%。训练和测试数据集上的结果相似性是表明该模型稳健且泛化能力良好的指标之一。与早期模型相比,MAPE 也略有下降,这表明修订后的模型表现更好。
结论
在本指南中,您学习了如何对时间序列数据进行机器学习。您学习了如何从日期变量创建特征并将其用作模型构建的独立特征。您还了解了强大的算法随机森林,该算法用于构建和评估机器学习模型。最后,您学习了如何使用随机森林选择重要变量。
要了解有关使用 R 进行数据科学的更多信息,请参阅以下指南:
<a href="https://www-pluralsight-com.translate.goog/resources/blog/guides/hypothes
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~