システムトレードの基礎教養としての「教師あり学習」入門

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

はじめに

システムトレードでは、プログラムを使って株式やFXの売買を自動化します。このプログラムに「機械学習」という技術を活用すると、市場のデータを分析し、売買のタイミングを賢く判断できるようになります。
その中でも「教師あり学習」は、最も基本的で重要な方法です。本記事では、初学者の方でもわかるように「教師あり学習」をやさしく解説します。


教師あり学習とは?

教師あり学習」は、機械学習の中でも特に広く使われる方法です。名前にある「教師」という言葉からわかるように、この学習方法には「先生」のような役割を持つデータが必要です。

機械学習についての詳細は下記の記事をご参照ください。

教師あり学習の仕組み

教師あり学習では、「入力データ」と「正解データ」のセットを使ってモデルを訓練します。

※ここでモデルとは、データを基に規則性やパターンを見つけ出し、未知のデータに対する予測や判断を行う仕組みの事を言います。

  • 入力データ: コンピュータに与える情報。たとえば、過去の株価や為替レート。
  • 正解データ: 入力データに対する答え。たとえば、「このデータなら価格は上がる」や「価格は下がる」といった結果。

プログラムは、入力データと正解データを大量に学ぶことで、次に新しいデータが来たときに「どんな結果になりそうか」を予測できるようになります

教師あり学習の具体例

1. システムトレードでの活用例

たとえば、過去の株価データを使って、次の日の価格が上がるか下がるかを予測するモデルを作ります。

入力データ:

  • 昨日までの株価
  • 売買の出来高
  • 為替レート

正解データ:

  • 翌日の株価が「上がった」か「下がった」か

プログラムにこれらのデータを与えて学習させると、新しいデータをもとに「上がる」か「下がる」かを判断できるようになります。

2. 身近な例で考える

教師あり学習は、システムトレードだけでなく、日常生活でも使われています。

  • メールの迷惑メール判定: メール本文を「入力データ」、迷惑メールかどうかを「正解データ」にして、迷惑メールを自動で分類します。
  • 天気予報: 気温や湿度を「入力データ」、実際の天気を「正解データ」にして、未来の天気を予測します。

教師あり学習を使ったモデルの作り方

1. データを集める

教師あり学習には、入力データと正解データのセットが必要です。入力データとは、モデルが規則性を学習するための材料であり、正解データは入力データに対応する「答え」を示します。

たとえば、株価のデータをダウンロードして、売買結果を「上がった」「下がった」でラベル付けします。

ラベルとは、

ラベルは、入力データに対応する正解やカテゴリのことです。たとえば、画像認識では「この画像は猫」「この画像は犬」といったタグがラベルです。モデルは、ラベルを学ぶことで入力データに基づく予測を行えるようになります。ラベルは、答えのヒントを与える役割を果たします。

2. データを分ける

教師あり学習では、集めたデータを「学習用データ」と「テスト用データ」に分ける必要があります。それぞれの役割について詳しく説明します。

学習用データ

これは、モデルを訓練するために使うデータです。モデルがデータの中の規則性やパターンを学ぶための材料となります。たとえば、株価の過去データで「この日は価格が上がった」「この日は価格が下がった」というラベルが付けられたデータを使って、どんな条件のときに価格が上がるのかを学びます。

テスト用データ

これは、学習が終わったモデルの予測精度を確認するために使うデータです。学習用データとは異なるデータを用意し、モデルが初めて見るデータに対して正しい予測ができるかどうかをテストします。

たとえば、モデルが「株価が上がるか下がるか」を予測できるようになったら、過去の別の日のデータを使って「この日は価格が上がると予測した」「実際には上がった」というように予測の正確さを評価します。

具体例

例えば、過去100日分の株価データがあるとします。

  1. 学習用データ: 最初の80日分(80%)を学習用データとして使います。このデータでモデルが「どんな条件で価格が上がったり下がったりするのか」を学習します。
  2. テスト用データ: 残りの20日分(20%)をテスト用データとして使います。このデータでモデルが学んだ内容をもとに、どれくらい正確に価格の動きを予測できるかを評価します。

