2022.07.07
モンテカルロ法をKubeflowで効率よく計算したい
グループ研究開発本部のT.Yです。最近の関心事として、データサイエンスの諸々の計算タスクにおいてマシンリソースを急遽スケールする必要が生じた場合に備えて柔軟に環境構築するにはどうすればいいかを模索しており、Kubernetes上で機械学習タスクを実行するためのツールキットであるKubeflowに興味を持っています。そこで今回、暗号資産の価格変動をモンテカルロ法でシミュレーションする際にリソースを調整するというユースケースを想定して取り組んでみます。
Summary
-
- Kubernetesのための機械学習ツールキットKubeflowを使うことで、簡単に計算リソースを調整できました。
- GPUを活用し、暗号資産価格をモンテカルロ法でシミュレーションしました。
- 解析に使える暗号資産関連のAPIを調べたのでご紹介します。
Kubeflowとは
KubeflowはKubernetesのためのオープンソースの機械学習ツールキットです。Kubernetesで計算リソースを管理・調整しつつ、Kubeflow上で探索的データ解析、モデルの構築と管理、サービング、リソース管理などができます。Kubeflowの主なコンポーネントは以下の通りです。
Kubeflowのデプロイ方法はいくつかあって、バージョンによって異なりますが、今回はGithubで公開されているManifestファイルを使用し、v1.5.0をインストールしました。Manifestファイルとは、Kubernetes上にリソースを作成する際に各コンポーネントごとにバージョンや環境変数などの詳細な設定値を定義したもので、Kubernetesの環境管理ツールであるKustomizeコマンドの実行時に指定する形で使用します。今回の場合、以下のようなManifestファイルの構成になっており、これらのファイルはRepository内のexampleディレクトリ配下のkustomization.yamlの中で参照されています。
Kubernetesクラスタが構築されている前提で、Kubeflowをデプロイするコマンドを以下に示します。(実行完了までに合計30分ほどかかります。)以下の3行目の実行時に途中でエラーが出る場合、時間をおいてもう一度3行目だけ実行するとデプロイできました。その他のTipsとしてはKubernetesとKustomizeのバージョンに注意する必要があります。
git clone https://github.com/kubeflow/manifests cd manifests | git checkout v1.5.0 kustomize build example | kubectl apply -f -
問題なく環境構築ができれば、KubeflowのCentral Dashboardへのアクセスを、以下のコマンドでlocalhostの8080Portにフォワーディングできます。
export NS=istio-system kubectl port-forward -n ${NS} svc/istio-ingressgateway 8080:80
http://localhost:8080をlistenしてCentral Dashboardにアクセスします。認証情報は、初期設定を変更していなければ”Email”: [email protected], “PW”: 12341234です。
また、別途、Kubernetes自体のDash Boardも作成しておくとリソースの使用状況をWeb UIで確認できるのでおすすめです。Kubernetes Dashboardの構築方法についてはこちらの公式ドキュメントなどをご参照ください。
解析に利用できる暗号資産APIの紹介
- CoinAPI: データの種類や対応している暗号資産銘柄・取引所が豊富です
- CoinGeckoAPI: Freeで使える範囲が広く、非公式ですがPython等のWrapperも公開されています
- CoinMarketCapAPI: 無料で使える範囲はかなり制限されていますが、有料版は豊富なデータにアクセス可能です
- CryptoSlam: バラエティはあまり豊富ではありませんが、NFT関連のデータが取得できます
- Coinpaper.io API: 時価総額上位100位の仮想通貨についてホワイトペーパーや直近のイベント情報が取得できます
分析の観点では、無料でAPIを使用したい場合、ヒストリカルデータを取得できるものがあまりないというのが調査して得た気づきでした。無料プランではヒストリカルデータを提供していないか、または、取得できる期間がかなり限定されているという状況なので、CoinAPIやCoinGeckoAPIは時系列のデータを分析したい場合に重宝します。上記の他にも、Coinpaprica API、NOWNodes、Nomics、Messari、NEWSDATA.IOなどが暗号資産データの分析に使用できます。また、各暗号資産取引所が提供しているAPIも板取引情報や出来高のデータを取得する際に役立つかもしれません。
今回はCoinAPIを使用して過去100日分のBTC/USDのOHLCVデータを取得しました。(事前にAPIキーを取得し、your_api_keyとして定義します。)
url = 'https://rest.coinapi.io/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/latest?period_id=1DAY' headers = {'X-CoinAPI-Key' : your_api_key} response = requests.get(url, headers=headers) ohlcv_df = pd.DataFrame(response.json()).sort_values(['time_period_start'])
Monte Carlo Simulation
Pandas-MonteCarlo
Pandas-MonteCarloという軽量なモジュールを使えば手軽にモンテカルロシミュレーションを試すことが出来ます。(こちらのRepositoryで公開されています。)以下は先ほどのBTC/USDのデータでシミュレーションを実行する際のサンプルコードです。
import pandas_montecarlo from matplotlib import pyplot as plt plt.style.use('seaborn-whitegrid') df['return'] = df['price_close'].pct_change().fillna(0) mc = df['return'].montecarlo(sims=20, bust=-0.3, goal=0) mc.plot(title="BTC Returns Monte Carlo Simulations", figsize=(15, 7))
オプション価格計算アルゴリズムのTensorflow実装
シンプルなBlack-Sholesモデルによるコールオプション価格のシミュレーション計算を実装します。(無リスク金利rやボラティリティσなどの設定は適当な値です。)Tensorflowで実装しておくと、GPU上でTensorの計算が可能な場合、自動でGPUデバイスを認識して計算に使用してくれるので便利です。後ほどシミュレーションを実行する際に計算リソースを調整する前提で、低コストなCPUインスタンスでコーディングしておけば大丈夫です。
from datetime import datetime from numpy import sqrt, maximum from tensorflow import exp from tensorflow.random import normal class MonteCarloSimulator(object): def __init__(self, M, N, T, S0, K, r, sigma): self.T = T self.M = M self.N = N self.delta = 1/M self.S0 = S0 self.K = K self.r = r self.sigma = sigma def calculate_payoff(self): seq = normal((self.M, self.N), 0, 1) S = self.S0 * exp((self.r - 0.5 * self.sigma ** 2) * self.T + self.sigma * sqrt(self.T) * seq) Sm = self.S0 * exp((self.r - 0.5 * self.sigma ** 2) * self.T + self.sigma * sqrt(self.T) * -seq) print(S.device) return maximum(S - self.K, 0), maximum(Sm - self.K, 0) def price_simulation(self): self.start_datetime = datetime.now() payoff, payoff_minus = self.calculate_payoff() price = exp(-self.r*self.T) * (payoff.mean() + payoff_minus.mean()) / 2 self.end_datetime = datetime.now() self.simulation_interval = self.end_datetime - self.start_datetime print(f'N={self.N}, time={self.simulation_interval.total_seconds():.2f}sec, Price: {price:.5f}(Antithetic Variates Method)') return price
なお、少し細かなテクニックですが、分散減少法の一種である対称変量法を実装してモンテカルロ法の収束が早くなる工夫をしています。
CPU NodeとGPU Nodeの速度比較
適当に計算量が必要になるパラメータ設定として実行してみます。GKE(Google Kubernetes Engine)を利用しており、GCPのWeb UIで計算の直前にKubernetesクラスタに必要なサイズのノードプールを追加することで、簡単にリソースをスケールすることが出来ました。非常に高価なA100 GPUインスタンスを使用しているので、計算終了後に即削除しましたが、削除もとても簡単でした。以下はNotebook ServerでCPUとGPUのノートブックを作成した後のダッシュボードのキャプチャになります。
CPU Node
4CPU Core, 40GiB MemoryのVM上で上記のシミュレーションを実行したところ93.36秒かかりました。
GPU Node
上記設定+NVidia A100 GPUのVM上で実行したところ17.91秒かかりました。Notebookが保存されたディスクイメージをマウントして起動することができるので、同じジョブを簡単に実行することが出来ます。
最後に
今回はKubeflow Notebookジョブの計算リソースを調整する例として、暗号資産価格のモンテカルロシミュレーションを実験しました。この記事の計算はシンプルなコードだったため今回は使用しませんでしたが、Kubeflow NotebookのコードからKubeflow Pipelineを自動作成してくれるKALEというJupyterlab extensionもおすすめです。
また、本来、Kubeflowは機械学習モデルの構築やパイプライン管理を行うKubernetes上の機械学習プラットフォームです。Kubeflowのビルドやノートブックサーバーのプロビジョニングに一定の時間がかかるので、計算量によってはGoogle ColabやVertex AIのNotebookインスタンスなどの方が手早く処理できるケースも多数あるでしょう。巨大な深層学習モデルの並列分散処理や、Sparkによるビッグデータ計算など、よりクラスタコンピューティングの本領が発揮されるタスクでKubeflowを活用してみたいと思いました。
グループ研究開発本部 AI研究開発室では、データサイエンティスト/機械学習エンジニアを募集しています。ビッグデータの解析業務などAI研究開発室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ 募集職種一覧 からご応募をお願いします。皆さんのご応募をお待ちしています。
参考
Pythonによるファイナンス 第2版 ―データ駆動型アプローチに向けて (オライリー・ジャパン)
Kubeflow Operations Guide: Managing Cloud and On-Premise Deployment
グループ研究開発本部の最新情報をTwitterで配信中です。ぜひフォローください。
Follow @GMO_RD