機械学習を利用したシステムトレード構築におけるデータの前処理について

Python

システムトレードは、コンピュータが自動で取引を行い利益を目指す手法です。
機械学習を活用してシステムトレードを行う際には、大量のデータを正しく使うことが重要です。ですが、生のデータをそのまま使うと、うまく学習できなかったり、正確な予測ができなかったりすることがあります。
そのため「データの前処理」という工程が欠かせません。この記事では、機械学習に適したデータの前処理方法を、中学生でもわかるように解説します。

スポンサーリンク
スポンサーリンク

データの前処理とは何か

データの前処理とは、分析や学習に適した形にデータを整える作業のことです。生のデータには「欠けている値」や「極端な値」などの問題が含まれることがあります。そのまま使うと予測精度が下がったり、学習の妨げになるため、適切な処理が必要です。

データの前処理の目的は、データを「使いやすく」「正確に」することです。これにより、機械学習が正しく学習できるようになり、システムトレードの精度も向上します。

データの前処理の主な手法

システムトレードに使うデータを前処理する際には、いくつかの基本的な方法があります。それぞれの手法について詳しく見ていきましょう。

1. 欠損値の処理

データが部分的に欠けていることを「欠損」と呼びます。例えば、株価データの中に、特定の日だけ取引量のデータが抜けている場合があります。そのような欠損値をそのままにすると、学習の妨げになるため、何らかの方法で対処する必要があります。

欠損値処理の方法

  • 平均値で埋める:欠けているデータを、他の日の平均値で補います。
  • 前後のデータで埋める:直前や直後のデータを利用して欠損を埋めます。
  • 欠損データを削除する:欠損が多い場合は、そのデータごと取り除くこともあります。

2. 異常値(外れ値)の処理

異常値は、他のデータから大きく離れた値のことです。例えば、ある日の株価だけ極端に高くなっている場合、それが異常値かどうかを確認する必要があります。異常値があると、分析結果が大きくずれてしまうことがあるため、適切に処理します。

異常値処理の方法

  • 削除する:異常値が明らかに間違いであるとわかる場合、そのデータを削除します。
  • 他の値に置き換える:平均値や中央値で異常値を置き換える方法もあります。

3. データのスケーリング(標準化と正規化)

データのスケーリングは、データの値を一定の範囲にそろえる処理です。株価や出来高など、数値の範囲が大きく異なるデータをそのまま使うと、機械学習が一部の特徴に偏りやすくなるため、範囲をそろえます。

  • 標準化:データの平均を0、標準偏差を1にします。これにより、データが同じスケールで扱われるようになります。
  • 正規化:データの最小値を0、最大値を1にそろえる方法です。データが0から1の範囲に収まるため、計算がしやすくなります。

4. カテゴリデータの変換

カテゴリデータとは、「値上がり」や「値下がり」のように、数値ではなく種類を表すデータです。このままでは機械学習で扱えないため、数値に変換する必要があります。

カテゴリデータの変換方法

  • ワンホットエンコーディング:カテゴリごとに「0」か「1」を割り当てる方法です。例えば、「値上がり」を1、「値下がり」を0として扱います。

データの前処理の具体例

次に、これまで説明した前処理を使って、株価データの処理を行う例を紹介します。

データの前処理例

ここでは、Pythonを使って株価データを前処理するコードを紹介します。

# 必要なライブラリをインポート
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler, MinMaxScaler

# ダミーデータの作成(実際のデータでは株価や出来高のデータを使用)
data = pd.DataFrame({
    'price': [100, 102, np.nan, 105, 107, 108, 250, 110, 115, 120],  # 一部に欠損値や異常値が含まれる
    'volume': [2000, 2100, 2150, 2200, 2300, 2400, 2500, 2450, 2600, 2700]
})

# 欠損値を前後の値で補完
data['price'].fillna(method='ffill', inplace=True)

# 異常値を平均値に置き換え
mean_price = data['price'].mean()
data['price'] = np.where(data['price'] > 200, mean_price, data['price'])

# データのスケーリング(標準化)
scaler = StandardScaler()
data[['price', 'volume']] = scaler.fit_transform(data[['price', 'volume']])

# 結果を表示
print(data)

コードの解説

以下は、上記コードの各部分について解説したものです


必要なライブラリをインポート

まず、このコードを動かすために、numpytensorflow.kerasのライブラリをインポートしています。ライブラリとは、便利な関数クラス(特定の機能を持つコードのまとまり)を集めたもので、これをインポートすることで、すぐに使えるようになります。

import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import SimpleRNN, Dense

ここで、numpyはデータの配列(複数のデータを一まとめにして扱える形式)を操作するために使います。tensorflow.kerasは、機械学習用のライブラリで、この中のSequentialSimpleRNNDenseというクラス関数を使って、データの学習と予測を行います。


ダミーデータの準備

