2021年4月春研修


2021年春研修

今回研修で作成するシステム



雛形の説明

今回はまずは修正せずにheroku環境を構築し、動作確認後、各自のテーマに従い修正する

NO 作成するもの 言語 内容
1 AI分析API Python Pythonのflaskを使用したAPI。
モデルを入れ替えるだけで基本的に修正なし
雛形「syslink-ai-api」
2 学習済モデル Python Scikit-learn 各自が機械学習のモデルを作成し、dumpで保存。
現在は4つの変数を入力に分類を返すモデルが上記1に格納されている
3 分析表示 RailsまたはJQuery 雛形「syslink-test-api」「jquery」

HEROKU開発環境

(1)HerokuCLIをインストールします(windows)

https://devcenter.heroku.com/articles/heroku-cli

(2)Gitをインストールします(windows)

https://git-scm.com/downloads

(3)macの場合、以下のサイトからheroku toolbeltをインストール

https://devcenter.heroku.com/articles/heroku-command-line
$brew tap heroku/brew && brew install heroku 

HEROKUのユーザ登録

(1)jp.heroku.comに移動し、新規登録ボタンをクリックします

(2)登録情報を入力し、無料アカウント作成ボタンをクリックします

(3)メールが送信されたことを示す画面が表示されます

(4)登録したメールアドレスにメールが届いているので確認します

(5)メールのURLをクリックします

(6)パスワードの設定画面が表示されるので、入力し、パスワードを設定しログインするボタンをクリックします

(7)完了画面が表示されるので、ここをクリックして次に進んでくださいボタンをクリックします

(8)ユーザ登録が完了し、HEROKU画面が表示されます

HEROKUのアプリ登録

※クライアントからHEROKUアプリを構築する方法もありますが、今回はHEROKUサーバー側で空プロジェクトを作ってクローンし、そのプロジェクトを反映する手順を取ります

(1)トップ画面からダッシュボードをクリックします

(2)Newボタンをクリックし、Create New Appボタンをクリックします。

(3)作成したいアプリ名を入力し、Create Appボタンをクリックします アプリ名はHeroku全体で一意であることが必要になりますので、他のアプリとは重複しない名前にします

(4)ダッシュボードに作成したアプリ名が表示すれば、アプリ作成は完了です

(5)Windowsで空のフォルダを作成します

(6)コマンドプロンプトを開いて、作成したディレクトリへ移動します

(7)herokuへのログインします

(8)git cloneコマンドの実行します

(9)完了後

(10)作成したフォルダにプロジェクトが追加されます

資産反映手順

APIの反映手順

(0)雛形syslink-ai-apiの内容を上記でcloneして作成されたフォルダにコピーします

(1)コマンドプロンプトを開いて、プロジェクトのディレクトリへ移動します

注意

①requirement.txtのscikit-learnのバージョンは取ってください
誤)scikit-learn == 0.20.3

正)scikit-learn

②cloneした資産にひな形をコピーするとき、

ひな形の.gitディレクトリーは上かぶせしないでください。

(2)git add .コマンドを入力し、変更情報を追加します

(3)git commitコマンドを入力し、コミット処理を行います

(4)git push heroku masterコマンドを入力します

(5)Herokuへの資産反映完了

(6)コマンドプロンプトからcurlコマンドで動作確認を行います

curl https://(アプリ名).herokuapp.com/predict -X POST -H "Content-Type:application/json" -d "{\"feature\":[1, 1, 1, 1]}"

(7)エラーになる場合は、herokuのログを確認します

コンソールからの確認することも可能です

$ heroku logs --tail -a (アプリ名)

Railsの反映手順

(1)雛形syslink-test-apiの内容を上記でcloneして作成されたフォルダにコピーします※APIとRailsは別のアプリとしてwebのherokuで作成します

(2)Herokuのスタックが20になり、ひな形のRubyのバージョンは対象外なので、スタックのバージョンを18に下げてください

