Kaggleに挑戦!【Jane Street Market Prediction】④目的変数(resp)の特徴

学習記録

 こんにちは。システムトレーダーの卵ことKenKenです。絶賛、Kaggleの”Jane Street Market Prediction”に挑戦中です。前回は、130個ある特徴量の次元を圧縮し、主成分やクラスタごとにrespとの関係を調べました。今回は、説明変数であるrespの特徴について調べてみたいと思います。

※本記事は、公開しているNotebookをまとめたものとなっております。

データの分布

 まずは、respの分布をヒストグラムにしてみる。

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import os
import matplotlib.pyplot as plt
%matplotlib inline

for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))

train = pd.read_csv('/kaggle/input/jane-street-market-prediction/train.csv')
# データの分布
train['resp'].hist(bins=30)

左右はほぼで対称、0近辺にデータが集中している。

累積和の推移

 次にrespの累積和の推移をプロットをしてみる。

# リターンの累積和
train['resp'].cumsum().plot(label='resp')
train['resp_1'].cumsum().plot(label='resp_1')
train['resp_2'].cumsum().plot(label='resp_2')
train['resp_3'].cumsum().plot(label='resp_3')
train['resp_4'].cumsum().plot(label='resp_4')
plt.legend()

最初の50,000個のデータでは着々とリターンを積み上げており、その後はしばらく横ばいが続き、最後の50,000個でリターンが積みあがっている様子が見られる。最初の上昇が継続している期間は、上昇トレンドが発生している可能性がある。最初の期間の特徴をうまく抽出してあげることがパフォーマンスの良いモデルを構築するカギとなるのかもしれない。

対数変換

 説明変数を対数変換することはよくある。そこで、対数変換をし、データの分布をヒストグラムで描いてみた。ただし、対数をとるだけでは、infになってしまうため、1を足している。

np.log(train['resp']+1).hist(bins=30, color='lightblue', label='log(y)')
train['resp'].hist(bins=30, histtype='step', color='red', label='y')
plt.legend()

対数変換前に比べると、マイナスのばらつきが広がった。また、0近辺のデータが増えている。対数変換により大して変化は見られなかったが、目的変数に用いてみるのも良いかもしれない。ただし、その場合は、予測値を逆変換する必要がある。

プラスとマイナスの割合

プラスとマイナスの割合を見てみる。

plt.pie(train['resp'].apply(lambda x:1 if x>0 else -1).value_counts(),
        labels=['plus', 'minus'], startangle=90, autopct='%1.1f%%')

若干だがプラスのデータの方が多かった。学習データに用いる場合は、ほぼ1:1なので問題はなさそう。

要約統計量

 respと対数変換後のrespの要約統計量を算出してみる。

train['resp'].describe()
np.log(train['resp']+1).describe()
resp
log(resp)

 対数変換による効果はあまりなさそう。

移動平均

 ウィンドウ幅を複数指定して、移動平均の累積和をプロットしてみる。

train['resp'].cumsum().plot(label='resp')
train['resp'].rolling(window=50).mean().cumsum().plot(label='MA_50')
train['resp'].rolling(window=50000).mean().cumsum().plot(label='MA_50000')
train['resp'].rolling(window=100000).mean().cumsum().plot(label='MA_100000')
plt.legend()

ウィンドウ幅として、50, 50000, 100000を指定してみた。結果としては、ウィンドウ幅による差はほとんど見られなかった。また、移動平均の累積和は右上がりとなっていた。50,000~150,000の期間のrespでは、横ばいの傾向が見られたが、移動平均は上昇傾向にある。

 次に各移動平均のヒストグラムを書いてみる。

plt.figure(figsize=(12, 4))
plt.subplot(1, 3, 1)
train['resp'].rolling(window=50).mean().hist(bins=30)
plt.title('window=50')

plt.subplot(1, 3, 2)
train['resp'].rolling(window=50000).mean().hist(bins=30)
plt.title('window=50000')

plt.subplot(1, 3, 3)
train['resp'].rolling(window=100000).mean().hist(bins=30)
plt.title('window=100000')

 中心極限定理に基づくと正規分布に従うはずである。window=50は正規分布に近い形をしているが、他の分布に関しては複数の分布から構成されているように見える。ウィンドウの幅は関係ないようにも思えたが、ちゃんと選ぶ必要があるのかもしれない。

まとめ

 今回はrespの特徴について簡単に調べてみました。あまり意味のないような分析かもしれませんが、今後のモデル開発で何かしら役に立てば幸いです。次回からは、モデル開発に着手してみたいと思います。締め切りまでもう1か月?なので時間がない…。

以上

タイトルとURLをコピーしました