使用 Python 中的时间序列数据进行机器学习
介绍
时间序列算法广泛用于分析和预测基于时间的数据。然而,考虑到时间之外其他因素的复杂性,机器学习已成为一种强大的方法,可用于理解时间序列数据中隐藏的复杂性并生成良好的预测。
在本指南中,您将从时间序列的角度学习特征工程和机器学习的概念,以及在 Python 中实现它们的技术。
数据
首先,熟悉数据。在本指南中,您将使用超市每日销售数据的虚构数据集,其中包含 3,533 个观测值和 4 个变量,如下所述:
日期: 每日销售日期
销售额:超市当天的销售额,以千美元计
库存:超市库存总单位数
Class:用于建模的训练和测试数据类
首先加载所需的库和数据。
import pandas as pd
import numpy as np
# Reading the data
df = pd.read_csv("ml_python.csv")
print(df.shape)
print(df.info())
df.head(5)
输出:
(3533, 4)
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3533 entries, 0 to 3532
Data columns (total 4 columns):
Date 3533 non-null object
Sales 3533 non-null int64
Inventory 3533 non-null int64
Class 3533 non-null object
dtypes: int64(2), object(2)
memory usage: 110.5+ KB
None
Date Sales Inventory Class
0 29-04-2010 51 40 Train
1 30-04-2010 56 44 Train
2 01-05-2010 93 74 Train
3 02-05-2010 86 68 Train
4 03-05-2010 57 45 Train
日期特征
有时,经典的时间序列算法不足以做出有力的预测。在这种情况下,通过从时间变量创建特征将时间序列数据转换为机器学习算法是明智的。下面的代码使用 pd.DatetimeIndex ()函数创建时间特征,如年份、一年中的某一天、季度、月份、星期几、工作日等。
import datetime
df['Date'] = pd.to_datetime(df['Date'])
df['Date'] = df['Date'].dt.strftime('%d.%m.%Y')
df['year'] = pd.DatetimeIndex(df['Date']).year
df['month'] = pd.DatetimeIndex(df['Date']).month
df['day'] = pd.DatetimeIndex(df['Date']).day
df['dayofyear'] = pd.DatetimeIndex(df['Date']).dayofyear
df['weekofyear'] = pd.DatetimeIndex(df['Date']).weekofyear
df['weekday'] = pd.DatetimeIndex(df['Date']).weekday
df['quarter'] = pd.DatetimeIndex(df['Date']).quarter
df['is_month_start'] = pd.DatetimeIndex(df['Date']).is_month_start
df['is_month_end'] = pd.DatetimeIndex(df['Date']).is_month_end
print(df.info())
输出:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3533 entries, 0 to 3532
Data columns (total 13 columns):
Date 3533 non-null object
Sales 3533 non-null int64
Inventory 3533 non-null int64
Class 3533 non-null object
year 3533 non-null int64
month 3533 non-null int64
day 3533 non-null int64
dayofyear 3533 non-null int64
weekofyear 3533 non-null int64
weekday 3533 non-null int64
quarter 3533 non-null int64
is_month_start 3533 non-null bool
is_month_end 3533 non-null bool
您现在不需要Date变量,因此可以将其删除。
df = df.drop(['Date'], axis = 1)
虚拟编码
数据集中的某些变量(例如year或quarter)需要被视为分类变量。因此,您将使用一种称为虚拟编码的技术将这些变量转换为可用作因子的数字变量。在这种技术中,对特征进行编码,因此不会重复信息。这是通过将参数drop_first=True传递给.get_dummies()函数来实现的,如下面的代码所示。最后一行打印有关数据的信息,这表明数据现在有 37 个变量。
df = pd.get_dummies(df, columns=['year'], drop_first=True, prefix='year')
df = pd.get_dummies(df, columns=['month'], drop_first=True, prefix='month')
df = pd.get_dummies(df, columns=['weekday'], drop_first=True, prefix='wday')
df = pd.get_dummies(df, columns=['quarter'], drop_first=True, prefix='qrtr')
df = pd.get_dummies(df, columns=['is_month_start'], drop_first=True, prefix='m_start')
df = pd.get_dummies(df, columns=['is_month_end'], drop_first=True, prefix='m_end')
df.info()
输出:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3533 entries, 0 to 3532
Data columns (total 37 columns):
Sales 3533 non-null int64
Inventory 3533 non-null int64
Class 3533 non-null object
day 3533 non-null int64
dayofyear 3533 non-null int64
weekofyear 3533 non-null int64
year_2011 3533 non-null uint8
year_2012 3533 non-null uint8
year_2013 3533 non-null uint8
year_2014 3533 non-null uint8
year_2015 3533 non-null uint8
year_2016 3533 non-null uint8
year_2017 3533 non-null uint8
year_2018 3533 non-null uint8
year_2019 3533 non-null uint8
month_2 3533 non-null uint8
month_3 3533 non-null uint8
month_4 3533 non-null uint8
month_5 3533 non-null uint8
month_6 3533 non-null uint8
month_7 3533 non-null uint8
month_8 3533 non-null uint8
month_9 3533 non-null uint8
month_10 3533 non-null uint8
month_11 3533 non-null uint8
month_12 3533 non-null uint8
wday_1 3533 non-null uint8
wday_2 3533 non-null uint8
wday_3 3533 non-null uint8
wday_4 3533 non-null uint8
wday_5 3533 non-null uint8
wday_6 3533 non-null uint8
qrtr_2 3533 non-null uint8
qrtr_3 3533 non-null uint8
qrtr_4 3533 non-null uint8
m_start_True 3533 non-null uint8
m_end_True 3533 non-null uint8
dtypes: int64(5), object(1), uint8(31)
数据分区
准备好数据后,您就可以在后续章节中转向机器学习了。不过,在转向预测建模技术之前,将数据划分为训练集和测试集非常重要。
train = df[df["Class"] == "Train"]
test = df[df["Class"] == "Test"]
print(train.shape)
print(test.shape)
输出:
(3442, 37)
(91, 37)
您现在不需要Class变量,因此可以使用下面的代码将其删除。
train = train.drop(['Class'], axis = 1)
test = test.drop(['Class'], axis = 1)
为特征和响应变量创建数组
对数据进行分区后,下一步是为特征和响应变量创建数组。第一行代码创建一个名为target_column_train的目标变量对象。第二行给出了所有特征的列表,不包括目标变量Sales。接下来的两行创建训练数据的数组,最后两行打印其形状。
target_column_train = ['Sales']
predictors_train = list(set(list(train.columns))-set(target_column_train))
X_train = train[predictors_train].values
y_train = train[target_column_train].values
print(X_train.shape)
print(y_train.shape)
输出:
(3442, 35)
(3442, 1)
使用下面的代码对测试数据重复相同的过程。
target_column_test = ['Sales']
predictors_test = list(set(list(test.columns))-set(target_column_test))
X_test = test[predictors_test].values
y_test = test[target_column_test].values
print(X_test.shape)
print(y_test.shape)
输出:
(91, 35)
(91, 1)
您现在可以构建机器学习模型了。首先加载库和模块。
from sklearn import model_selection
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error
from math import sqrt
决策树
决策树,也称为分类和回归树 (CART),适用于分类和连续输入和输出变量。它们的工作原理是根据独立变量中最重要的分割器将数据分成两个或多个同质集。最好的区分器是最小化成本指标的那个。分类树的成本指标通常是熵或基尼指数,而对于回归树,默认指标是均方误差。
使用DecisionTreeRegressor类创建 CART 回归模型。第一步是实例化下面第一行代码中完成的算法。第二行在训练集上拟合模型。使用的参数是max_depth(表示树的最大深度)和min_samples_leaf(表示叶节点所需的最小样本数)。
dtree = DecisionTreeRegressor(max_depth=8, min_samples_leaf=0.13, random_state=3)
dtree.fit(X_train, y_train)
输出:
DecisionTreeRegressor(criterion='mse', max_depth=8, max_features=None,
max_leaf_nodes=None, min_impurity_decrease=0.0,
min_impurity_split=None, min_samples_leaf=0.13,
min_samples_split=2, min_weight_fraction_leaf=0.0,
presort=False, random_state=3, splitter='best')
在训练集上建立模型后,您就可以进行预测了。下面的第一行代码在训练集上进行预测。第二行和第三行代码打印了训练集上的评估指标——RMSE 和 R 平方。在第四行到第六行中,对测试数据集重复了相同的步骤。
# Code lines 1 to 3
pred_train_tree= dtree.predict(X_train)
print(np.sqrt(mean_squared_error(y_train,pred_train_tree)))
print(r2_score(y_train, pred_train_tree))
# Code lines 4 to 6
pred_test_tree= dtree.predict(X_test)
print(np.sqrt(mean_squared_error(y_test,pred_test_tree)))
print(r2_score(y_test, pred_test_tree))
输出:
7.42649982627121
0.8952723676224715
13.797384350596744
0.4567663254694022
上面的输出显示,训练数据的 RMSE 为 7.4,测试数据的 RMSE 为 13.8。另一方面,训练数据的 R 平方值为 89%,测试数据的 R 平方值为 46%。训练集和测试集结果之间存在差距,可以通过参数调整来进一步改进。更改参数max_depth的值,看看这对模型性能有何影响。
下面前四行代码分别实例化并拟合了max_depth参数为 2 和 5 的回归树。第五行和第六行代码对训练数据生成预测,而第七行和第八行代码对测试数据进行预测。
# Code Lines 1 to 4: Fit the regression tree 'dtree1' and 'dtree2'
dtree1 = DecisionTreeRegressor(max_depth=2)
dtree2 = DecisionTreeRegressor(max_depth=5)
dtree1.fit(X_train, y_train)
dtree2.fit(X_train, y_train)
# Code Lines 5 to 6: Predict on training data
tr1 = dtree1.predict(X_train)
tr2 = dtree2.predict(X_train)
#Code Lines 7 to 8: Predict on testing data
y1 = dtree1.predict(X_test)
y2 = dtree2.predict(X_test)
下面的代码为第一个回归树“dtree1”生成评估指标——RMSE 和 R 平方。
# Print RMSE and R-squared value for regression tree 'dtree1' on training data
print(np.sqrt(mean_squared_error(y_train,tr1)))
print(r2_score(y_train, tr1))
# Print RMSE and R-squared value for regression tree 'dtree1' on testing data
print(np.sqrt(mean_squared_error(y_test,y1)))
print(r2_score(y_test, y1))
输出:
7.146794965406164
0.9030125411762373
11.751081527241734
0.6059522633855321
<font
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~