特征工程之处理时间序列数据

简介: 特征工程之处理时间序列数据

如何将上述特种数据用于搭建Gradient Boosting 回归模型,并且实现对于地铁州际交通量的预测

数据情况

在本文中,我们使用地铁州际交通量数据集,它可以在UCI机器学习库中找到(https://archive.ics.uci.edu/ml/datasets/Metro+Interstate+Traffic+Volume)。该数据集是明尼苏达州圣保罗州明尼阿波利斯市I-94的每小时交通量,其中包括2012-2018年的天气和假日数据。这48204行数据包含以下属性:

  1. holiday:类型数据,包含美国国家法定假日、区域假日、明尼苏达州博览会等
  2. temp:数值型数据,平均温度(开尔文)
  3. rain_1h:数值型数据,每小时降雨(毫米)
  4. snow_1h:数值型数据,每小时降雪(毫米)
  5. clouds_all:数值型数据,云层情况(百分比)
  6. weather_main:类型数据,当前天气的分类描述(简要)
  7. weather_description:类型数据,当前天气的分类描述(详细)
  8. data_time:时间序列数据
  9. traffic_volume:数值型数据,每小时I-94 ATR 301记录的西行交通量(本文预测目标)

接下来,我们首先载入数据:

#importlibrariesimportpandasaspdimportnumpyasnpimportmatplotlib.pyplotasplt#loadthedataraw=pd.read_csv('Metro_Interstate_Traffic_Volume.csv')
#displayfirstfiverowsraw.head()
#displaydetailsforeachcolumnraw.info()

640.png

raw.head()

640.png

raw.info()

查看info信息,我们发现data_time这一类目是object类型,所以我们需要将其转化为datetime类型:

#convertdate_timecolumntodatetimetyperaw.date_time=pd.to_datetime(raw.date_time)

特征工程

从上面的info方法的输出中,我们知道除了date_time列之外还有其他的分类特征。但是由于本文的主要主题是处理时间序列数据,我们将重点关注针对date_time的特性工程。

Month

Pandas自身有许多易于使用的方法来处理datetime类型的数据。要提取时间/日期信息,我们只需调用pd.Series.dtpd.Series.dt.month是提取month信息所需的函数。这将产生一系列int64格式的月份数字(例如1代表1月,10代表10月)。

#extractmonthfeaturemonths=raw.date_time.dt.month

Day of month

Month类似,我们只需要调用pd.Series.dt.day函数。以2012-10-27 09:00:00为例,调用该函数提取结果为27。

#extractdayofmonthfeatureday_of_months=raw.date_time.dt.day

Hour

类似地,pd.Series.dt.hour将生产对应的小时信息数据(范围为0-23的整数)。

#extracthourfeaturehours=raw.date_time.dt.hour

Day name

获取Day name的方式和上面几个数据有所不同。我们想要确定raw.date_time序列中关于星期几的信息,需要以下两个步骤。首先,通过pd.Series.dt.day_name()生成day name序列。然后,我们需要通过pd.get_dummies()进行独热编码(one-hot encode)。

#first: extractthedaynameliteralto_one_hot=raw.date_time.dt.day_name()
#second: onehotencodeto7columnsdays=pd.get_dummies(to_one_hot)
#displaydatadays

640.png

独热编码后的Day name信息

Daypart

在本部分中,我们将基于Hour数据创建一个分组。我们希望有六个小组代表每一天的各个部分。它们是黎明(02.00-05.59)、上午(06.00-09.59)、中午(10.00-13.59)、下午(14.00-17.59)、晚上(18.00-21.59)和午夜(22.00-次日01.59)。

为此,我们创建了一个标识函数,稍后将使用该函数来作为数据系列的apply方法。然后,我们对得到的dayparts执行一个热编码。

#daypartfunctiondefdaypart(hour):
ifhourin [2,3,4,5]:
return"dawn"elifhourin [6,7,8,9]:
return"morning"elifhourin [10,11,12,13]:
return"noon"elifhourin [14,15,16,17]:
return"afternoon"elifhourin [18,19,20,21]:
return"evening"else: return"midnight"#utilizeitalongwithapplymethodraw_dayparts=hours.apply(daypart)
#onehotencodingdayparts=pd.get_dummies(raw_dayparts)
#re-arrangecolumnsforconveniencedayparts=dayparts[['dawn','morning','noon','afternoon','evening','midnight']]
#displaydatadayparts

640.png

独热编码后的Day parts信息

Weekend flag

我们从date_time时间序列数据中提取的最后一个特征是is_weekend。这一特征指示给定的日期时间是否在周末(星期六或星期日)。为了实现这一目标,我们将利用pd.Series.dt.day_name()方法以及lambda函数。

#is_weekendflagday_names=raw.date_time.dt.day_name()
is_weekend=day_names.apply(lambdax : 1ifxin ['Saturday','Sunday'] else0)

Holiday flag 以及 weather

幸运的是,这些数据还包含公共假日信息。信息是细粒度的,因为它提到每个公共假日的名称。尽管如此,本文假设对每个假期进行编码并没有显著的好处。因此,让我们创建一个二进制特性来指示对应的日期是否是假日。

#is_holidayflagis_holiday=raw.holiday.apply(lambdax : 0ifx=="None"else1)

我们需要考虑的最后一个分类特征是天气。我们只对该特征进行如下独热编码。

#one-hotencodeweatherweathers=pd.get_dummies(raw.weather_main)
#displaydataweathers

640.png

独热编码后的Weather信息

特征处理后的数据

现在,我们终于有了最终的可用于训练的数据!让我们创建一个名为features的全新数据集,它包含所有的特征,包括数值型特征(我们从原始数据中按原样放置)和类型特征(我们设计的特性)。

#featurestable#firststep: includefeatureswithsinglecolumnnaturefeatures=pd.DataFrame({
'temp' : raw.temp,
'rain_1h' : raw.rain_1h,
'snow_1h' : raw.snow_1h,
'clouds_all' : raw.clouds_all,
'month' : months,
'day_of_month' : day_of_months,
'hour' : hours,
'is_holiday' : is_holiday,
'is_weekend' : is_weekend})
#secondstep: concatwithone-hotencodetypedfeaturesfeatures=pd.concat([features, days, dayparts, weathers], axis=1)
#targetcolumntarget=raw.traffic_volume

