Kewei
首页·Home
留言·Message
关于·About
搜索
时间序列预测(三)—— Xgboost模型
2019年05月20日 15:24:55
10447
0
0
文章分类:
Data Analysis
Python
# 时间序列预测(三)—— Xgboost模型 欢迎大家来我的个人博客网站观看原文:https://xkw168.github.io/2019/05/20/%E6%97%B6%E9%97%B4%E5%BA%8F%E5%88%97%E9%A2%84%E6%B5%8B-%E4%B8%89-Xgboost%E6%A8%A1%E5%9E%8B.html ## 文章链接 [(一)数据预处理](https://blog.csdn.net/kewei168/article/details/90375591) [(二)AR模型(自回归模型)](https://blog.csdn.net/kewei168/article/details/90375623) [(三)Xgboost模型](https://blog.csdn.net/kewei168/article/details/90375743) [(四)LSTM模型](https://blog.csdn.net/kewei168/article/details/90375856) [(五)Prophet模型(自回归模型)](https://blog.csdn.net/kewei168/article/details/90375897) --- ## 模型原理   Xgboost(Extreme Gradient Boost)模型,是一种特殊的梯度提升决策树(GBDT,Gradient Boosting Decision Tree),只不过是力求将速度和效率发挥到了极致,故叫X(Extreme)gradientboost。Xgboost其本质上还是基于树结构并结合集成学习的一种方法,其基础树结构为分类回归树(CART,Classification and Regression Tree)。类似于局部加权线性回归算法,基于树的回归算法也是一类局部的回归算法,通过将数据集切分成多份,在每一份数据上单独建模。但不同的是基于树的回归算法是一种基于参数的学习算法,利用训练数据训练完模型后,参数一旦确定,无需再改变。分类回归树是一种基于决策树的结构,既可以用于解决分类问题也可以用于解决回归问题,是国际权威的学术组织The IEEE International Conference on DataMining (ICDM)早前评选出了数据挖掘领域的十大经典算法之一。   CART算法核心内容包含以下三个方面: 1. 二分(Binary Split):在每次判断过程中,都是对观察变量进行二分。CART算法采用一种二分递归分割的技术,算法总是将当前样本集分割为两个子样本集,使得生成的决策树的每个非叶结点都只有两个分枝。因此CART算法生成的决策树是结构简洁的二叉树; 2. 单变量分割(Split Based on One Variable):每次最优划分都是针对单个变量; 3. 剪枝策略:CART算法的关键点,也是所有基于树(Tree-Based)算法的关键步骤   决策树的生成就是递归地构建二叉决策树的过程,核心思想为在训练数据集所在的输入空间中,递归地将每个区域划分为两个子区域并决定每个子区域上输出值。划分子区域的标准取决于树的种类,对回归树用平方误差最小化准则,对分类树用基尼指数最小化准则。回归树的生成具体步骤如下: 1. 选择最优切分变量j与切分点s,求解 $$min[min{\sum_{x_i \in R_1(j,s)} (y_i-c_1)^2} + min{\sum_{x_j \in R_2(j,s)} (y_j-c_2)^2}]$$ 遍历变量j,对固定的切分变量j扫描切分点s,选择使上式最小值的对$(j; s)$。其中$R_m$是被划分的输入空间,$c_m$是空间$R_m$对应的输出值 2. 用选定的对$(j; s)$划分区域并决定相应的输出值 $$ R_1(j,s)=\{x|x^{(j)} \leq s\}, R_2(j,s)=\{x|x^{(j)} > s\} \\ \hat{c}_m = \frac{1}{N_m} \sum_{x_i \in R_m(j,s)} y_i, x \in R_m, m = 1,2 $$ 3. 继续对两个子区域递归的调用上述步骤,最终将输入空间划分为M个区域$R_1,R_2,…,R_m$,生成决策树 $$f(x) = \sum_{m=1}^{M} \hat{c}_m I(x \in R_m)$$ 4. 当输入空间划分确定时,可以用平方误差来衡量回归树对于训练数据的拟合程度,用平方误差最小的准则不断地递归划分子树,直到平方误差满足需求 $$L(y, f(x)) = \sum_{x_i \in R_m} {(y_i - f(x_i))}^2$$   单棵分类回归树精度有限,应用场景受限,故Xgboost在CART的基础上引入了集成学习(boosting方法),并采用并行计算等方式极大的加速了模型计算速度。Boosting的核心思想就是所有弱分类器的结果相加等于预测值,然后下一个弱分类器去拟合误差函数对预测值的梯度/残差(这个梯度/残差就是预测值与真实值之间的误差),从而不断地减小残差,直到满足系统的误差要求(如图所示)  --- ## 模型安装 `pip install xgboost` --- ## 模型实现 ```python def xgboost_predict(train_data, evaluation_data, forecast_cnt=365, freq="D", importance_fig=False, model_dir=""): """ predict time series with XGBoost library which is based on Gradient Boost and CART(classification and regression tree) :param train_data: data use to train the model :param evaluation_data: data use to evaluate the model :param forecast_cnt: how many point needed to be predicted :param freq: the interval between time index :param importance_fig: whether plot importance of each feature :param model_dir: directory of pre-trained model(checkpoint, params) :return: """ def create_features(df, label=None): """ Creates time series features from datetime index """ df['date'] = df.index df['hour'] = df['date'].dt.hour df['dayofweek'] = df['date'].dt.dayofweek df['quarter'] = df['date'].dt.quarter df['month'] = df['date'].dt.month df['year'] = df['date'].dt.year df['dayofyear'] = df['date'].dt.dayofyear df['dayofmonth'] = df['date'].dt.day df['weekofyear'] = df['date'].dt.weekofyear X = df[['hour', 'dayofweek', 'quarter', 'month', 'year', 'dayofyear', 'dayofmonth', 'weekofyear']] if label: y = df[label] return X, y return X model_directory = "./model/XGBoost_%s" % now() params = { } # if there is a pre-trained model, use parameters from it if model_dir: model_directory = model_dir latest_date = evaluation_data["ds"].tolist()[-1] # set index with datetime train_data = train_data.set_index(pd.DatetimeIndex(train_data["ds"])) evaluation_data = evaluation_data.set_index(pd.DatetimeIndex(evaluation_data["ds"])) forecast_data = pd.DataFrame.from_dict({ "ds": generate_time_series(start_date=latest_date, cnt=forecast_cnt, delta=delta_dict[freq]) }) forecast_data = forecast_data.set_index(pd.DatetimeIndex(forecast_data["ds"])) x_train, y_train = create_features(train_data, label='y') x_eval, y_eval = create_features(evaluation_data, label="y") x_forecast = create_features(forecast_data) reg = XGBRegressor(n_estimators=1000) if model_dir: reg.load_model(model_directory) else: reg.fit(x_train, y_train, eval_set=[(x_train, y_train), (x_eval, y_eval)], early_stopping_rounds=50, verbose=False) # Change verbose to True if you want to see it train reg.save_model(model_directory) if importance_fig: plot_importance(reg, height=0.9) evaluation_data["y"] = reg.predict(x_eval) forecast_data["y"] = reg.predict(x_forecast) return evaluation_data, forecast_data ``` --- ### 关键参数 - early_stopping_rounds:早期停止次数,用于控制模型的迭代次数。假设为50,则模型会在训练到50次内误差基本不变的时候提前结束训练。 注意这里假设只有一个时间序列,实际情况中,可能存在多个序列与待分析的时间序列相关,可以模仿这里的写法将其拓展为多特征分析与预测(这里仅仅用到了时间这一特征)。
点赞
0
分享