風待ち

プログラミングの勉強や日々の出来事のログなど

scikit-learnのテキトーに作ったモデルを読み込んで、Flaskを使ってWebでもアクセスできるようにしてみる。

前に作ったモデルを読み込んで使う。

バッチ処理だけではなんなので、Webアプリに組み込んでみた。

import json

from flask import Flask
from flask import request
from flask import abort

import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.externals import joblib

scaler = joblib.load("foo.scaler")
model = joblib.load("foo.learn")

app = Flask(__name__)


@app.route('/foo', methods=['POST'])
def foo():
    if not request.json:
        abort(400)

    data = pd.DataFrame(request.json)
    for col in data.loc[:, data.dtypes == 'int64']:
        data[col] = data[col].astype(float)

    X = data.loc[:, data.columns].as_matrix()
    X = scaler.transform(X)

    y_predict = model.predict(X)
    return json.dumps(str(y_predict[0]))


if __name__ == "__main__":
    app.run(debug=True, port=5000)

こんなテキトーなものでも動いてるな。

$ curl http://localhost:5000/foo -s -X POST -H "Content-Type: application/json" -d '{"YYYY": ["2018"], "MM": ["08"], "DD": ["05"], "DY": ["0"]}'

試してないけど、jQueryだとこんな感じかな。

$('#btn').click(function() {
  var d = {"YYYY": ["2018"], "MM": ["08"], "DD": ["05"], "DY": ["0"]};
  $.ajax({
    url: 'http://localhost:5000/foo',
    type: 'POST',
    contentType: 'application/json',
    data: JSON.stringify(d),
  }).done(function (data) {
    console.log(JSON.parse(data));
  });
});

バッチ処理だけでは利用用途が限られるのと、未来の予測に必要なデータを作り込むのが大変だけど、こうやってWebで使えるようになると、入力に反応してリアルタイムに使う道が増えるから一気に活用の場所が広がるな。

あと、初めてFlaskを使ったけど、小さいものを作る分にはものすごく楽。

scikit-learnのテキトーに作ったモデルを読み込んで使ってみる。

前に作ったモデルを読み込んで使ってみる。

まずは予測したい列を除いたCSVファイル(「target.csv」って名前にする)を用意する。 前に作った時には「target」カラムがあったけど、今回はそれを予測するためのデータなのでその行はない。

YYYY,MM,DD,DY
2018,1,9,火
2018,1,10,水
2018,1,11,木
2018,1,12,金
2018,1,13,土

作ったモデルを読み込んで、予測したあと、もう一度、CSVを読んで結果を追記して「result.csv」に出力する。

import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.externals import joblib

target_csv_file = "target.csv"

data = pd.read_csv(target_csv_file, encoding="SHIFT-JIS", sep=",")

le = LabelEncoder()
for col in data.loc[:, data.dtypes == 'object']:
    data[col] = le.fit_transform(data[col])

for col in data.loc[:, data.dtypes == 'int32']:
    data[col] = data[col].astype(float)

X = data.loc[:, data.columns].as_matrix()

scaler = joblib.load("foo.scaler")
X = scaler.transform(X)

model = joblib.load("foo.learn")
y_predict = model.predict(X)

data = pd.read_csv(target_csv_file, encoding="SHIFT-JIS", sep=",")
tmp = []
for i in range(len(y_predict)):
    tmp.append(y_predict[i])

data["result"] = tmp

data.to_csv("result.csv", encoding="SHIFT-JIS", sep=",")

CSVで入出力してしまえば、どの程度のデータ量が必要かはおいといてDBから出して加工して入れるっていうこれまでよく作ってきたバッチ処理と同じだから実際のシステムに組み込む場合のイメージがつきやすいな。

テキトーなCSVファイルを用意してscikit-learnをテキトーに使ってみる

機械学習の本を読んでサンプルをいじっているだけでは、わかったつもりになるだけで実際に使えるようにはならないので、本当にテキトーなデータで機械学習してみる。

