---
tags: Survey
lang: ja-jp
---
# GBM x Time Series
- [SIGNATEお弁当の売り上げをLightGBMで予測してみた](https://qiita.com/chusan/items/d7b210243f3b646375ba)
時系列の予測で言えば、ガウス過程も良いアイディアかもしれないので、今後調査する。
## Overview
1. トレンドの捕捉(Curve Fitting)
2. 時系列1点あたりの予測(Gradient Boosting Machineなど)
## scipy.optimize.curve_fit
[SciPy Doc](https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html)
関数のシグネチャは次の通り:
`curve_fit(f, xdata, ydata, p0=None, absolute_sigma=False, check_finite=True, bounds=(-inf, inf), method=None, jac=None, **kwargs)`
### description
- 非線形の最小二乗法で関数`f`をデータにフィットさせる
- `ydata`と`xdata`は`f`によって`ydata = f(xdata, *params) + eps`という誤差構造によって束縛されることを仮定している
- 返り値は`popt: array`と`pcov: 2darray`
- **popt**: 残渣平方和を最小化するパラメータ`*params*の結果
- **pcov**: 最適化されたパラメータの分散共分散行列
- 次のような場合にエラーを挙げる:
- **ValueError**: ydataまたはxdataにNaNが含まれているか、引数として不適切な値が設定されている場合
- **RuntimeError**: 最小二乗法による最適化が失敗した場合
- **OptimizeWarning**: パラメータの共分散が推定できない場合
## Curve Fitting
トレンドを捉える場合に、`scipy.optimize.curve_fit`が便利。逆に言えば、時系列のプロットから異なるトレンドが混在している場合にはその区間を分割して扱わなければならない。
また、フィットさせる関数としてどのようなものを利用するかについて考える必要もある。
```python=
import numpy as np
from scipy.optimize import curve_fit
def func(x, a, b, c):
return a * np.exp(-b * x) + c
xs = train.index.values
ys = train['y'].values
popt, pcov = curve_fit(func, xs, ys)
a1, b1, c1 = popt
y_reg = a1 * np.exp(-b1 * xs) + c1
```
## EDA
時系列データには周期性が存在することはほとんど自明であり、月、曜日、時間帯などで構造を捉えてみると良い。
### 「日」(1〜31日)によるばらつきの可視化
```python=
import plotly.offline as offline
offline.init_notebook_mode(connected=False)
import plotly.graph_objs as go
layout = go.Layout(
autosize=False,
width=950,
height=500,
margin=go.layout.Margin(
l=80,
r=50,
b=50,
t=10,
pad=4),
xaxis=dict(
title='day',
titlefont=dict(
size=14,
),
showticklabels=True,
tickangle=0,
tickfont=dict(
size=12,
),
),
yaxis=dict(
title='トレンドを除いた販売数',
titlefont=dict(
size=14,
),
showticklabels=True,
tickfont=dict(
size=10,
),
)
)
data = [go.Box(x=train['day'], y=train['new_y'])]
fig = go.Figure(data=data, layout=layout)
offline.iplot(fig, filename=example, show_link=False,
config={'displaylogo': False, 'modeBarButtonsToRemove': ['sendDataToCloud']})
```
### Mean/Median Encoding
WIP
## GBMのパラメータ調整
1. 大きめの学習率(0.1くらい)で最適な木の数(n_estimators)を決定する
2. 木に関するパラメータ(colsample_bytree, max_depth, subsampleなど)をチューニングする
3. 正則化パラメータ(reg_alpha, reg_lambda)をチューニングする
4. より小さい学習率で最適な木の数を決定する