heroku stack:set heroku-18 -a [アプリ名]

※上記以外はAPIと同じ手順で反映します(git add > git commit > git push)

サーバの変更情報を取り込む方法

(1)git pullコマンドを入力し、変更情報を取り込みます

$ git pull heroku master

PythonAPIサンプルの説明(syslink-ai-api.zip)

app.py

from joblib import dump, load
import flask
import numpy as np
from flask_cors import CORS 

# initialize our Flask application and pre-trained model
app = flask.Flask(__name__)
CORS(app)
model = None

# 学習済モデルの読み込み
def load_model():
    global model
    print(" * Loading pre-trained model ...")
    model = load("sample-model.pkl")
    print(' * Loading end')

# 接続確認テスト用 getでrootにアクセスしたときに、Hello Worldを表示させる
@app.route('/')
def index():
    return 'Hello World!'

# 機械学習結果返却処理
@app.route("/predict", methods=["POST"])
def predict():
    model = load("sample-model.pkl")
    response = {
        "success": False,
        "Content-Type": "application/json"
    }
    # ensure an feature was properly uploaded to our endpoint
    if flask.request.method == "POST":
        if flask.request.get_json().get("feature"):
            # read feature from json
            feature = flask.request.get_json().get("feature")

            # preprocess for classification
            # list  -> np.ndarray
            feature = np.array(feature).reshape((1, -1))

            # classify the input feature
            response["prediction"] = model.predict(feature).tolist()

            # indicate that the request was a success
            response["success"] = True
    # return the data dictionary as a JSON response
    return flask.jsonify(response)


if __name__ == "__main__":
    load_model()
    print(" * Flask starting server...")
    app.run(host='0.0.0.0', port='8000')

PythonAPIサンプルの説明2(syslink-ai-api.zip)

requirements.txt

pythonで使用するライブラリを指定する(必要に応じてバージョンを指定)

flask
gunicorn
numpy
pandas
scipy
seaborn
scikit-learn
flask-cors
joblib

クライアントの説明

以下のいずれかでクライアントを作成してください

注意)Herokuの無料枠はしばらく使っていないとスリープするので、クライアントの初回実行はちょっと時間がかかります

Railsクライアントサンプルの説明(syslink-test-api.zip)

Controller

require 'json'
require 'net/https'
require "uri"

class ApiTestController < ApplicationController
  def index
    data={feature: [10, 20, 5, 1]}
    uri = URI.parse("http://syslink-ai-api.herokuapp.com/predict")
    http = Net::HTTP.new(uri.host, uri.port)
    req = Net::HTTP::Post.new(uri.path)
    req.set_content_type("application/json")
    req.body = data.to_json

    res = http.request(req)

    p res.code
    #if res.code == Net::HTTPSuccess
    if res.code == "200"
      res_data = JSON.parse(res.body)
      @prediction = res_data["prediction"]
    end
  end
end

View

<div class="container">
    <!-- 表題 -->
    <div class="content-title">
        <h3><span class="title-style"><label>AI分析結果</label></span></h3>
    </div>
    <div class="well">
        <h2>AI分析結果</h2>
        <h1>あなたの評価は<%= @prediction %>です</h1>
    </div>
</div>

JQueryクライアントサンプルの説明(jquery.zip)

main.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title></title>
</head>
<body>
<p><input type="text" id="input1" value="0.74"></p>
<p><input type="text" id="input2" value="1.22"></p>
<p><input type="text" id="input3" value="1.22"></p>
<p><input type="text" id="input4" value="1.22"></p>
<button id="button">ボタン</button>
<p>結果:<span id="answer"></span></p>

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="main.js"></script>
</body>
</html>

main.js

