こんにちは、荒井(@yutakarai)です。
僕が最初に機械学習に学びはじめた当初、誰かが書いて公開したソースコードをそのまま写して動かす、ということを繰り返していました。
誰かが書いたソースコードをそのまま写す「写経」から学べることも大きいです。しかし、そこで自己満足していては先へ進めないということに気づきました。
今回は、コードの写経だけで終わらないために、簡単な機械学習WEBシステムを作る方法を説明します。
まずは、データセットを手にいれる
機械学習プロジェクトは、良いデータセットを見つけることが大切です。
データセットの質が低かったり小さすぎる場合、正確な予測を行うことはできません。
KaggleやUCI Machine Learning Repositoryなどで良いデータセットを見つけることができます。
今回この記事では、ワイン品質のデータセットを利用してみます。
特徴として、pH、密度、酸性度などがあり、ラベルカラムとしてワイン品質(0から10の間でスコア)があります。
1 – fixed acidity(固定酸度)
2 – volatile acidity(揮発性酸度)
3 – citric acid(クエン酸)
4 – residual sugar(残糖)
5 – chlorides(塩化物)
6 – free sulfur dioxide(二酸化硫黄)
7 – total sulfur dioxide(総二酸化硫黄)
8 – density(密度)
9 – pH(pH値)
10 – sulphates(硫酸塩)
11 – alcohol(アルコール)
Output variable (based on sensory data):
12 – quality (score between 0 and 10)(ワイン品質)
このデータセットを扱うためにpandasというライブラリを利用します。
pandasは、データ解析についての便利な機能を提供しているライブラリです。
まず、データセットをpandasにロードし、ラベル(label)と特徴(features)に分割します。
ラベルとして「品質」を取得し、そしてその他のすべての特徴を取得します。
import pandas as pd #ワインデータをPandasにロード df = pd.read_csv('winequality-red.csv', delimiter=";") #qualityカラムを取得 label = df['quality'] #quality以外の全てのカラムを取得 features = df.drop('quality', axis=1)
モデルをトレーニングする
機械学習は、ラベルとその特徴との間の関係を見つけることによって機能します。
モデルにデータセットを与え、モデルはそれぞれの特徴がラベルにどのように影響するかを学習します。このプロセスを、モデルのトレーニング(学習)と呼びます。
シンプルな機械学習のためにScikit-learnライブラリを利用します。
今回のワインのデータセットには、線形回帰モデルを使います。
線形回帰は、データ分析の中でも非常に単純なモデルです。
データセットを通って一番良い直線の直線を描こうとするモデルです。(詳しい解説は専門書を参照するかググってみてください)
モデルはfit関数を通して回帰データを得ます。予測機能によって偽ワインの特徴を渡すことでモデルを利用できます。
例として下のコードでは、偽ワインの特徴(適当な特徴の数値)をモデルに渡しています。
モデルはトレーニングに基づいて答えを出力します。
import pandas as pd import numpy as np from sklearn import linear_model #データをロードし、labelとfeaturesそれぞれを取得 df = pd.read_csv('winequality-red.csv', delimiter=";") label = df['quality'] features = df.drop('quality', axis=1) #線形回帰モデルを作成し、ワインデータを使って学習をする regr = linear_model.LinearRegression() regr.fit(features, label) #学習済みモデルを使って偽ワインを推測する #各数字は、pH、酸性度などの特徴を表す print regr.predict([[6.3,1.65,0,2.3,0.062,23,30,0.8876,4.63,0.59,8.2]]).tolist()
機械学習モデルの保存とロード
PythonのPickleライブラリを利用すると、学習済みのモデルをファイルに簡単にシリアライズできます。
モデルを保存しておくと、プログラム内でモデルを読み込んでそのまま使うことができます。
これにより、モデルをトレーニングするコードと、モデルを展開するコードとを分けておくことができます。
Pickleについては以下記事に書きましたのでご参照ください。
以下のコードでは、一度保存したモデルを他のプログラムでロードして使用しています。
import pickle #モデルを定義し、トレーニング regr = linear_model.LinearRegression() regr.fit(features, label) #モデルをシリアライズしファイル名「winemodel.pkl」で保存 pickle.dump(regr, open("winemodel.pkl","wb")) #「winemodel.pkl」で保存されたモデルを読み込み model = pickle.load(open("winemodel.pkl","r"))
機械学習モデルを組み込むWEBシステムを準備する
機械学習モデルをWEB上で使うためには、WEBシステムを準備する必要があります。
WEBシステムは、送られたリクエストに対して紐づけられた処理を実行します。
そして、実行した結果をレスポンスとしてリクエスト元へ送り返します。
Flaskは、手軽にWEBシステムを作成することができるPythonのフレームワークです。
以下のコードでは、Flaskを利用してシンプルなWEBシステムを実行します。
動きは単純です。
ひとつPOSTリクエストを待ち受け、リクエスとを受けたらレスポンスを返します。
POSTリクエストによって、JSONオブジェクトが渡されます。
from flask import Flask from flask import request #ウェブシステム初期化 app = flask.Flask(__name__) #POSTリクエストを受け取るhelloルートを定義 @app.route('/hello', methods=['POST']) def index(): #grabs the data tagged as 'name' name = request.get_json()['name'] #レスポンスを返す return "ようこそ!" + name + "さん"
サーバーにモデルを配置する
pickleライブラリを利用して、学習済みモデルをWEBシステムにロードすることができます。
これでこのWEBシステムは初期化の際、学習済みモデルをロードするようになりました。
「/predict」へリクエストを送ることによってモデルを利用できます。
リクエストを受け取ったシステムは、JSON情報を取得し、モデルに渡します。
レスポンスとして、モデルの予測結果が返されます。
import pickle import flask app = flask.Flask(__name__) #学習済みモデルをロード model = pickle.load(open("winemodel.pkl","r")) @app.route('/predict', methods=['POST']) def predict(): #リクエストに含まれている、ワインの特徴情報(features)を取得 feature_array = request.get_json()['feature_array'] #モデルにワインの特徴情報を渡し予測 prediction = model.predict([feature_array]).tolist() #レスポンス情報を準備 response = {} response['predictions'] = prediction #レスポンスを返す(JSON) return flask.jsonify(response)
まとめ
Githubのリポジトリにソースコードを上げておきましたので、ご確認ください。
今回は、ものすごくシンプルな機械学習WEBシステムをつくってみました。おおまかな流れを掴んでいただけたら幸いです。
実際にビジネスに適用する場合は、もっとたくさん考慮しなければいけない点や、泥臭い作業があります。
ただただ公開されているサンプルをそのまま使って実行するだけでは、そこから実務へ活用するまでにはギャップがあります。
実務への機械学習の活用を考えた際は、ぜひ自分の手で試行錯誤しながら作ってみることをおすすめします。