なぜ分ける必要があるのか?

学習用データだけを使ってモデルの性能を評価すると、モデルはそのデータを覚えてしまい、未知のデータに対して正しい予測ができない場合があります。この状態を「過学習」といいます。

テスト用データを使って評価することで、モデルが本当に新しいデータに対しても正しく予測できるかどうかを確認することができます。

学習用データとテスト用データのイメージ

学習用データは、「試験勉強用の練習問題」のようなものです。テスト用データは、「本番のテスト問題」と考えるとわかりやすいです。本番のテストでは練習問題とは異なる問題が出題されるため、練習問題をしっかり学んで、どれだけ本番で通用するかを試すイメージです。

こうしたデータの分け方をしっかり行うことで、モデルが実際に使える状態になるかを確認できます。

3. モデルを訓練する

モデルを訓練する」とは、学習用データを使ってコンピュータが「データの中の規則や関係性」を学ぶことを指します。この作業を通じて、モデルは入力データと正解データの関係を理解し、新しいデータに対して予測ができるようになります。

モデル訓練の流れ

  1. 学習用データを入力
    過去のデータ(入力データ)とそれに対応する正解データをコンピュータに与えます。たとえば、株価データで「この日は価格が上がった」「この日は下がった」といった情報をセットで提供します。
  2. データのパターンを学ぶ
    コンピュータは与えられたデータを分析し、規則性を見つけようとします。たとえば、「前日の取引量が多いときは価格が上がりやすい」といった関係を自動的に探し出します。
  3. 予測結果を正解と比較
    コンピュータはデータを使って予測を行い、その予測がどれだけ正解データと一致しているかを確認します。たとえば、「この日は価格が上がると予測したが、実際には上がらなかった」という場合、予測が外れていると判断します。
  4. 予測の改善
    コンピュータは、間違いを修正しながら予測を改善していきます。このプロセスを繰り返すことで、モデルの精度が徐々に高まります。

具体例

たとえば、次のような株価データを使ってモデルを訓練するとします。

日付前日の価格変化取引量の変化結果(ラベル)
1月1日上がった増えた上がった
1月2日下がった減った下がった
1月3日上がった減った下がった
1月4日下がった増えた上がった

このデータを使って、次のような学習が行われます。

  • コンピュータは「前日の価格変化」と「取引量の変化」の関係を見つけます。
  • 「前日の価格が上がり、取引量が増えた場合、価格は上がりやすい」という規則性を学びます。
  • 「前日の価格が下がり、取引量が減った場合、価格は下がりやすい」というパターンも発見します。

実際の動き

訓練中、モデルは何度も予測を行い、間違いを修正します。 例えば、「前日の価格が上がったときに価格が下がることもある」といった例外的なケースにも対応できるよう、データを繰り返し見直します。

「モデルの訓練」についてのイメージ

モデルの訓練を「練習問題の反復」に例えるとわかりやすいです。問題を解いて間違えたら、その原因を考え、次は間違えないようにする。こうして練習を重ねることで、本番(新しいデータ)でも正しい答えを出せるようになるのがモデル訓練の目的です。

この訓練の段階が、未来の予測や判断にとって最も重要なステップです。正しく訓練することで、モデルの精度が大きく向上します。

4. テストで精度を確認する

モデルが完成したら、テスト用データを使ってその精度を確認します。この段階では、モデル学習用データ以外の新しいデータに対してどれくらい正確に予測できるかを評価します。

テストの目的

テスト用データを使う理由は、モデルが未知のデータ(学習に使っていないデータ)に対しても正しい予測ができるかを確認するためです。学習用データでのみ高い精度を示していても、未知のデータでは予測が外れることがあります。これを防ぐため、テスト用データで評価を行います。

