如何使用Flask輕松部署機器學習模型?
譯文【51CTO.com快譯】數(shù)據(jù)科學家/機器學習工程師使用Scikit-Learn、TensorFlow、Keras或PyTorch等開發(fā)機器學習模型時,最終目標是將其部署到生產(chǎn)環(huán)境。從事機器學習項目時,我們常常過于關注探索性數(shù)據(jù)分析(EDA)、特征工程和超參數(shù)調(diào)整等,卻往往忘了主要目標:從模型預測中提取實際價值。
部署機器學習模型或?qū)⒛P筒渴鸬缴a(chǎn)環(huán)境意味著將模型提供給最終用戶或系統(tǒng)。然而,部署機器學習模型存在復雜性。本文旨在讓你開始使用Flask API將經(jīng)過訓練的機器學習模型部署到生產(chǎn)環(huán)境。
我將利用線性回歸,使用利率和前兩個月的銷售額來預測第三個月的銷售額。
什么是線性回歸?
線性回歸模型的目的是找到一個或多個特征(獨立變量)與連續(xù)目標變量(獨立變量)之間的關系。如果只有特征,名為單變量線性回歸;如果有多個特征,名為多變量線性回歸。
線性回歸假設
線性回歸模型可用下列方程式加以表示:
- Y是預測值
- θ₀是偏項。
- θ₁,…,θn是模型參數(shù)
- x 1,x 2,…,x n是特征值。
圖1. 線性回歸圖解
為什么使用Flask?
- 易于使用。
- 內(nèi)置的開發(fā)服務器和調(diào)試器。
- 集成的單元測試支持。
- 充分利用REST的請求分派。
- 豐富的說明文檔。
項目結構
該項目有四個部分:
- model.py——這包含機器學習模型基于頭兩個月的銷售額預測第三個月銷售額的代碼。
- app.py——這包含通過GUI或API調(diào)用接收銷售明細,基于我們的模型計算預測值并返回的Flask API。
- request.py —這使用請求模塊來調(diào)用app.py中定義的API,并顯示返回值。
- HTML/CSS——這包含讓用戶可以輸入銷售明細并顯示第三個月預測銷售額的HTML模板和CSS樣式。
圖2. 部署機器學習模型的管道
環(huán)境和工具
- scikit-learn
- pandas
- numpy
- flask
代碼在哪里?
不妨先從代碼開始入手。Github上的整個項目可以在這里(https://github.com/abhinavsagar/Machine-Learning-Deployment-Tutorials)找到。
先從使用HTML構建前端以便用戶輸入值入手。用戶需要填三個字段:利率、第一個月的銷售額和第二個月的銷售額。
- <!DOCTYPE html>
- <html >
- <head>
- <meta charset="UTF-8">
- <title>Deployment Tutorial 1</title>
- <link href='https://fonts.googleapis.com/css?family=Pacifico' rel='stylesheet' type='text/css'>
- <link href='https://fonts.googleapis.com/css?family=Arimo' rel='stylesheet' type='text/css'>
- <link href='https://fonts.googleapis.com/css?family=Hind:300' rel='stylesheet' type='text/css'>
- <link href='https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300' rel='stylesheet' type='text/css'>
- <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
- </head>
- <body style="background: #000;">
- <div class="login">
- <h1>Sales Forecasting</h1>
- <!-- Main Input For Receiving Query to our ML -->
- <form action="{{ url_for('predict')}}"method="post">
- <input type="text" name="rate" placeholder="rate" required="required" />
- <input type="text" name="sales in first month" placeholder="sales in first month" required="required" />
- <input type="text" name="sales in second month" placeholder="sales in second month" required="required" />
- <button type="submit" class="btn btn-primary btn-block btn-large">Predict sales in third month</button>
- </form>
- <br>
- <br>
- {{ prediction_text }}
- </div>
- </body>
- </html>
接下來我使用CSS,為輸入按鈕、登錄按鈕和背景構建一些樣式。
- @import url(https://fonts.googleapis.com/css?family=Open+Sans);
- html { width: 100%; height:100%; overflow:hidden; }
- body {
- width: 100%;
- height:100%;
- font-family: 'Helvetica';
- background: #000;
- color: #fff;
- font-size: 24px;
- text-align:center;
- letter-spacing:1.4px;
- }
- .login {
- position: absolute;
- top: 40%;
- left: 50%;
- margin: -150px 0 0 -150px;
- width:400px;
- height:400px;
- }
- .login h1 { color: #fff; text-shadow: 0 0 10px rgba(0,0,0,0.3); letter-spacing:1px; text-align:center; }
- input {
- width: 100%;
- margin-bottom: 10px;
- background: rgba(0,0,0,0.3);
- border: none;
- outline: none;
- padding: 10px;
- font-size: 13px;
- color: #fff;
- text-shadow: 1px 1px 1px rgba(0,0,0,0.3);
- border: 1px solid rgba(0,0,0,0.3);
- border-radius: 4px;
- box-shadow: inset 0 -5px 45px rgba(100,100,100,0.2), 0 1px 1px rgba(255,255,255,0.2);
- -webkit-transition: box-shadow .5s ease;
- -moz-transition: box-shadow .5s ease;
- -o-transition: box-shadow .5s ease;
- -ms-transition: box-shadow .5s ease;
- transition: box-shadow .5s ease;
- }
- view rawstyle.css hosted with ❤ by GitHub
- >
我為這個項目創(chuàng)建了自定義銷售數(shù)據(jù)集,它有四列:利率、第一個月的銷售額、第二個月的銷售額和第三個月的銷售額。
rate |
sales_in_first_month |
sales_in_second_month |
sales_in_third_month |
|
2 |
500 |
300 |
||
4 |
300 |
650 |
||
four |
600 |
200 |
400 |
|
nine |
450 |
320 |
650 |
|
seven |
600 |
250 |
350 |
|
five |
550 |
200 |
700 |
view rawsales.csv hosted with ❤ by GitHub
現(xiàn)在,不妨構建一個機器學習模型來預測第三個月的銷售額。首先,不妨使用Pandas處理缺失的值。如果沒有為一個或多個項提供任何信息,數(shù)據(jù)會丟失。如果未提供值,我將在利率這列填充零,將在第一個月的銷售額這列填充該列的平均值。我使用線性回歸作為機器學習算法。
序列化/反序列化
簡而言之,序列化是一種在磁盤上寫入Python對象(對象可以傳輸?shù)饺魏蔚胤?,以后由Python腳本反序列化(讀回)的方法。
圖3. 序列化和反序列化
我使用pickling將Python對象這種形式的模型轉(zhuǎn)換成字符流。其想法是,該字符流含有用另一個Python腳本重新構建對象必需的所有信息。
- import numpy as np
- import matplotlib.pyplot as plt
- import pandas as pd
- import pickle
- dataset = pd.read_csv('sales.csv')
- dataset['rate'].fillna(0, inplace=True)
- dataset['sales_in_first_month'].fillna(dataset['sales_in_first_month'].mean(), inplace=True)
- X = dataset.iloc[:, :3]
- def convert_to_int(word):
- word_dict = {'one':1, 'two':2, 'three':3, 'four':4, 'five':5, 'six':6, 'seven':7, 'eight':8,
- 'nine':9, 'ten':10, 'eleven':11, 'twelve':12, 'zero':0, 0: 0}
- return word_dict[word]
- X['rate'] = X['rate'].apply(lambda x : convert_to_int(x))
- y = dataset.iloc[:, -1]
- from sklearn.linear_model import LinearRegression
- regressor = LinearRegression()
- regressor.fit(X, y)
- pickle.dump(regressor, open('model.pkl','wb'))
- model = pickle.load(open('model.pkl','rb'))
- print(model.predict([[4, 300, 500]]))
- view rawmodel.py hosted with ❤ by GitHub
下一個部分是構建這樣一個API:通過GUI收到銷售明細后,基于我們的模型來計算預測的銷售額。為此,我反序列了Python對象這種形式的pickled模型。我使用index.html設置主頁面。一旦使用POST將表單值提交給/predict,我們就獲得了預測銷售額。
只要對/results提出另一個POST請求,即可顯示結果。它收到JSON輸入,使用經(jīng)過訓練的模型來進行預測,并返回使用JSON格式的該預測,它可通過API端點來訪問。
- import numpy as np
- from flask import Flask, request, jsonify, render_template
- import pickle
- app = Flask(__name__)
- model = pickle.load(open('model.pkl', 'rb'))
- @app.route('/')
- def home():
- return render_template('index.html')
- @app.route('/predict',methods=['POST'])
- def predict():
- int_features = [int(x) for x in request.form.values()]
- final_features = [np.array(int_features)]
- prediction = model.predict(final_features)
- output = round(prediction[0], 2)
- return render_template('index.html', prediction_text='Sales should be $ {}'.format(output))
- @app.route('/results',methods=['POST'])
- def results():
- data = request.get_json(force=True)
- prediction = model.predict([np.array(list(data.values()))])
- output = prediction[0]
- return jsonify(output)
- if __name__ == "__main__":
- app.run(debug=True)
- view rawapp.py hosted with ❤ by GitHub
最后,我使用請求模塊來調(diào)用app.py中定義的APP。它顯示了第三個月的返回銷售額。
- import requests
- url = 'http://localhost:5000/results'
- r = requests.post(url,json={'rate':5, 'sales_in_first_month':200, 'sales_in_second_month':400})
- print(r.json())
- view rawrequest.py hosted with ❤ by GitHub
結果
使用該命令運行這個Web應用程序。
- $ python app.py
圖4
在Web瀏覽器中打開http://127.0.0.1:5000/,應該會出現(xiàn)如下所示的GUI。
圖5. 圖形用戶界面
結束語
本文演示了部署機器學習模型的一個很簡單的方法。我利用線性回歸,使用利率和前兩個月的銷售額來預測第三個月的銷售額。你可以利用本文中學到的知識構建一些很酷的模型,并將它們部署到生產(chǎn)環(huán)境中,以便別人享受到成果。
原文標題:How to Easily Deploy Machine Learning Models Using Flask,作者:Abhinav Sagar
【51CTO譯稿,合作站點轉(zhuǎn)載請注明原文譯者和出處為51CTO.com】