こんにちは。システムトレーダーの卵こと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()


対数変換による効果はあまりなさそう。
移動平均
ウィンドウ幅を複数指定して、移動平均の累積和をプロットしてみる。
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か月?なので時間がない…。
以上