テストの流れ

  1. テスト用データモデルに入力
    テスト用データには、正解ラベルが付けられています(例: 株価が「上がった」や「下がった」など)。モデルにこのデータを与え、その結果を予測します。
  2. 予測結果と正解を比較
    モデルが出した予測と、正解ラベルを比較してどれくらい一致しているかを確認します。たとえば、20個のデータのうち18個が正解していれば、精度は90%です。
  3. 精度を計算
    正解率や誤差率を計算します。正解率が高ければ高いほど、モデルの性能が良いことを示します。一方、精度が低い場合は、学習が不足しているか、モデルがデータのパターンを正しく捉えられていない可能性があります。

具体例

例えば、株価予測モデルをテストする場合、以下のようなデータを使います。

日付前日の価格変化取引量の変化正解ラベル(実際の結果)モデルの予測
1月5日上がった増えた上がった上がった
1月6日下がった減った下がった下がった
1月7日上がった減った下がった上がった
1月8日下がった増えた上がった上がった

この結果から、以下のように精度を計算します。

  • 正解した件数: 3件(1月5日、1月6日、1月8日)
  • 全体の件数: 4件
  • 正解率: 3 ÷ 4 = 75%

この例では、モデルの精度は75%であると評価できます。

精度を確認する際の注意点

  1. バランスの取れたデータを使う
    テスト用データが偏っていると、評価が不正確になります。たとえば、上昇ばかりのデータで評価すると、モデルの性能を正しく測れない可能性があります。
  2. 過学習を防ぐ
    モデル学習用データを覚えすぎてしまい、新しいデータに対応できない場合があります。テスト用データでの精度を確認することで、こうした問題を検出できます。

イメージしやすい例

モデルのテストを「模擬試験」に例えるとわかりやすいです。練習問題ばかり解いていると、本番の試験問題で困ることがあります。同様に、学習用データモデルが高精度でも、テスト用データでの結果が悪ければ、そのモデルは実際の場面で使えません。

テストを通じてモデルの性能を確認することで、実際の利用シーンでどれだけ信頼できるかを評価できます。テスト結果をもとにモデルを改善することも可能です。

教師あり学習のサンプルコード(Python)

以下は、教師あり学習を使って簡単な線形回帰モデルを作成するコードです。
※線形回帰とは、与えられたデータセットの間に存在する直線的な関係を見つけ出し、将来の値を予測するための統計的手法です。この手法により、データからパターンを学習し、未来の値を推定することができます。
<参照>
非線形回帰分析

# 必要なライブラリをインポートします
import numpy as np  # 数値計算用のライブラリ
from sklearn.model_selection import train_test_split  # データを分割するための関数
from sklearn.linear_model import LinearRegression  # 線形回帰モデル
from sklearn.metrics import mean_squared_error  # モデルの誤差を計算するための関数

# データを作成します
# 例えば、x が勉強時間、y がテストの点数であるとします
# x: 勉強時間 (入力データ)
# y: テストの点数 (正解データ)
x = np.array([[1], [2], [3], [4], [5]])  # 1次元の入力データ
y = np.array([50, 55, 60, 65, 70])  # 正解データ(出力)

# データを訓練用とテスト用に分割します
# 訓練用データ: モデルを学習させるためのデータ
# テスト用データ: モデルの性能を確認するためのデータ
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)

# 線形回帰モデルを作成します
model = LinearRegression()  # 線形回帰のモデルをインスタンス化

# モデルを訓練(学習)します
# fit メソッドは、入力データ (x_train) と正解データ (y_train) を使ってモデルを学習させます
model.fit(x_train, y_train)

# 学習したモデルを使ってテストデータの予測を行います
# predict メソッドは、与えられた入力データ (x_test) から予測値を出力します
y_pred = model.predict(x_test)

# モデルの性能を評価します
# 平均二乗誤差 (Mean Squared Error, MSE) を計算します
# この値が小さいほど、モデルの予測精度が高いことを意味します
mse = mean_squared_error(y_test, y_pred)