まず、テキトーなCSVデータ(「train.csv」って名前で保存)を用意する。下のは一部でこんな感じでたくさん用意する。

YYYY,MM,DD,DY,target
2018,1,20,土,2038
2018,1,21,日,2039
2018,1,22,月,2040
2018,1,23,火,2041
2018,1,24,水,2042
2018,1,25,木,2043

このCSVの「target」行を予測するモデルを作ってみる。

import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsRegressor
from sklearn.externals import joblib

train_csv_file = "train.csv"
target_column_name = "target"

data = pd.read_csv(train_csv_file, encoding="SHIFT-JIS", sep=",")

le = LabelEncoder()
for col in data.loc[:, data.dtypes == 'object']:
    data[col] = le.fit_transform(data[col])

for col in data.loc[:, data.dtypes == 'int32']:
    data[col] = data[col].astype(float)

X = data.loc[:, data.columns != target_column_name].as_matrix()
y = data[target_column_name].as_matrix()

scaler = StandardScaler()
scaler.fit(X)
X = scaler.transform(X)

X_train, X_test, y_train, y_test = train_test_split(X, y)

model = KNeighborsRegressor(n_neighbors=5)
model.fit(X_train, y_train)

print("Train score: {:.2f}".format(model.score(X_train, y_train)))
print("Test  score: {:.2f}".format(model.score(X_test, y_test)))

joblib.dump(scaler, "foo.scaler")
joblib.dump(model, "foo.learn")

こんななんの役にも立たないモデルでも一応、動くものを作った方が勉強にはなるだろう。

PandasでシフトJISのCSVファイルを読み込む

Oracle SQL DeveloperでエクスポートしたCSVファイルがシフトJISだったので調べた。

エンコードを指定して読み込めばいいわけね。

import pandas as pd

data = pd.read_csv("train.csv", encoding="SHIFT-JIS", sep=",")

vimを使いだして20年がすぎようとしている頃、emacsを使い始めた。そして、半年後、暗黒面に落ちた。

それを入れた時、最初は軽い気持ちだった。

けれど、 指は確かに覚えていた。

使い慣れた操作は、あのエディタに戻るべきかと思わせた。

しかし、冷静な心が言う。

emacsのエディタ部分以外は、vimよりもいいじゃないか。

今ではもう、ほとんど、emacsから外にでていないだろ?

vim script と emacs lisp を比べて見ろ。もどりたいのか?

そして、決意する。

少数派でもいいじゃないか。

ダークサイドに落ちても、使いたいんだ。

Evil 最高です。

開発者の方に心から感謝します。

init.el

(setq evil-toggle-key "C-`")
(require 'evil)
(setq evil-emacs-state-cursor '("green" box))
(setq evil-motion-state-cursor '("orange" box))
(setq evil-normal-state-cursor '("yellow" box))
(setq evil-visual-state-cursor '("blue" box))
(setq evil-insert-state-cursor '("purple" (bar . 2)))
(setq evil-replace-state-cursor '("red" bar))
(setq evil-operator-state-cursor '("red" bar))
(evil-mode 1)

(global-set-key "\C-z" nil)

(require 'powerline)
(require 'powerline-evil)
(powerline-evil-vim-color-theme)

【emacs自分メモ】emacsで括弧を入力したら閉じ括弧も入力してくれる。コーテーションを入力したら閉じる方も入力してくれる設定

なぜ、半年使ってきて、この設定をしていないかったのか?

なぜ、なんの疑問もなく、毎回、キーを叩いていたのか?

vimの時には真っ先に設定してたのに。

init.el

(electric-pair-mode 1)

【emacs自分メモ】emacsで文字をコピーした時に、OSのクリップボードにも入れる

クリップボードの履歴を残せるようなツールを使っていると、emacsと共有できた方が便利なので。

init.el

(setq x-select-enable-clipboard t)