記事作成年月日等:2023年(令和5年)6月4日(日)
要 旨
今回はflaskを使用したUSDJPY1時間足予測AIWebアプリをデプロイする方法について記述します。
実行環境等
VPS:KAGOYAクラウド KVM CPU 1コア、メモリ1GB、ストレージ25GB
料金:20円/1日、550円/月(2023年(令和5年)6月4日(日)時点)
OS:Ubuntu22.04LTS
操作端末:iMac
実行要領
KAGOYAクラウドは、sshキーを使用してログインするのでrootで実施した。
サーバーにログインして、アップデートする。
1 |
apt update |
flask_usdjpy_transformers_appフォルダの作成
1 |
mkdir flask_usdjpy_transformers_app |
作成したflask_usdjpy_transformers_appフォルダへ移動する。
1 |
cd flask_usdjpy_transformers_app |
仮想環境virtualenvをインストールする。
1 |
apt -y install python3.10-venv |
1 |
python3 -m venv .venv |
インストールしたvirtualenvをアクティベートする。
1 |
source .venv/bin/activate |
ファイルを、sftpを使用して以下のように配置する。
flask_usdjpy_transformers_app
--- templatesフォルダ--- base.html, index.html, result.html
--- app.py
--- gunicorn.conf.py
--- requirements.txt
--- start.sh
各ファイルの内容は、以下のとおり。
base.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>USDJPY_H1_predict app</title> <link rel="icon" type="image/x-icon" href="https://sample.com/favicon/favicon.ico"> </head> <body> <h1>USDJPY1時間足予測(Transformers)アプリ</h1> <h2>概要及び注意事項</h2> <p>当アプリでは、USDJPYの1時間足を直近のデータ量に基づき上昇するか、下落するかを過去データ(yfinance)によりTransformersモデルを使用して予測します。</p> <p>ただし本結果により投資にいかなる損失が生じても、当アプリでは責任を取りません。</p> </p>あくまで参考程度にご利用ください。</p> <p>なお時刻はUTC(日本時間マイナス9時間)の表示となります。</p> <table> <tr> <td><form method="post" action="{{ url_for('result') }}"> <input type="submit" value="予測開始"> </form></td> <td><form method="post" action="{{ url_for('reset') }}"> <input type="submit" value="リセット"> </form></td> </tr> </table> {% block content %} {% endblock %} </body> </html> |
index.html
1 2 3 4 |
{% extends 'base.html' %} {% block content %} {% endblock %} |
result.html
1 2 3 4 5 6 7 8 9 10 11 |
{% extends "base.html" %} {% block content %} <h3>予測結果</h3> {{ predict_datetime }}</br> {{ predicted_result }}</br> {{ accuracy }}</br> {{ delay_time }} {% endblock %} |
app.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
from flask import Flask, render_template, request app = Flask(__name__) @app.route('/') def index(): return render_template('index.html') @app.route('/result', methods=['POST']) def result(): # "予測開始"ボタンをクリックしたら処理する if request.method=='POST': import time t1 = time.time() import numpy as np import csv import math import pandas as pd import yfinance as yf from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression # 外為データ取得 tks = 'USDJPY=X' data = yf.download(tickers = tks , # 通貨ペア period = '1y', # データ取得期間 15m,1d,1mo,3mo,1y,10y,20y,30y 1996年10月30日からデータがある。 interval = '1h', # データ表示間隔 1m,2m,5m,15m,30m,60m,90m,1h,1d,5d,1wk,1mo,3mo ) #最後の日時を取り出す。 lastdatetime = data.index[-1] #Close価格のみを取り出す。 data_close = data['Close'] #対数表示に変換する ln_fx_price = [] for line in data_close: ln_fx_price.append(math.log(line)) count_s = len(ln_fx_price) # 為替の上昇率を算出、おおよそ-1.0-1.0の範囲に収まるように調整 modified_data = [] for i in range(1, count_s): modified_data.append(float(ln_fx_price[i] - ln_fx_price[i-1])*1000) count_m = len(modified_data) # 前日までの4連続の上昇率のデータ successive_data = [] # 正解値 価格上昇: 1 価格下落: 0 answers = [] for i in range(4, count_m): successive_data.append([modified_data[i-4], modified_data[i-3], modified_data[i-2], modified_data[i-1]]) if modified_data[i] > 0: answers.append(1) else: answers.append(0) # print (successive_data) # print (answers) # データ数 n = len(successive_data) # print (n) m = len(answers) # print (m) # pipeline(transformers)モデル clf = Pipeline([ ('scaler', StandardScaler()), ('clf', LogisticRegression())]) # サポートベクターマシーンによる訓練 (データの75%を訓練に使用) clf.fit(successive_data[:int(n*750/1000)], answers[:int(n*750/1000)]) # テスト用データ # 正解 expected = answers[int(-n*250/1000):] # 予測 predicted = clf.predict(successive_data[int(-n*250/1000):]) predict_datetime=f'{lastdatetime}の次の1時間足の予測' # 末尾の10個を比較 #print ('正解:' + str(expected[-10:])) #print ('予測:' + str(list(predicted[-10:]))) # 正解率の計算 correct = 0.0 wrong = 0.0 for i in range(int(n*250/1000)): if expected[i] == predicted[i]: correct += 1 else: wrong += 1 #print('正解数: ' + str(int(correct))) #print('不正解数: ' + str(int(wrong))) successive_data.append([modified_data[count_m-4], modified_data[count_m-3], modified_data[count_m-2], modified_data[count_m-1]]) predicted = clf.predict(successive_data[-1:]) #print ('次の1時間足の予測:' + str(list(predicted)) + ' 1:陽線, 0:陰線') if str(list(predicted)) == str([1]): predicted_result='上昇するでしょう。' else: predicted_result='下落するでしょう。' accuracy="正解率: " + str(round(correct / (correct+wrong) * 100, 2)) + "%" t2 = time.time() elapsed_time = t2- t1 elapsed_time = round(elapsed_time, 2) delay_time='プログラム処理時間: ' + str(elapsed_time) + '秒' return render_template('result.html', predict_datetime=predict_datetime, predicted_result=predicted_result, accuracy=accuracy, delay_time=delay_time) @app.route('/reset', methods=['POST']) def reset(): # "予測開始"ボタンをクリックしたら処理する if request.method=='POST': return render_template('index.html') if __name__ == "__main__": app.run(debug=False) |
gunicorn.conf.py
1 2 3 |
bind='0.0.0.0:8000' workers=4 timeout=120 |
requirements.txt
1 2 3 4 |
yfinance scikit_learn flask gunicorn |
start.sh
1 |
gunicorn --daemon -c gunicorn.conf.py -w 4 -b 0.0.0.0 'app:app' |
requirements.txtによりpip installを実施する。
1 |
pip install -r requirements.txt |
start.shファイルに実行権限を付与する。
1 |
chmod +x start.sh |
アプリを起動させる。
1 |
./start.sh |
http://[IPアドレス]:8000で表示を確認する。
SSLの設定
apache2のインストール
1 |
apt -y install apache2 |
以下に種々の設定ファイルが作成されるが、現時点では修正の必要はない。後ほど修正・追記する。
/etc/apache2/
snapのインストール
Ubuntu22.04LTSにはプリインストールされているので不要。
snapのアップデート
1 |
snap refresh |
既にインストールされているcertbot-autoの削除。
まずdnfをインストールする。
1 |
apt -y install dnf |
削除する。
1 |
dnf remove certbot |
Certbotのインストール
1 |
snap install --classic certbot |
Certbotコマンドの準備。
1 |
ln -s /snap/bin/certbot /usr/bin/certbot |
apache2を起動する。
1 |
systemctl start apache2 |
apache2の自動起動設定を実施する。
1 |
systemctl enable apache2 |
apache2の状態確認
1 |
systemctl status apache2 |
apache2の自動起動状態の確認
1 |
systemctl is-enabled apache2 |
ブラウザでhttp://[IPアドレス]でapache2のデフォルトページが表示されるのを確認する。
python3-certbot-apacheのインストール
1 |
apt -y install python3-certbot-apache |
1 |
certbot --apache |
これで指示に従って入力していく。
プロキシを有効にする。
1 |
a2enmod proxy |
1 |
a2enmod proxy_http |
apache2を再起動する。
1 |
systemctl restart apache2 |
システムファイルの編集
1 |
vi /etc/apache2/sites-available/000-default-le-ssl.conf |
以下を追記する
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<Virtual Host *:443> #追記する ProxyPass / http://localhost:8000/ ProxyPassReverse / http://localhost:8000/ ProxyPass /result http://localhost:8000/result ProxyPassReverse /result http://localhost:8000/result ProxyPass /reset http://localhost:8000/reset ProxyPassReverse /reset http://localhost:8000/reset </Virtual Host> |
gunicornを一旦停止させる。
1 |
ps aux | grep gunicorn |
プロセス番号を確認して、停止させる。
1 |
kill [プロセス番号] |
gunicornを起動させる。
1 |
./start.sh |
apache2を再起動する。
1 |
systemctl restart apache2 |
ブラウザでアクセスする。
https://[ドメイン名]
正常に表示されれば完成。
結 言
今回はflaskを使用したUSDJPY1時間足予測AIWebアプリのデプロイ方法について記述しました。
最後までお読みくださり、ありがとうございました。