# 結果を表示します
print("テストデータの実際の値:", y_test)  # 実際の正解データ
print("テストデータの予測値:", y_pred)  # モデルが予測した値
print("モデルの誤差 (MSE):", mse)  # モデルの予測精度

コードの解説

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

import

import は、Pythonで他のモジュールやライブラリを利用する際に使います。

モジュールとは、特定の機能をまとめたPythonファイルで、ライブラリは複数のモジュールが集まったものです。

モジュール内に定義された関数クラス変数などを、現在のスクリプトに取り込む役割を果たします。

例:import numpy

これで numpy ライブラリ全体を取り込み、numpy を使った処理が可能になります。

from … import …

from は、特定のモジュールから一部の関数クラスを直接取り込むときに使います。
これにより、モジュール全体ではなく、必要な部分だけを効率的に利用できます。

例:from sklearn.model_selection import train_test_split
  • sklearn.model_selection モジュールから train_test_split という関数だけを取り込んでいます。
as

as は、インポートしたモジュールや関数に別名(エイリアス)をつけるために使います。これにより、スクリプト内での名前の衝突を避けたり、名前を短くして記述を簡略化できます。

例:import numpy as np
  • numpy モジュールを np という短い名前で利用できるようにしています。
  • 以降は numpy.array の代わりに np.array と記述できます。

以下のように記述することで、必要な部分を簡潔に取り込み、使いやすく名前を調整できます。

# 必要なライブラリをインポートします
import numpy as np  # 数値計算用のライブラリ
from sklearn.model_selection import train_test_split  # データを分割するための関数
from sklearn.linear_model import LinearRegression  # 線形回帰モデル
from sklearn.metrics import mean_squared_error  # モデルの誤差を計算するための関数

これにより、コードが読みやすく、保守性も向上します。

データの作成

ここでは、x を勉強時間、y をテストの点数として扱いました。

x は2次元配列(縦に並んだ1次元データ)として定義しています。

y は1次元配列で、対応するテストの点数を格納しています。

np.array の役割

np.array は、NumPy ライブラリが提供する「配列」を扱うためのデータ構造です。Pythonのリストに似ていますが、数値計算に特化しており、大量のデータを効率的に処理できます。

サンプルコードでは、以下のように np.array を使用して、データを配列として管理しています。

  • x = np.array([[1], [2], [3], [4], [5]])
    縦に並んだ2次元配列を作成しています。1次元リストを直接使わない理由は、機械学習のデータが通常、行と列を持つ「行列」として扱われるからです。ここでは「勉強時間」を表しています。
  • y = np.array([50, 55, 60, 65, 70])
    1次元配列として「テストの点数」を表しています。

重要なポイント

  • np.array にリストを渡すことで配列が作られます。
  • x は2次元配列にし、行列の形を明示的にしています。これにより、データを「縦に並べた形式」で扱うことができます。
  • y は1次元の配列として、シンプルに数値を保持しています。

この形式にすることで、機械学習モデルが扱いやすい形でデータを準備しています。

データの分割

サンプルコードでは、train_test_split という関数を使って、データを訓練用(80%)とテスト用(20%)に分けています。この分割作業は、機械学習モデルを適切に評価するためにとても重要です。


train_test_split の役割

train_test_split は、データを次の2つの目的のために分ける関数です。

  1. 訓練用データ(train data): モデルを学習させるためのデータ。
  2. テスト用データ(test data): モデルが新しいデータにどれだけ正確に予測できるかを評価するためのデータ。

この関数は、データをランダムにシャッフルしてから分割します。


引数の説明

train_test_split を呼び出す際に、次の引数を指定します。

  1. x: 入力データ(勉強時間などの特徴データ)
    • ここでは x配列np.array([[1], [2], [3], [4], [5]]))を渡しています。
  2. y: 出力データ(テストの点数などの正解データ)
    • ここでは y配列np.array([50, 55, 60, 65, 70]))を渡しています。
  3. test_size=0.2: テストデータの割合を指定
    • 0.2 とすることで、全体の20%をテスト用データに割り当て、残り80%を訓練用データにします。
  4. random_state=42: ランダムな分割を固定するための乱数シード
    • データの分割は通常ランダムに行われますが、この値を固定することで、実行するたびに同じ分割結果を得られるようにしています(再現性を保つため)。

