当前位置: 首页 > 后端技术 > Python

多变量时间序列特征工程指南

时间:2023-03-26 18:38:38 Python

使用Python添加基于汇总统计的新特征,本文将向您展示如何计算跨多个时间序列的滚动统计。将此信息添加到解释变量中通常会带来更好的预测性能。简介自回归多元时间序列包含两个或多个变量,研究这些数据集的目的是预测一个或多个变量,请参见下面的示例。上图是一个有9个变量的多元时间序列。这些是智能浮标捕捉到的海况。大多数预测模型都基于自回归。这相当于解决一个监督学习回归任务。这个序列的未来值是目标变量。输入的解释变量是每个变量最近的过去值。自回归在一个主要假设下起作用。最近的过去值包含足够的关于未来的信息。但这不一定是真的。我们可以尝试从最近的数据中提取更多信息。例如,滚动摘要统计有助于描述最近的动态。自动化特征工程特征工程涉及提取和生成解释变量,这是任何数据科学项目的关键。特征质量是模型性能的核心方面,因此数据科学家在这个过程中花费了大量时间。特征工程通常是一个临时过程:数据科学家根据他们的领域知识和专业知识创建特征,如果这个过程可以自动化,它将为我们节省大量时间。让我们看看如何在多元时间序列中做到这一点。基线模型读取数据我们将使用从智能浮标收集的多元时间序列作为本文的数据集[1]。这个浮标位于爱尔兰海岸外。它捕获了9个与海洋条件相关的变量。其中包括海水温度、波高和海流速度等。上面的图1显示了2022年的第一个月。以下是使用pandas读取此数据的方法:importpandasaspd#skippingsecondrow,settingtimecolumnasadatetimecolumn#datasetavailablehere:https://github.com/vcerqueira/blog/tree/main/databuoy=pd.read_csv('data/smart_buoy.csv',skiprows=[1],parse_dates=['time'])#设置时间为索引buoy.set_index('time',inplace=True)#重采样为每小时数据buoy=buoy.resample('H').mean()#简化列名buoy.columns=['PeakP','PeakD','Upcross','SWH','SeaTemp','Hmax','THmax','MCurDir','MCurSpd']该数据集研究的目标是预测SWH(有效波高)变量的未来值。该变量通常用于量化波浪的高度。这个问题的一个用例是估计海浪的电力大小,因为这种能源是一种越来越受欢迎的不可再生能源替代品。自回归模型时间序列是多变量的,因此可以使用ARDL(Auto-regressivedistributedlags)方法来解决这个任务。我们之前也介绍过这种方法。下面是这个方法的现实:importpandasaspdfromsklearn.model_selectionimporttrain_test_splitfromsklearn.metricsimportmean_absolute_percentage_errorasmapefromsklearn.multioutputimportMultiOutputRegressorfromlightgbmimportLGBMRegressor#https://github.com/vcerqueira/blog/blob/main/src/tde.pyfromsrc.tdeimporttime_delay_embeddingtarget_var='SWH'colnames=buoy.columns.tolist()#使用时间延迟嵌入创建具有滞后特征的数据集buoy_ds=[]forcolinbuoy:col_df=time_delay_embedding(buoy[col],n_lags=24,horizo??n=12)buoy_ds.append(col_df)#连接所有变量buoy_df=pd.concat(buoy_ds,axis=1).dropna()#定义目标(Y)和解释变量(X)predictor_variables=buoy_df.columns.str.contains('\(t\-')target_variables=buoy_df.columns.str.contains(f'{target_var}\(t\+')X=buoy_df.iloc[:,predictor_variables]Y=buoy_df.iloc[:,target_variables]#train/testsplitX_tr,X_ts,Y_tr,Y_ts=train_test_split(X,Y,test_size=0.3,shuffle=False)#在没有特征工程的情况下拟合lgbm模型model_wo_fe=MultiOutputRegressor(LGBMRegressor())model_wo_fe.fit(X_tr,Y_tr)#为测试集获取预测.predict(X_ts)#计算MAPE误差mape(Y_ts,preds_wo_fe)#0.238首先将时间序列转化为自回归问题这是由函数time_delay_embedding完成的。预测的目标是预测12个未来的SWH值(horizo??n=12)。解释变量是序列中每个变量过去24个值(n_lag=24)。我们这里直接使用LightGBM来训练每个预测层。该方法是一种常用的多步前瞻性预测方法。它也在scikit-learn中实现,称为MultiOutputRegressor。上面的代码构建并测试了一个自回归模型。解释变量只包括每个变量最近的过去值。结果的平均绝对百分比误差为0.238。让我们将这个结果与基类进行比较,看看我们是否可以通过特征工程来改进它。多元时间序列的特征工程本文将介绍两种从多元时间序列中提取特征的方法:单变量特征提取。计算每个变量的滚动统计数据。例如,滚动平均可用于去除虚假观察;二进制特征提取。计算变量对的滚动统计数据以总结它们的相互作用。例如,两个变量之间的滚动协方差。单变量特征提取我们可以总结每个变量最近的过去值。例如,计算滚动平均值以总结最近的情况。或滚动增量以了解最近的点差。importnumpyasnpSUMMARY_STATS={'mean':np.mean,'sdev':np.std,}univariate_features={}#对于数据中的每一列forcolincolnames:#获取该列的滞后X_col=X.iloc[:,X.columns.str.startswith(col)]#对于feat的每个汇总统计数据,funcinSUMMARY_STATS.items():#沿行计算该统计数据univariate_features[f'{col}_{feat}']=X_col.apply(func,axis=1)#将特征连接到pd.DF中可以将函数添加到SUMMARY_STATS字典中以实现此目的。将这些函数放在字典中可以保持代码整洁。二元特征提取和单变量统计错过了不同变量之间的潜在相互作用。因此,我们可以使用二进制特征提取过程来捕获此信息。这个想法是为不同的变量对计算特征。这些对的联合动态可以使用双变量统计进行总结。有两种方法可以做到这一点:滚动二进制统计。以变??量对作为输入计算统计数据。例如,滚动协方差或滚动相关性滚动二进制统计的示例包括协方差、相关性或相对熵。滚动二进制转换,然后是单变量统计。这会将一对变量转换为一个变量并对该变量进行统计。例如,计算元素相互关系,然后取平均。二元变换的方法有很多种。例如,成对变量之间的百分比差异、相关性或线性卷积。通过第一步后,这些转换会用平均值或标准差等统计数据进行汇总。下面是用于完成这两个过程的代码:':covariance,'co_integration':co_integration,'js_div':jensenshannon,}BIVARIATE_TRANSFORMATIONS={'corr':signal.correlate,'conv':signal.convolve,'rel_entr':rel_entr,}#获取所有变量对col_combs=list(itertools.combinations(colnames,2))bivariate_features=[]#foreachrowfori,_inX.iterrows():#在第i个时间步的特征集feature_set_i={}forcol1,col2incol_combs:#列对的特征col1,col2#获取每列的第i个实例x1=X.loc[i,X.columns.str.startswith(col1)]x2=X.loc[i,X.columns.str.startswith(col2)]#计算每个汇总统计forfeat,funcinBIVARIATE_SUMMARY_STATS.items():feature_set_i[f'{col1}|{col2}_{feat}']=func(x1,x2)#foreachtransformationfortrans_f,t_funcinBIVARIATE_TRANSFORMATIONS.items():#应用转换xt=t_func(x1,x2)#在SUMMARY_STATS.items()中计算feat,s_func的摘要统计:feature_set_i[f'{col1}|{col2}_{trans_f}_{feat}']=s_func(xt)bivariate_features.append(feature_set_i)bivariate_features_df=pd.DataFrame(bivariate_features,index=X.index)添加其他函数到字典bivariate_transforms或BIVARIATE_STATS,可以添加额外的transformations或statistics提取所有特征后,我们将它们连接起来为原始解释变量。训练和测试的过程与之前相同,只是我们添加了一些人为生成的变量。#连接所有具有滞后的特征X_with_features=pd.concat([X,univariate_features_df,bivariate_features_df],axis=1)#train/testsplitX_tr,X_ts,Y_tr,Y_ts=train_test_split(X_with_features,Y,test_size=0.3,seshuffle)#用特征工程拟合lgbm模型model_w_fe=MultiOutputRegressor(LGBMRegressor())model_w_fe.fit(X_tr,Y_tr)#获取测试集的预测preds_w_fe=model_w_fe.predict(X_ts)#计算MAPEerrorYprintts,mape(preds_w_fe))#0.227获得0.227的平均绝对百分比误差,这是一个小改进,因为我们的基线是0.238。特征选择通过上述提取过程共得到558个解释变量。根据变量和汇总统计数据的数量,这可能会产生高维问题。因此,从数据集中删除不良或冗余特征非常重要。我们将找到一些重要的特征并重新训练#获取每个特征在每个视野中的重要性avg_imp=pd.DataFrame([x.feature_importances_forxinmodel_w_fe.estimators_]).mean()#获取前100个特征n_top_features=100importance_scores=pd.Series(dict(zip(X_tr.columns,avg_imp)))top_features=importance_scores.sort_values(ascending=False)[:n_top_features]top_features_nm=top_features.index#通过这些特征对训练和测试集进行子集X_tr_toptop_features_nm]X_ts_top=X_ts[top_features_nm]#重新拟合lgbm模型model_top_features=MultiOutputRegressor(LGBMRegressor())model_top_features.fit(X_tr_top,Y_tr)#获取测试集的预测preds_top_feats=model_top_features.predict(X_ts_top)#计算MAE误差mape(Y_ts,preds_top_feats)#0.229可以看出前100个特征与全部558个特征表现相似。下面是前15个特征的重要性(为简洁省略其他特征):可以看出,最重要的特征是目标变量的第一个滞后值。一些提取的特征也出现在前15名中。例如第三个特征SWH|Hmax_js_div。这表示目标变量的滞后与Hmax的滞后之间的Jensen-Shannon散度。第五个特征是SeaTemp_sdev,代表海洋温度的标准差滞后。删除冗余特征的另一种方法是应用相关过滤器。去除高度相关的特征来降低数据的维度,这里我们不做演示。总结本文重点研究预测多变量时间序列的问题。特征提取过程应用于时间序列的多个子序列,在每个时间步,用一组统计数据汇总过去24小时的数据。我们还可以使用这些统计数据一次性描述整个时间序列。如果我们的目标是对一组时间序列进行聚类,这将很有用。通过特征提取总结每个时间序列。然后将聚类算法应用于生成的特征。用几句话总结这篇文章的要点:多变量时间序列预测通常是一个自回归过程特征工程是数据科学项目中的关键步骤。多变量时间序列数据可以通过特征工程进行改进。这包括计算单变量和双变量转换和汇总统计。提取太多特征会导致高维问题。特征选择方法可用于去除不需要的特征。本文数据集下载地址:https://avoid.overfit.cn/post/dcb4ca4d223e4e728fb778739b69f136作者:VitorCerqueira