data = np.array([100, 102, 101, 105, 107, 108, 110, 115, 120, 125, 130, 128, 129, 133, 135, 138, 140, 145, 150, 155])

ここでは、実際のデータの代わりにdataという名前のダミーデータ(例となるデータ)を作成しています。このデータは、過去の株価終値が順番に並んでいると考えます。np.arrayは、リストを「配列」として扱えるようにするためのものです。配列を使うと、たくさんのデータをまとめて処理できます。


データの変換

X = np.array([data[i:i+5] for i in range(len(data) - 6)])
y = data[6:]

機械学習で使うデータは、学習に適した形に変換する必要があります。Xは入力データ、yは予測したい目標データです。

  1. Xでは、data配列の中から、5つずつ連続したデータを取り出して、新たな配列として保存します。
  • for i in range(len(data) - 6)という部分は、iを0からlen(data) - 6まで動かすという意味です。
  • data[i:i+5]は、dataから連続した5つのデータを取り出す部分です。
  1. yには、5日間のデータの次の日の値が入るようにしています。このようにして、機械学習モデルに「過去5日分のデータから次の日の株価を予測させる」という形になります。

モデルの作成

model = Sequential()
model.add(SimpleRNN(10, activation='relu', input_shape=(5, 1)))
model.add(Dense(1))

ここでは、Sequentialというクラスを使って、予測のためのモデルを作成しています。Sequential()は、モデルの「入れ物」を作るためのクラスです。

SimpleRNN(10, activation='relu', input_shape=(5, 1))は、RNN(リカレントニューラルネットワーク)というタイプの層を作成します。

  • 10は、この層の中にある「ニューロン」(情報を処理する部分)の数です。
  • activation='relu'は、活性化関数の種類を指定しています。活性化関数とは、次に送る値の範囲を調整するための関数で、reluは一般的に使われる方法です。

活性化関数についての詳細は下記の記事をご参照ください。

  • input_shape=(5, 1)は、入力データの形を指定します。5つの値を1つの配列として扱う形になります。

model.add(Dense(1))は、最終的に1つの値を出力する層(出力層)を追加しています。Denseとは、全てのニューロンが次の層のすべてのニューロンとつながっている「密結合層」のことです。


モデルのコンパイル

model.compile(optimizer='adam', loss='mse')

ここでは、model.compileメソッドを使って、学習に使う方法を設定しています。

  • optimizer='adam'は、最適化手法の指定です。adamは学習を効率よく進めるための方法です。
  • loss='mse'は、損失関数を指定します。損失関数は、予測の結果がどれだけ正しいかを評価するためのもので、mseは「平均二乗誤差」といって、予測値と正解の値の差が大きいほど損失が大きくなる方法です。

モデルの学習

model.fit(X.reshape(-1, 5, 1), y, epochs=100)

ここで、model.fitメソッドを使って、モデルを学習させます。

  • X.reshape(-1, 5, 1)は、入力データXの形を変更して、RNNに適した形にしています。-1はデータの個数に自動で合わせ、5, 1は「5日分のデータを1つの配列として扱う」という意味です。
  • yは目標データで、予測したい次の日の株価のデータです。
  • epochs=100は、学習を100回繰り返すという設定です。学習回数を増やすほどモデルは多くのパターンを覚えますが、増やしすぎると逆に精度が下がることもあります。

次の日の株価を予測

next_day_prediction = model.predict(X[-1].reshape(1, 5, 1))
print("予測される次の日の株価:", next_day_prediction)

最後に、model.predictメソッドを使って、次の日の株価を予測します。

  • X[-1].reshape(1, 5, 1)は、最新の5日間のデータをRNNに適した形に変換しています。X[-1]Xの最後のデータを取り出す方法です。
  • model.predictは、入力データをもとにモデルが予測した結果を返します。
  • print関数を使って、予測された次の日の株価を表示します。

データの前処理を行う際の注意点

データの前処理は予測精度を高めるために重要ですが、いくつかの注意点があります。

  • 過度な処理を避ける:データを処理しすぎると、逆に重要な特徴を失ってしまうことがあります。例えば、異常値でも相場の特徴を表している場合は、そのまま扱うこともあります。
  • 目的に合った処理を行う:たとえば、価格のスケーリングは標準化が適している場合もあれば、正規化が適している場合もあります。目的に合わせた手法を選ぶことが重要です。
  • データの順序を確認する時系列データ(時間の流れに沿ったデータ)は、データの順序が重要です。前処理の際も順序を崩さないように気をつけます。

まとめ

機械学習を使ったシステムトレードでは、データの前処理が非常に重要な役割を果たします。前処理を正しく行うことで、データが「使いやすく」「正確」になり、予測精度が向上します。欠損値や異常値の処理、スケーリングやカテゴリデータの変換など、目的に応じた適切前処理を行い、機械学習がより正確に学習できるデータを整えましょう。システムトレードでのデータ分析をより効果的にするため、前処理の重要性を理解し、実践に役立ててください。

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