Webアプリ開発、scikit-learnモデルの保存と読み込み

scikit-learnのモデルを読み込んで、活かせるようなプログラムに変更しました。

ちょっと実用的な感じが出てきていいね

本プログラムはあらかじめpipなどで環境にscikit-learnを入れておく必要があります。前回の記事の続きとなりますので、こちらもご参考ください。

ぱんだクリップ
flaskでWebアプリ開発、シンプルにscikit-learnと合体 | ぱんだクリップ flaskの基本を学んだので、ちょっとWebアプリ的な何かを作ってみたいです。 初めてのWebアプリケーションだね flaskのクイックスタートでとても基本的な部分を学んできまし...

こんな人の役に立つかも

・flaskのシンプルなアプリチュートリアルを探している人

・flaskのみのチュートリアルだといまいち実用性がつかめない人

・flaskでWebアプリを作りたい人

目次

訓練モデルの保存プログラム

まずは、訓練したモデルをpickleというPythonのモジュールで保存します。

Python documentation
pickle --- Python オブジェクトの直列化 ソースコード: Lib/pickle.py pickle モジュールは Python オブジェクトの直列化および直列化されたオブジェクトの復元のためのバイナリプロトコルを実装しています。"Pick...

※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アプリを作るときは、モデル訓練するためのマシンなど別の環境でモデル構築をした方が効率的ですね。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次