
教えてChatGPT 日経平均株価を予測するAIモデルに最適な構造について
ChatGPTに日経平均株価を予測するAIモデルの最適な構造について質問してみました
前回は、ChatGPTに学習および評価データに関する質問を行いました。
詳細は、下記の記事を参照ください。
今回は、教えてもらった学習および評価データに最適なAIモデルの構造について、ChatGPTに聞いてみることにしました。
ChatGPTへの質問内容(プロンプト)
ChatGPTに入力したプロンプトの内容は、以下の通りです。
■作成したいAIの定義
翌営業日の日経平均株価が陽線か陰線かを推測するニューラルネットワーク構造のAIモデルを作成したい
■説明変数の定義
説明変数は、下記の情報により構成されるデータとする
- 日経平均株価(始値、高値、安値、終値)
- 単純移動平均(5日、25日、75日)
- ボリンジャーバンド(±2σ、±σ、20日SMA)
- MACD(MACDおよびMACDシグナル)
- RSI
- S&P500(始値、高値、安値、終値)
- NASDAQ(始値、高値、安値、終値)
- VIX指数(始値、高値、安値、終値)
また、各データは、カテゴリ毎に標準化処理が実施されている
■目的変数の定義
翌営業日の日経平均株価が陰線なら0, 翌営業日の日経平均株価が陽線なら1
■学習データおよび評価データ
学習データの期間は2015年1月1日から2023年12月31日の9年間とする
評価データの期間は2024年1月1日から2024年12月31日の1年間とする
■現状の問題点
中間層として、3層のDenseを使用したニューラルネットワーク構造のAIモデルを評価しているが、Training Errorは減少するものの、Validation Errorが増加してしまう問題に遭遇している。
上述の課題を解決するAIモデルとして、中間層の構造をどうすれば良いか教えて欲しい。
また、その構造において、各レイヤーのパラメータの詳細についても教えて欲しい。
これに対するChatGPTの回答(一部抜粋)は、以下となります。
Validation Errorの増加(過学習)は、ニューラルネットワーク設計でよく見られる問題です。これを解決するために、以下のアプローチを提案します。特に金融時系列データに特化した構造で考えます。
1. LSTM(Long Short-Term Memory)層の導入
金融データは時系列情報を含むため、LSTMやGRUなどのRNNアーキテクチャが有効です。単純なDense層では時間的な依存関係が学習できません。
(中略)
2. 各層の詳細設定
LSTM層
・ユニット数: 64(64〜128程度が一般的)
・活性化関数: デフォルト(tanh)
・Recurrent Activation: デフォルト(sigmoid)
・Return sequences: False
・初期化方法: Glorot Uniform
Dropout
・ドロップ率: 0.2〜0.5(過学習を抑制)
Dense層
・1つ目のDense層: 32ユニット、活性化関数ReLU
・出力層: 1ユニット、活性化関数Sigmoid(バイナリ分類のため)
その他の設定
・損失関数: binary_crossentropy
・オプティマイザ: Adam(learning_rate=0.001)
・エポック数: 50〜100
・バッチサイズ: 32〜128
・Early Stopping: patience=10で適用
さらに、下記のサンプルコードも提示されました。
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.regularizers import l2
model = Sequential([
LSTM(64, input_shape=(timesteps, features), kernel_regularizer=l2(0.01)),
Dropout(0.2),
Dense(32, activation='relu', kernel_regularizer=l2(0.01)),
Dropout(0.2),
Dense(1, activation='sigmoid')
])
model.compile(optimizer=Adam(learning_rate=0.001),
loss='binary_crossentropy',
metrics=['accuracy'])
model.summary()
これには大変驚きました。
(;゚Д゚) ソコマデデキルノ?
これはもう、試す以外の選択肢はありません。
しかし、Neural Network Consoleで上記の構造をどうやって実現するのか、さっぱり分かりませんでした。
このため、Keras環境で上記のAIモデルを評価することにしました。
ChatGPTが提示したAIモデルの構造を評価するPythonプログラム
ChatGPTが提示したAIモデルの構造を評価するPythonプログラムを下記に示します。
import numpy as np
import pandas as pd
import argparse
import time
import matplotlib.pyplot as plt
import os
import keras
from keras import regularizers, optimizers
from keras.layers import Dense, LSTM, Dropout
from keras.callbacks import ModelCheckpoint
from sklearn.metrics import confusion_matrix, classification_report
# Data format converter
# Label: 'x' or 'y'
# Data: Neural Network Console training/validation data(DataFrame形式)
def DataFormatConv(Label, Data):
# Labelで指定された文字を含む列を抽出
OutData = Data.filter(like = Label, axis = 'columns')
# DataFrameをndarrayに変換
OutData = OutData.to_numpy()
return OutData
def main():
# 下記のエラー対応
# OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5 already initialized.
os.environ["KMP_DUPLICATE_LIB_OK"] = 'TRUE'
# 下記のメッセージ対応
# This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2
os.environ["TF_CPP_MIN_LOG_LEVEL"] = '2'
# コマンドライン引数の処理
parser = argparse.ArgumentParser(description = '2 Affine neural network training and validation program')
parser.add_argument('--e', type = int, default = 10, help = 'Number of Epoch(Default: 10)')
parser.add_argument('--b', type = int, default = 64, help = 'Batch size(Default: 64)')
parser.add_argument('--t', required = True, default = 'training.csv', help = 'Training data file name(Default: training.csv)')
parser.add_argument('--v', required = True, default = 'validation.csv', help = 'Validation data file name(Default: validation.csv)')
parser.add_argument('--m', default = 'Best_model.h5', help = 'Minimum val_loss model name(Default: Best_model.h5)')
parser.add_argument('--o', default = 'Result_model_validation.csv', help = 'File name for best model evaluation results(Default: Result_model_validation.csv)')
args = parser.parse_args()
print('Training data: ', args.t)
print('Validation data: ', args.v)
# csvファイルのデータをDataFrameに入力
TrainData = pd.read_csv(args.t, encoding = 'utf-8')
ValidData = pd.read_csv(args.v, encoding = 'utf-8')
# 学習データをKeras用に成形
TrainDataX = DataFormatConv('x', TrainData)
TrainDataY = DataFormatConv('y', TrainData)
# 評価データをKeras用に成形
ValidDataX = DataFormatConv('x', ValidData)
ValidDataY = DataFormatConv('y', ValidData)
# ニューラルネットワークを構築
TestNN = keras.models.Sequential()
TestNN.add(LSTM(64, input_shape = (28, 1), kernel_regularizer = regularizers.l2(0.01))) # 28個の1次元データ
TestNN.add(Dropout(0.2))
TestNN.add(Dense(32, activation = 'relu', kernel_regularizer = regularizers.l2(0.01)))
TestNN.add(Dropout(0.2))
TestNN.add(Dense(1, activation = 'sigmoid'))
TestNN.summary()
# 学習プロセスの設定
TestNN.compile(loss = 'binary_crossentropy', optimizer = optimizers.Adam(learning_rate = 0.001), metrics = ['accuracy']) # 損失関数
# 学習時間の計測開始
FitTimeStart = time.perf_counter()
# コールバックの設定
CheckPointPath = args.m
CallBack = ModelCheckpoint(filepath = CheckPointPath, monitor = 'val_accuracy', verbose = 1, save_best_only = True, mode = 'max', save_weights_only = False, save_freq = 'epoch')
# AIモデルの学習
Epochs = args.e
BatchSize = args.b
History = TestNN.fit(x = TrainDataX, y = TrainDataY, batch_size = BatchSize, epochs = Epochs, validation_data = (ValidDataX, ValidDataY), shuffle = True, callbacks = [CallBack])
# 学習時間の計測終了
FitTimeEnd = time.perf_counter()
# 学習時間
print()
print('学習時間: ', '{:.2f}'.format(FitTimeEnd - FitTimeStart), '[s]\n')
# 保存されたHDF5形式のベストモデルを読み込み
ValidModel = keras.models.load_model(CheckPointPath)
# ベストモデルを評価
Result = ValidModel(ValidDataX)
# EagerTensorをDataFrame形式に変換
TmpResult = pd.DataFrame(Result)
# ベストモデルの評価結果をファイルに保存
TmpResult.to_csv(args.o, index = False)
print('Validation results: ', args.o, '\n')
# 混同行列、等を表示
ResultInt = (0.5 <= Result).numpy().astype('int32') # Numpy化
MyConfusionM = pd.DataFrame(confusion_matrix(ValidDataY, ResultInt), index = ['y=0', 'y=1'], columns = ['y\'=0', 'y\'=1']) # 混同行列の作成 + ラベル名の追加
print('混同行列\n', MyConfusionM, '\n')
print('その他指標\n', classification_report(ValidDataY, ResultInt, digits = 3), '\n')
# グラフ表示
plt.plot(range(1, Epochs + 1), History.history['loss'], label = 'Loss')
plt.plot(range(1, Epochs + 1), History.history['val_loss'], label = 'Val Los')
plt.plot(range(1, Epochs + 1), History.history['val_accuracy'], label = 'Val Acc')
plt.xlabel('Epochs')
plt.legend()
plt.grid(axis = 'x', which = 'major')
plt.grid(axis = 'y', which = 'both')
plt.show()
if __name__ == '__main__':
main()
上記のPythonプログラムをfilename.pyに保存した場合の実行方法は、下記の通りです。
> python filename.py --t training.csv --v validation.csv --e 100
training.csvはNeural Network Console向けの学習データ、validation.csvはNeural Network Console向けの評価データです。
具体的には、前回の記事で作成したデータとなります。
また、--eオプションではEpochを指定します。
ChatGPTが提示したAIモデルの構造に対する評価結果
以下は、学習曲線です。

