stylesheet

2018-08-25

HerokuのDocker Deployで機械学習APIを5ステップで作成

HerokuでDockerが使えるようになっていたので、遅まきながら、機械学習を使ったAPIを5ステップで作成してみた。

STEP1: 事前準備

herokuへサインアップし、APPを作成。
また、herokuコマンドとdockerをインストールして使えるようにしておく。

STEP2: サンプルコードを入手

heroku公式のminicondaイメージのサンプルコードがあるので、コレをベースに使用。

$ git clone https://github.com/heroku-examples/python-miniconda.git

ざっと中身を確認すると、

  • python 2.7
  • miniconda環境構築済み (condaコマンドが使える)
  • scikit-learn導入済み
  • webフレームワークはflask
  • gunicornでwsgi
  • ポート番号は環境変数PORTで指定

となっていた。

STEP3: APIを実装

heroku用だろうと特に変わることはないので、いつものようにサクッと実装する。

開発中にライブラリを追加した場合は、Dockerfileへの反映も忘れずに。

pandas等condaで追加するもの -> Dockerfile内のconda installに追記
pipでインストールするもの -> requirements.txt

STEP4: ローカルで動作チェック

Dockerコンテナを起動して動作を確認する。

引数指定がめんどうなので、docker-compose.ymlを作成してdocker-composeを使用することにする。

# docker-compose.yml
version: "2"
services:
  app:
    build: .
    ports:
      - "8100:8100"
    environment:
      PORT: "8100"

コンテナ起動とブラウザで動作チェック。

$ docker-compose up
$ xdg-open http://localhost:8100

STEP5: herokuへデプロイ

ここからがherokuで行う操作となるが、いくつかコマンドを打つだけで本番反映まで行える。素晴らしい。

$ heroku login
Email: nobody@somewhere.com
Password: ********
$ heroku container:login
$ heroku container:push web -a アプリ名
$ heroku container:release web -a アプリ名

以上で完了。

終わり

Heroku の Docker Registry & Runtime (Docker Deploy)は、ほぼストレスフリーで簡単に使用できる完成度の高いプラットフォームと思う。

詰まったところといえば、サンプルコードのREADME.md記載の手順が少し古かったところぐらい。
container-registry用のpluginをインストールするよう書かれていたが、現在は不要。

作ったもの

結局、何を作ったかというとIPO銘柄の初値予想APIを作った。
過去のIPOデータを学習させてRidge回帰で暴騰率を予測させている。スコア的には残念だが、雰囲気はでていると思う。

ブラウザの場合は、http://ipo-cal.herokuapp.comへアクセスするとGUIで試せる。

API本体はhttp://ipo-cal.herokuapp.com/api/predictで公開している。
curlだと以下のように呼び出す。

$ curl -X POST \
  -H "Content-type: application/json" \
  -d '[{"code":"4385", "market":3, "sector":25, "price": 3000.0, "fund":122142.9, "kobo":18159.5, "uri":22554.8}]' \
  http://ipo-cal.herokuapp.com/api/predict

{"data":[{"code":"4385","inflation":189.6046720498996,"price":5700,"rank":3}],"status":"success"}

json文字列をhttp://ipo-cal.herokuapp.com/api/predictへpostするだけでOK。
配列にして一度に50件までまとめて実行できる。

レスポンスはJsendに概ね準拠している。

レスポンスがなかなか返ってこない時は、サーバーがスリープしている。コンテナが起動するまでしばらくかかるので、10秒ほど待機してからリトライしてみて欲しい。