独学でプログラミングを学んでみた

python初心者がテックブログを書いてみた

Pythonで特徴量を作る際に気を付けておくこと:rollingについて

rollingを使って特徴量を作る際に気を付けておくことを書いておきます。

正直に申しますとかなりアホな間違えをしてしまったので、戒めのために備忘録として残しておきます。

ここでの記事はpython機械学習での説明になります。

・rollingの扱い

基本的なrollingの扱いは以下の通り

import pandas as pd
s = pd.Series(range(10))

#########################
0    0
1    1
2    2
3    3
4    4
5    5
6    6
7    7
8    8
9    9
#########################
df = pd.DataFrame({
    'num' : s,
    'rolling': s.rolling(3).sum()
})
index num rolling
0 0 NaN
1 1 NaN
2 2 3.0
3 3 6.0
4 4 9.0
5 5 12.0
6 6 15.0
7 7 18.0
8 8 21.0
9 9 24.0

rolling(window=3)の場合は
index[0]+[1]+[2] = 3
index[1]+[2]+[3] = 6
index[2]+[3]+[4] = 9
index[3]+[4]+[5] = 12
index[4]+[5]+[6] = 15
index[5]+[6]+[7] = 18
index[6]+[7]+[8] = 21
index[7]+[8]+[9] = 24

3の場合は2つズレたうえで3つずつを足し算する動きを取る。
但し、min_periodsという引数を入れるとその値の個数のデータが含まれていれば結果が算出される。

さて本題ですが
私はテストデータと訓練データをくっつける際に使用上出てこない数字(python初学者が競馬予測をしてみたをもとにすると[result, 3ftime, rank3, rank4などの指数])
これに関しては欠損値が出てしまうので999の値を入れていたのですが、実際に入れてみるとこんな感じ

s['10'] = 999

#########################
0       0
1       1
2       2
3       3
4       4
5       5
6       6
7       7
8       8
9       9
10    999
#########################

これをrollingすると(結果はわかるかもしれませんが。。。)

index num rolling
0 0 NaN
1 1 NaN
2 2 3.0
3 3 6.0
4 4 9.0
5 5 12.0
6 6 15.0
7 7 18.0
8 8 21.0
9 9 24.0
10 999 1016.0

そうです。index10の所が異常値になって返ってきます。
解決策として

df = pd.DataFrame({
    'num' : s,
    'rolling': s.rolling(3).sum().shift(1)
})
index num rolling
0 0 NaN
1 1 NaN
2 2 NaN
3 3 3.0
4 4 6.0
5 5 9.0
6 6 12.0
7 7 15.0
8 8 18.0
9 9 21.0
10 999 24.0


案の一つかもしれませんがこんな感じでかけたりします。
shiftを使う際はmin_periodsという引数を入れた方がいいのかもしれません。

df = pd.DataFrame({
    'num' : s,
    'rolling': s.rolling(3, min_periods=2).sum().shift(1)
})
index num rolling
0 0 NaN
1 1 NaN
2 2 1.0
3 3 3.0
4 4 6.0
5 5 9.0
6 6 12.0
7 7 15.0
8 8 18.0
9 9 21.0
10 999 24.0

いい感じに加工できたと思います。

明らかに間違いをした場合は機械学習した際に予測値がおかしくなり正常に予想ができなくなります。
そうなった場合は前処理の部分を中心に探してみるのもいいかもしれません。

ではまた。