scikit-learnのモデルを読み込んで、活かせるようなプログラムに変更しました。
ちょっと実用的な感じが出てきていいね
本プログラムはあらかじめpipなどで環境にscikit-learnを入れておく必要があります。前回の記事の続きとなりますので、こちらもご参考ください。
こんな人の役に立つかも
・flaskのシンプルなアプリチュートリアルを探している人
・flaskのみのチュートリアルだといまいち実用性がつかめない人
・flaskでWebアプリを作りたい人
訓練モデルの保存プログラム
まずは、訓練したモデルをpickleというPythonのモジュールで保存します。
※pickelはPythonのモジュール。データを直列化(単なるデータの並びのようなもの)することで、データの保存、読み込みができるようになります。
次のプログラムを「application.py」として保存し、ブラウザで「localhost:5000」にアクセスして実行すると、同じ階層内に「my_k_neighbors」というファイルが保存されます。
本当は、この処理をflaskでやる必要がないのですが、今回はflaskの勉強ということで、訓練したモデルデータを作成する部分もWebアプリに実装してみました。
使いたがりです。
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import pickle
import numpy as np
from flask import Flask, flash, redirect, render_template, request, url_for
app = Flask(__name__)
@app.route('/')
def index():
#ほんとはここでデータを読み込みたくないけれどとりあえず
panda_box = load_iris()
X = panda_box.data
y = panda_box.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.5, stratify=y)
#k-最近傍法のオブジェクトの宣言
knc = KNeighborsClassifier(n_neighbors = 1)
#学習
knc.fit(X_train, y_train)
#pickelで分類器のデータを出力
pickle.dump(knc, open('my_k_neighbors', 'wb'))
return "<div>分類器モデル出力</div>"
アヤメのデータをscikit-learnから読み込み、訓練用データとテストデータに分割しています。そして、k最近傍法を訓練して、pickleでデータを保存しています。
※今回のアヤメデータの分割は流れで行なっています。厳密に訓練とテストデータを利用する場合、同じテストデータが後のプログラムでも利用できるように保存などしておくべきなのかな、とも思いました。
このプログラムで、次のようにアプリのルート階層に無事出力された模様です。
モデルは「static」フォルダとかにおいた方が良いかもしれない。
モデルを読み込んで利用するプログラム
ここに訓練済みのk最近傍法のデータができたので、次からはモデルの訓練をせず、このデータをロードするように「application.py」を変更します。
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import pickle
import numpy as np
from flask import Flask, flash, redirect, render_template, request, url_for
app = Flask(__name__)
@app.route('/')
def index():
#ほんとはここでデータを読み込みたくないけれどとりあえず
panda_box = load_iris()
#アヤメのデータとラベルを変数Xとyに格納
X = panda_box.data
y = panda_box.target
#アヤメのデータ、ラベルを訓練用、テスト用に分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.5, stratify=y)
#★変更点★分類器モデルの読み込み←fitをせず、pickleで読み込む
knc = pickle.load(open('my_k_neighbors', 'rb'))
#X_test[0]をnumpyの形にする。predictするためにnumpyに。
test_data = np.array([X_test[0]])
#データの予測(predict)
kotae = str(knc.predict(test_data))
#アヤメの種類を文字で表示するように
if kotae == "[0]":
kotae = "setosa"
elif kotae == "[1]":
kotae = "versicolor"
elif kotae == "[2]":
kotae = "virginica"
#文字列を結合して変数をHTMLに埋め込みました。
return "<div>アヤメの種類</div><div>" + kotae + "</div>"
前回のプログラムの訓練部分をそのままpickleでモデル読み込みのプログラムに変更しています。
これで、このプログラムで訓練を行わなくてよくなりました。モデルのロードのタイミングはアクセスしたとき毎回なのですが、とりあえず今回は置き換えるのみとします。
機械学習系のWebアプリを作るときは、モデル訓練するためのマシンなど別の環境でモデル構築をした方が効率的ですね。