戻り値の説明

train_test_split戻り値は次の4つです。

  1. x_train: 訓練用データの入力部分(勉強時間)。
  2. x_test: テスト用データの入力部分(勉強時間)。
  3. y_train: 訓練用データの出力部分(テストの点数)。
  4. y_test: テスト用データの出力部分(テストの点数)。

これらは、それぞれ別々の変数に格納して、モデルの学習と評価に使います。


なぜ分割するのか?

機械学習モデルは、学習したデータに対しては高い精度を出すことが多いですが、まったく新しいデータに対してはうまく動かない場合があります。このため、テストデータを別に用意し、「学習していないデータに対する精度」を確認する必要があります。これを「汎化性能」と呼びます。

train_test_split を使うことで、この分割作業を簡単に実現しています。

モデルの作成と学習

サンプルコードでは、LinearRegression クラスを使ってモデルを作成し、データを使ってモデルに学習させます。


LinearRegression の役割

LinearRegression は、NumPy配列を使った線形回帰モデルを作成するためのクラスです。線形回帰とは、データの関係を直線(または平面)で表現することで、予測を行う方法です。


fit メソッドの説明

fit メソッドは、モデルを訓練(学習)するためのメソッドです。訓練データ(x_train)と、それに対応する正解データ(y_train)を渡すことで、モデルがデータのパターンを学習します。

  • x_train: 学習に使う入力データ(例えば勉強時間)。
  • y_train: 入力データに対応する正解データ(例えばテストの点数)。

予測と性能評価

predict メソッドの説明

predict メソッドは、学習済みモデルを使って新しいデータ(テストデータ)に基づく予測を計算します。

  • x_test: 学習には使用しなかったテスト用の入力データ。
  • y_pred: predict メソッドが出力する予測値。

predict(x_test) によって、例えば「勉強時間を与えたときに、テストの点数がどうなるか」を予測できます。


mean_squared_error の説明

mean_squared_error は、モデルが予測した値(y_pred)と、実際の正解値(y_test)の誤差を測定します。この誤差を「平均二乗誤差(MSE)」と呼び、次のような特徴があります。

  • 値が小さいほど、モデルが正確に予測していることを示します。
  • 計算方法は、「予測値と正解値の差」を2乗して、その平均を取るものです。

出力結果

  • y_test: テストデータにおける実際の正解値。
  • y_pred: モデルが予測した値。

テストデータの実際の値(y_test)と予測値(y_pred)を比較することで、モデルがどれくらい正確に予測できているかを確認します。また、MSE(平均二乗誤差)の値を使い、予測精度を数値として判断します。

教師あり学習を活用する際の注意点

1. データの質が重要

モデルの精度はデータの質に大きく左右されます。間違ったデータや偏りのあるデータを使うと、モデルも正確に学べません。

2. 過学習を防ぐ

「過学習」とは、モデルが学習データにあまりにも詳しくなりすぎて、新しいデータに対応できなくなることです。これを防ぐには、学習データとテストデータをしっかり分けることが重要です。

3. 必ずしも未来を完全に予測できるわけではない

株価や為替レートの動きには偶然性も含まれるため、100%正確に予測することはできません。教師あり学習は、あくまで「可能性」を判断するためのツールです。

まとめ: 教師あり学習をシステムトレードにどう活かすか

教師あり学習」を使えば、システムトレードでの売買判断を高度化できます。しかし、技術を使いこなすには、データの集め方やモデルの訓練方法を正しく理解する必要があります。
まずはPythonなどで簡単な教師あり学習モデルを作り、少しずつ実践してみるのがよいでしょう。

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