$(function(){
var url = 'http://syslink-ai-api.herokuapp.com/predict';
    $('#button').on('click', function() {
        var arays = []
        arays.push(parseFloat($('#input1').val()));
        arays.push(parseFloat($('#input2').val()));
        arays.push(parseFloat($('#input3').val()));
        arays.push(parseFloat($('#input4').val()));
        console.log(arays);

        // API連携
        $.ajax({
          type: 'POST',               // 使用するHTTPメソッド
          url : url,                  // 通信先URL
          dataType: 'json',           // レスポンスのデータタイプ
          contentType: "application/json",
          data: JSON.stringify({feature: arays}),
          traditional: true
        })
        .done(function(data, textStatus, jqXHR) {
          console.log(data.prediction[0]);
          $('#answer').text(data.prediction[0]);
        })
        .fail(function(jqXHR, textStatus, errorThrown) {
          console.log('通信が失敗しました');
        });
    
    });
});

Vue.jsクライアントサンプルの説明(vuejs.zip)

main.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title></title>
</head>
<body>
<div id="app">
    <p><input type="text" id="input1" value="10"></p>
    <p><input type="text" id="input2" value="20"></p>
    <p><input type="text" id="input3" value="5"></p>
    <p><input type="text" id="input4" value="1"></p>
    <button v-on:click="showData">ボタン</button>
    <p>結果:<span id="answer"></span></p>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://jp.vuejs.org/js/vue.js"></script>
<script src="main.js"></script>
</body>
</html>

main.js

var app = new Vue({
    el: '#app',
    data: {
      message: ''
    },
    methods: {
        showData: function() {
            var url = 'http://syslink-ai-api.herokuapp.com/predict';
            var arays = []
            arays.push(parseFloat($('#input1').val()));
            arays.push(parseFloat($('#input2').val()));
            arays.push(parseFloat($('#input3').val()));
            arays.push(parseFloat($('#input4').val()));
            console.log(arays);

            // API連携
            $.ajax({
                type: 'POST',               // 使用するHTTPメソッド
                url : url,                  // 通信先URL
                dataType: 'json',           // レスポンスのデータタイプ
                contentType: "application/json",
                data: JSON.stringify({feature: arays}),
                traditional: true
            })
            .done(function(data, textStatus, jqXHR) {
                console.log(data.prediction[0]);
                $('#answer').text(data.prediction[0]);
            })
            .fail(function(jqXHR, textStatus, errorThrown) {
                console.log('通信が失敗しました');
            })
        }
    }
});

サンプルが動いたら1

サンプルを以下の機械学習モデルに入れ替えてみましょう(家賃を予測するモデル)

#家賃を予測する
import numpy as np
from sklearn import linear_model
#1次元目は面積 2次元目は階
X = np.array([
    [7, 7.12, 7.2, 7.69, 7.79, 8, 8.28, 8.37, 8.7, 9.93, 10.5, 10.53, 11, 12.19, 12.4],
    [2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 3, 3, 1]
]).T
#家賃(千円単位)
Y = np.array([
    [45, 51, 52, 53, 52.6, 52, 54, 54.2, 56, 64, 65, 72, 75, 78.3, 80]
]).T

model = linear_model.LinearRegression(fit_intercept=False)
model.fit(X, Y)

#面積8m² で3階にある部屋の家賃は?=>[[51.32707814]]
print(model.predict([[8, 3]]))

サンプルが動いたら2

各自で独自のモデルを作って、それに合わせてアプリも作成してください

例)プロ野球分析システム ※Teamsにソースをアップしています

https://sys-link-baseball.herokuapp.com/

ログインID及びパスワードはTeamsで連絡します



学習済モデルのdump方法例

アヤメのデータの例 学習したモデルを保存するには、学習したモデルをdumpします

from sklearn import svm
from sklearn import datasets
from joblib import dump, load

# classifier
clf = svm.SVC()

iris = datasets.load_iris()

X, y = iris.data, iris.target
clf.fit(X, y)

dump(clf, 'sample-model.pkl')