在我们将数据输入模型之前,我们需要分割数据(训练集和测试集)。请注意,下面我们不随机化我们的数据,这是由于我们的数据具有时间序列特征。

#splitdataintotrainingandtestdataX_train, X_test, y_train, y_test=train_test_split(features, target, test_size=0.1, shuffle=False)

建立回归预测模型

现在我们准备建立我们的模型来预测地铁州际交通量。在这项工作中,我们将使用Gradient Boosting回归模型。

该模型的理论和具体细节超出了本文的讨论范围。但是简单来说,gradient-boosting模型属于集成模型,它使用梯度下降算法来降低弱学习模型(决策树)中的预测损失。

训练模型

让我们在训练数据上实例化模型并训练模型!

fromsklearnimportdatasets, ensemble#definethemodelparametersparams= {'n_estimators': 500,
'max_depth': 4,
'min_samples_split': 5,
'learning_rate': 0.01,
'loss': 'ls'}
#instantiateandtrainthemodelgb_reg=ensemble.GradientBoostingRegressor(**params)
gb_reg.fit(X_train, y_train)

评价模型

我们选择两个指标来评价模型:MAPE 和 R2得分。在测试集上使用训练完成的模型进行预测,然后计算这两个指标。

#defineMAPEfunctiondefmape(true, predicted):        
inside_sum=np.abs(predicted-true) /truereturnround(100*np.sum(inside_sum ) /inside_sum.size,2)
#importr2scorefromsklearn.metricsimportr2_score#evaluatethemetricsy_true=y_testy_pred=gb_reg.predict(X_test)
#print(f"GB model MSE is {round(mean_squared_error(y_true, y_pred),2)}")
print(f"GB model MAPE is {mape(y_true, y_pred)} %")
print(f"GB model R2 is {round(r2_score(y_true, y_pred)* 100 , 2)} %")

640.png

测试集上的评价指标结果

我们可以看出我们的模型性能相当不错。我们的MAPE低于15%,而R2得分略高于95%。

结果可视化

为了直观理解模型性能,结果可视化很有必要。

由于我们的测试数据(4820个数据点)的长度,我们只绘制了最后100个数据点上的实际值和模型预测值。此外,我们还包括另一个模型(在下面的绘图代码中称为gb_reg_lite),它不包含日期时间特征作为其预测因子(它只包含非日期时间列作为特征,包括tempweather等)。

