得屋(FP2級 × AIエンジニアのブログ)

FP資格を持つAIエンジニアならではの、お得情報をお届けします

MENU

株価予想AIの作り方 Tips データ準備の効率化方法

f:id:mycrofton:20201014161555j:plain

目次

はじめに

本記事では、株価を予想するAI(人工知能)の作り方を紹介しています。

前回までの記事で、作り方について一通り紹介しましたので、今回からは、AIを作る上で役立つ情報を Tips として発信していきたいと思います。

役立つ情報のその2は、データ準備の効率化についてです。

その1では、AI学習時間の短縮について紹介しているので合わせて参照ください。

なお、対象としている方は、AIやプログラムに馴染みのない方を想定しています。詳しい方にとっては、説明に正確性を欠くと感じる部分もあるかと思いますが、なるべく平易な書き方にしたいと考えたためですので、ご容赦ください。

データ準備の効率化はなぜ必要?

実際にAIのためのデータ(ローソク足チャート画像)を準備したことがある方は感じていることだと思いますが、データを準備するのはとても時間がかかります。

たとえば、ローソク足チャート画像を数千の銘柄について10年間ほどのデータを使って用意しようとすると、その数は数百万画像になります。ローソク足チャート画像の作り方について過去記事で紹介したプログラムでは、パソコンの性能にもよりますが、簡単に月単位の時間がかかってしまうことがあります。

お試しでAIを作ってみる分には、大量のデータを必要としないかもしれませんが、本格的にAIを作ってみたい場合、データを準備する時間がかかるのは大きな問題になります。

そこで今回は、データの準備、具体的には、ローソク足チャート画像の作成処理時間を短縮する方法を紹介します。

処理を並列化することで高速化する

処理時間の短縮のために、順番に行っていた処理を並列化します。並列化とは、処理を同時に実行することです。

具体例で説明します。たとえば、複数銘柄(銘柄Aと銘柄B)のローソク足チャート画像を作る処理があった場合、銘柄Aのローソク足チャート画像を作り終わってから、銘柄Bのローソク足チャート画像を作っていたのが、過去記事で紹介したプログラムです。一方、処理の並列化では、銘柄Aのローソク足チャート画像を作る処理と銘柄Bのローソク足チャート画像を作る処理を同時に実行します。

同時に実行すると何故処理が速くなるのかについては、少し難しい話になるので割愛しますが、興味のある方はWeb検索等で調べてみてください。

プログラムを修正する

それでは、さっそく処理を並列化するためにプログラムを修正しましょう。以下のコードが修正されたコードです。

import pandas as pd
import mplfinance as mpf
from joblib import Parallel, delayed import io # 指定されたcsvファイルを読み込み def load_csv(code): return pd.read_csv('./data/csv/' + str(code) + '.csv', index_col=0, parse_dates=True) # 指定された株価データを使ってローソク足チャート(+移動平均線+出来高)を生成 def draw_chart(code): data_range = 50 #チャートにする営業日の範囲(50営業日) data = load_csv(code) data_num = len(data) create_num = data_num - data_range - 5 #5営業日後が存在するか確認するため if create_num <= 0: #5営業日後が存在しない場合はチャートを作らない return for i in range(create_num): # 指定範囲の翌営業日の株価が5営業日後に上昇しているか判定 open_value = data.iat[i+data_range, 0] #チャートの範囲はi~i+data_range-1なので翌営業日はi+data_range close_value = data.iat[i+data_range+4, 3] #5営業日後はi+data_range+4 ch_rate = close_value / open_value # 上昇or下落で格納するフォルダを分離 if ch_rate > 1.05: #5%上昇する場合は上昇と判定 filename = './data/chart/up/' + str(code) + '_' + str(i) + '.png' else: filename = './data/chart/down/' + str(code) + '_' + str(i) + '.png' mpf.plot(data[i:i+data_range], type='candle', volume=True, mav=(5, 25), savefig=filename) # main def main(): codes = [
1301, 1332] Parallel(n_jobs=-1)([delayed(draw_chart)(codes[index])for index in range(len(codes))]) if __name__ == '__main__': main()

ほどんど変わっていませんが、2点ほど変更されています。

1点目は、プログラム冒頭の

import pandas as pd
import mplfinance as mpf
import io

が、以下のように変更(from joblib import Parallel, delayed が追加)されています。この変更は、処理を並列化するための前準備になります。

import pandas as pd
import mplfinance as mpf
from joblib import Parallel, delayed import io

2点目は、プログラム終盤の

    for index in range(len(codes)):
        draw_chart(codes[index])

が、以下のように変更されています。この変更が実際に処理を並列で実行するための指示になります。

Parallel(n_jobs=-1)([delayed(draw_chart)(codes[index])for index in range(len(codes))])

プログラムを実行するために前準備をする

プログラムの修正は終わりましたが、並列化の仕組みを利用するために、前準備が必要になります。

コマンドプロンプトを起動して、『pip install joblib』と入力します。

並列化に必要な追加情報がインストールされます。少し時間がかかるかもしれませんが、コマンドプロンプトに文字が入力できるようになるまで待ってください。

f:id:mycrofton:20201015165042j:plain

プログラムを実行する

前準備が終わったら、さっそくプログラムを実行してみましょう。

python xxxxx.py』と入力します。(xxxxx.py)はプログラムのファイル名です。プログラムファイルの作り方などは、過去記事に記載していますので、忘れてしまった、分からない、という方は過去記事を参照してください。

実行結果として作成されるファイルは以前のものと変わらないので説明はしません。

処理時間を比べてみた

プログラムを実行してみて、以前のプログラムよりも早く終了することを実感できたのではないでしょうか。

体感だけでは、どのくらい速くなったのかわからないので、私の環境で処理速度を測ってみました。

処理対象は2銘柄で、作成するローソク足チャート画像の数は、2322枚です。

処理速度の計測結果は、以下の通りで、今回紹介の並列化したプログラムが約2倍速くなっています。

プログラム 処理時間 [秒]
旧プログラム(並列化していないもの) 1366.4
変更後のプログラム(並列化したもの) 678.6

かなり効果があることが、この結果からもわかると思います。ただし、高速化の効果については、お使いのパソコンの性能によっても変わってくる可能性があるので、ご了承ください。

注意事項

紹介した並列化を使ったプログラムを動作させると、その他のパソコンの操作が遅くなる可能性があります。

パソコンを使って何か作業を行いたい時に、今回ご紹介したプログラムを動かすと、作業に支障をきたす可能性があるので注意してください。

ちなみに、並列化したプログラムを動かすと、パソコンのパワーが無駄なく使われるため、ほかのことを処理する余力がなくなります。ほかのことを処理する余力がないため、結果としてその他のパソコン操作が遅くなってしまうということが発生します。

まとめ

並列化を使ったデータ準備(ローソク足チャート画像の作成)プログラムの高速化について紹介しました。

処理の高速化、処理時間の短縮についての1つのアプローチとしての紹介になります。

ただ、2銘柄を対象としたローソク足チャート画像の作成にも関わらず、私の環境では10分以上かかっており、決して速いとは言えないかもしれません。

数千におよぶ東証の銘柄についてデータを揃えようとすると、今回紹介した工夫をしても、かなりの時間がかかってしまうことになります。

もう少し工夫をしたくなると思います。実は、私の環境では、ある工夫をして、この問題を回避しています。問題回避の方法については別の機会にまとめたいと思いますので、楽しみにしてください。