LoginSignup
6
8

More than 3 years have passed since last update.

機械学習実装のWeb サイト作り【Flask使用】

Last updated at Posted at 2021-04-02

目的

入力したワインの特徴から、ワインの品質(quality)Bランク〜Sランクを予測するWebサイトを作成する
機械学習を使った、webサイト作成を体験してみる

4285898_s.jpg

スクリーンショット 2021-04-02 18.08.55.png

データ

使用出来るデータ
https://archive.ics.uci.edu/ml/datasets/Wine+Quality

複数の成分からワインの品質の予測を行う

固定酸性度 fixed_acidity
揮発性酸性度 volatile_acidity
クエン酸 citric_acid
残留糖 residual_sugar
塩化物 chlorides
遊離亜硫酸濃度 free_sulfur_dioxide
総亜硫酸濃度 total_sulfur_dioxide
密度 density
pH ph
硫酸塩 sulphates
アルコール alcohol
品質 quality

環境

Colaboratory使用(学習モデル作成時)
Atom1.55.0(Web page作成)

学習のモデル作り

googleのColaboratoryでまずは、機械学習のモデル作りを行う

ワインのデータセットをダウンロード

import pandas as pd
wine = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv", sep=";", encoding="utf-8")
wine

1599index(行)×12 columns(列)のデータセット確認

スクリーンショット 2021-03-30 14.55.42.png

corr()でqualityとの相関係数を確認をする
残念ながら。。。
0.6や-0.6を超えるような、qualityに大きな影響を当たる特徴がない

wine.corr()

スクリーンショット 2021-03-31 15.53.38.png

正解の品質ラベルのデータをY
個人的に予測に使用するデータは、シンプルにアルコールとよく成分で見かけるtotal_sulfur_dioxide(総亜硫酸濃度)としたいが

2つの特徴だけでは、いい精度を出すのは不可能に近いので

今回は、相関係数が高いvolatile_acidity(揮発性酸性度),sulphates(硫酸塩)も使用する

Y = wine["quality"]
using_coulumns=["total sulfur dioxide","alcohol","volatile acidity","sulphates"]

X =wine[using_coulumns]

この4つの特徴から、ワインの品質を予測する

スクリーンショット 2021-04-02 17.32.12.png

ヒストグラムでワインの品質を確認

from matplotlib import pyplot as plt
plt.hist(Y,bins=10)

スクリーンショット 2021-04-02 17.35.15.png

3と8が少しだけあるが、これを含めて予測するのは難しいので
正解ラベルを3等分にする、
3,4→0
5,6→1
7,8→2

Y.replace({3:0,4:0},inplace=True)
Y.replace({5:1,6:1},inplace=True)
Y.replace({7:2,8:2},inplace=True)

正解ラベルYと特徴Xから、学習するためのtrainデータと
精度確認のためtestデータを作成
testデータは3割りで残りは学習データとする

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)

今回はrandom_forestで学習を行う、

from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
model.fit(x_train, y_train)

先ほど学習を行ったモデルでtestデータの予測を行う
testデータのラベル(正解)と、予測したデータをaccuracy_scoreで比較する
結果は正答率85%前後

from sklearn.metrics import accuracy_score
y_pred = model.predict(x_test)

print("正解率 = ", accuracy_score(y_test, y_pred))

先ほどの学習のモデルをpickleで保存
左のファイルから右クリックでダウンロード出来る
このwinemodel.pklをweb pageで使用する

import pickle
with open('winemodel.pkl', mode='wb') as fp:
  pickle.dump(model,fp)

スクリーンショット 2021-03-30 15.55.56.png

Web作成

表示するHTMLのindex.htmlはtemplatesへ

├main.py
├winemodel.pkl
├templates/index.html

main.py file

main.py


from flask import Flask, render_template, redirect
from flask import request, jsonify
import pandas as pd
import pickle
from sklearn.ensemble import RandomForestRegressor

app = Flask(__name__)

#先ほどの機械学習のモデル読み込み
model_file_name='winemodel.pkl'
model = pickle.load(open(model_file_name, 'rb'))

#実行を開始すべきURLを指定
@app.route('/')
def index():
   return render_template('index.html')

#HTMLのformから受け取った時の処理
@app.route('/hinshitsu', methods=['POST'])
def lower_conversion():
   total = request.form["total sulfur dioxide"]
   alcohol=request.form["alcohol"]
   volatile = request.form["volatile acidity"]
   sulphates = request.form["sulphates"]
  #受け取ったデータをデータフレームに変更
   df = pd.DataFrame({'total sulfur dioxide': [total],
                   'alcohol': [alcohol],
                   'volatile acidity': [volatile],
                   'sulphates': [sulphates],
                   })
  #予測
   result = model.predict(df)
  #予測結果をpythonのint型に変更
   result = result.item()
   rank=""
   if result==0:
       rank="Bランク"
   elif result==1:
       rank="Aランク"
   else:
       rank="Sランク"

   #HTMLに変更内容を送る
   return render_template('index.html',rank = rank)


if __name__ == '__main__':
   app.run(host="0.0.0.0", port=8080)

入力フォームは step=で入力出来る小数点の単位を指定

index.html

<!DOCTYPE html>
<html lang="ja">
 <head>
   <meta charset="utf-8"></meta>
   <title>ワイン品質予測</title>
 </head>
 <body>
         <h1>ワインの品質予想</h1>
             <hr>
             ここに結果が表示される:<h1>{{rank}}</h1>
             <hr>
             <p>ワインの成分を入力して下さい</p>
         <form method='POST' action='/hinshitsu'>

             <div>
                 <p>総亜硫酸濃度(total sulfur dioxide):</p>
                 <p><input type="number" step="0.01"  name="total sulfur dioxide"required></p>
             </tr>
             </div>

             <div>
                 <p>アルコール(alcohol):</p>
                 <p> <input type="number" step="0.01"  name="alcohol"required></p>
             </div>

             <div>
                 <p>揮発性酸性度(volatile acidity):</p>
                 <p>  <input type="number" step="0.001" name="volatile acidity"required></p>
             </div>
             <div>
                 <p>硫酸塩(sulphates):</p>
                 <p> <input type="number" step="0.01"  name="sulphates"required></p>
             </div>


          <input type="submit" value="予測">
          </form>
</body>
</html>

python main.pyでmain.py fileを実行する
下記、WARNINGが表示されたら成功、Running onに表示されているURLにアクセスしたら完了

WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)

実験

モデルを作成する時に使った、最初の0番目のデータで確認

スクリーンショット 2021-03-31 16.54.38.png

スクリーンショット 2021-04-02 18.08.55.png

予測すると・・・

品質5なので無事Aランクで表示

スクリーンショット 2021-03-31 17.00.44.png

終わりに

ターゲットをソムリエなどのプロ集団なら、データの特徴を増やして、精度をかなり上げないといけないが
軽く参考程度に確認を行う場合は、複雑な成分がありすぎると利用面では不便
どれだけ精度を出せるか、また使いやすさも大切でトレードオフな部分がある
まずは、ターゲットを絞ることが大切かもしれない

6
8
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8