# Python时间序列梯度提升模型预测优化共享单车调度

{% tabs %}
{% tab title="关键词" %}
Python | 共享单车 | 梯度提升 | 预测模型 | 时间序列 | NumPy | Pandas | Matplotlib | XGBoost | LightGBM | Catboost
{% endtab %}

{% tab title="梗概" %}
梯度提升模型在机器学习社区中脱颖而出，因为它们在众多用例（回归和分类）中取得了良好的效果。 尽管它们在预测中的使用受到限制，但近年来，已经表明它们可以取得非常有竞争力的结果。 使用这种类型的模型的一些优点是：

* 除了自回归变量之外，易于包括外生变量。
* 它们允许在模型中包含非线性关系。
* 高可扩展性，允许在大量数据可用时应用它们。

尽管它们具有潜在的优势，但在将机器学习模型应用于预测问题时，会出现一些问题，使分析师不愿意使用它们，主要是：

* 重塑数据，使其可以像回归问题一样使用。
* 根据需要多少未来预测（预测范围），必须对迭代过程进行编程，其中每个新预测都依赖于先前的预测。
* 模型验证需要特定的策略，例如回溯测试、前向验证或时间序列交叉验证。不能应用传统的交叉验证。

### 共享单车调度

共享单车系统是一种共享交通服务，其中单车可在短期内供个人共享使用。 许多单车共享系统允许人们从码头借用单车，然后在属于同一系统的另一个码头归还。 码头是特殊的单车位，可以锁定单车，只能通过计算机控制释放。

管理这些系统的主要挑战之一是需要重新分配自行车，以确保在所有码头都有可用的单车以及可供归还的空闲空间。

为了改进单车配送的规划和执行，建议创建一个能够预测未来 36 小时内用户数量的模型。 这样，在每天 12:00 时，负责管理系统的公司将能够了解当天剩余时间（12 小时）和次日（24 小时）的预期需求。 为了简化本文档中显示的示例，假设正在对单个站进行建模。

### 数据集

本文档中的数据代表 2011 年和 2012 年自行车租赁系统的每小时使用情况。除了每小时的用户数量外，还提供有关天气状况和节假日的信息。 原始数据已从机器学习存储库中获得，并且之前已应用以下修改进行了清理（代码）：

* 使用更具描述性的名称重命名列。
* 重命名天气变量的类别。大雨的类别已与雨的类别合并。
* 非归一化的温度、湿度和风变量。
* 创建变量 date\_time 并设置为索引。
* 通过前向填充填补缺失值。

生成的数据集包含以下列：

* date\_time：日期和时间。
* month：1月\~12月。
* hour：0时\~23时。
* holiday：如果当天是假期
* weekday：星期几（星期一 = 0，星期日 = 6）。
* workingday：如果是工作日。
* weathersit：当天的天气（晴、雾、雨）。
* temp：注册温度。
* atemp：热感觉。
* hum：记录的湿度。
* windspeed：记录的风速。
* users：单车租赁服务的用户总数。

```python
# Split train-val-test
# ==============================================================================
end_train = '2012-03-31 23:59:00'
end_validation = '2012-08-31 23:59:00'
data_train = data.loc[: end_train, :]
data_val   = data.loc[end_train:end_validation, :]
data_test  = data.loc[end_validation:, :]

print(f"Dates train      : {data_train.index.min()} --- {data_train.index.max()}  (n={len(data_train)})")
print(f"Dates validacion : {data_val.index.min()} --- {data_val.index.max()}  (n={len(data_val)})")
print(f"Dates test       : {data_test.index.min()} --- {data_test.index.max()}  (n={len(data_test)})")
```

### 图形绘制

时间序列的图形探索对于识别趋势、模式和季节性非常有用，这有助于指导选择可能是良好预测指标的滞后。

```python
data_train['users'].plot(ax=main_ax, label='train', alpha=0.5)
data_val['users'].plot(ax=main_ax, label='validation', alpha=0.5)
data_test['users'].plot(ax=main_ax, label='test', alpha=0.5)
min_y = min(data['users'])
max_y = max(data['users'])
main_ax.fill_between(zoom, min_y, max_y, facecolor='blue', alpha=0.5, zorder=0)
main_ax.set_xlabel('')
main_ax.legend(loc='lower center', ncol=3, bbox_to_anchor=(0.5, -0.8))

data.loc[zoom[0]: zoom[1]]['users'].plot(ax=zoom_ax, color='blue', linewidth=2)

main_ax.set_title(f'Number of users: {data.index.min()}, {data.index.max()}', fontsize=14)
zoom_ax.set_title(f'Number of users: {zoom}', fontsize=14)
plt.subplots_adjust(hspace=1)
```

#### 季节绘图

#### 自相关图

### 极端梯度提升

#### 外生变量

#### LightGBM | CatBoost

### 源代码
{% endtab %}
{% endtabs %}

{% content-ref url="../zhi-dian-mi-jin-brief" %}
[zhi-dian-mi-jin-brief](../zhi-dian-mi-jin-brief)
{% endcontent-ref %}