fig, ax=plt.subplots(figsize= (12,6))
index_ordered=raw.date_time.astype('str').tolist()[-len(X_test):][-100:]
ax.set_xlabel('Date')
ax.set_ylabel('Traffic Volume')
#theactualvaluesax.plot(index_ordered, y_test[-100:].to_numpy(), color='k', ls='-', label='actual')
#predictionsofmodelwithengineeredfeaturesax.plot(index_ordered, gb_reg.predict(X_test)[-100:], color='b', ls='--', label='predicted; with date-time features')
#predictionsofmodelwithoutengineeredfeaturesax.plot(index_ordered, gb_reg_lite.predict(X_test_lite)[-100:], color='r', ls='--', label='predicted; w/o date-time features')
every_nth=5forn, labelinenumerate(ax.xaxis.get_ticklabels()):
ifn%every_nth!=0:
label.set_visible(False)
ax.tick_params(axis='x', labelrotation=90)
plt.legend()
plt.title('Actual vs predicted on the last 100 data points')
plt.draw()

640.png

后100个点的预测结果

该图中蓝色虚线与黑色实线十分接近。也就是说,我们提出的gradient-boosting模型可以很好地预测地铁交通量。

同时,我们看到不使用日期时间特征的模型在性能上出现了差异(红色虚线)。为什么会这样?只是因为我们会依赖交通工具,交通流量在周末趋于减少,但在高峰时段出现高峰。因此,如果我们不对日期时间数据进行特征工程处理,我们将错过这些重要的预测因子!

目录
相关文章
|
2月前
|
机器学习/深度学习 算法 数据建模
探索XGBoost:时间序列数据建模
探索XGBoost:时间序列数据建模
117 2
|
机器学习/深度学习 存储 算法
时序数据特征工程浅析
内容摘要特征工程是指将原始数据标记处理为价值密度更高,更容易解释目标问题的工程化过程,在面向大量原始采集的数据集统计分析,尤其是对于高通量持续采集、且价值密度较低的时序数据更是如此。时序数据特征工程则是指利用有效方法,将原始时序数据转化为带有含义分类标签的序列数据片段或特征数值,例如,我们可以将指定时间窗口序列数据标识为特定异常关联数据,并保留平均、最大、最小值作为该序列的特征值。这样我们就可以围
2919 0
时序数据特征工程浅析
|
2月前
时间序列分析实战(二):时序的ARMA模型拟合与预测
时间序列分析实战(二):时序的ARMA模型拟合与预测
|
3天前
|
机器学习/深度学习 vr&ar
技术心得:时间序列:ARIMA模型
技术心得:时间序列:ARIMA模型
|
2月前
|
机器学习/深度学习 数据可视化 数据挖掘
时间序列预测:探索性数据分析和特征工程的实用指南
时间序列分析在数据科学和机器学习中广泛应用于预测,如金融、能源消耗和销售。随着技术发展,除了传统统计模型,机器学习(如树模型)和深度学习(如LSTM、CNN和Transformer)也被应用。探索性数据分析(EDA)是预处理关键步骤,它通过Pandas、Seaborn和Statsmodel等Python库进行。本文展示了时间序列分析模板,包括描述性统计、时间图、季节图、箱形图、时间序列分解和滞后分析。使用Kaggle的小时能耗数据集,展示了如何通过这些方法揭示数据模式、季节性和趋势,为特征工程提供见解。
42 3
|
2月前
R语言用ARIMA模型,ARIMAX模型预测冰淇淋消费时间序列数据
R语言用ARIMA模型,ARIMAX模型预测冰淇淋消费时间序列数据
R语言用ARIMA模型,ARIMAX模型预测冰淇淋消费时间序列数据
|
2月前
|
数据挖掘 vr&ar Python
使用Python实现时间序列预测模型
使用Python实现时间序列预测模型
68 3
|
2月前
R语言多元时间序列滚动预测:ARIMA、回归、ARIMAX模型分析
R语言多元时间序列滚动预测:ARIMA、回归、ARIMAX模型分析
|
2月前
|
SQL 数据可视化
Prophet在R语言中进行时间序列数据预测
Prophet在R语言中进行时间序列数据预测
|
9月前
|
机器学习/深度学习 运维 计算机视觉
TimesNet:时间序列预测的最新模型
2023年4月发表了一个新的模型,它在时间序列分析的多个任务中实现了最先进的结果,如预测、imputation、分类和异常检测:TimesNet。
578 0