各線の意味
Loss: おそらくAIモデルの学習時の損失(COSTと等価?)
Val Los: AIモデルの評価時の損失(VALIDATION ERRORと等価?)
Val Acc: AIモデルの評価時の予測精度
続いて、混同行列を以下に示します。

予測精度は、53.5%でした。
とりあえず動かすことができました。
ちなみに、Pythonプログラムの実行時間は33.67 [s]でした。
問題発生!! ソースコードのムダについて
後は、色々なAIモデルの構造を試してみようと思ったのですが、一つ、問題が発生しました。
それは、Pythonプログラムのソースコードにムダが生じるというものです。
どういうことかと言いますと、色々なAIモデルの構造を試す場合、上記のPythonプログラムにおいて、修正すべきは下記の部分のみです。
TestNN.add(LSTM(64, input_shape = (28, 1), kernel_regularizer = regularizers.l2(0.01))) # 28個の1次元データ
TestNN.add(Dropout(0.2))
TestNN.add(Dense(32, activation = 'relu', kernel_regularizer = regularizers.l2(0.01)))
TestNN.add(Dropout(0.2))
TestNN.add(Dense(1, activation = 'sigmoid'))
それ以外のソースコードは、全く同じで変える必要がありません。
つまり、中身がほとんど同じPythonプログラムのファイルが大量に発生することになります。
これはムダです。
また、変えなくて良いソースコードを誤って修正してしまうリスクもあります。
可能であれば、以下のようなことがやりたいです。
AIモデルの構造を記述したファイルと、その他のソースコードを記述したファイルを別々に用意する
検証するAIモデル毎にAIモデルの構造を記述したファイルを用意する
AIモデルの構造を記述したファイルとその他のソースコードを記述したファイルを組み合わせて検証を行う
どうすれば期待通りのことがができるのか、ちょっと考えたいと思います。