[譯] 使用 Python Flask 框架釋出機器學習 API

掘金翻譯計劃發表於2019-05-12

本文描述瞭如何通過 Python Flask REST API 向外界暴露機器學習模型。

Source: Pixabay

Flask 正如其官方網站所述,充滿樂趣且易於安裝。確實,這個 Python 的微框架提供了一種使用 REST 端點註釋 Python 函式的有效方式。目前我使用 Flask 釋出機器學習模型 API,以供第三方業務應用程式訪問。

此示例基於 XGBoost。

為了更佳的程式碼維護性,我建議使用一個單獨的 Jupyter notebook 釋出機器學習模型 API。匯入 Flask 和 Flask CORS 模組:

from flask import Flask, jsonify, request
from flask_cors import CORS, cross_origin

import pickle
import pandas as pd
複製程式碼

該模型使用皮馬印第安人糖尿病資料集(Pima Indians Diabetes Database)訓練。CSV 資料可以從這兒下載。要構建一個 Pandas 資料幀型別的變數來作為模型預測函式的輸入,我們需要定義一個包含資料集的列名的陣列:

# 獲取請求頭中的 payload
headers = ['times_pregnant', 'glucose', 'blood_pressure', 'skin_fold_thick', 'serum_insuling', 'mass_index', 'diabetes_pedigree', 'age']
複製程式碼

使用 Pickle 載入預訓練模型:

# 使用 Pickle 載入預訓練模型
with open(f'diabetes-model.pkl', 'rb') as f:
    model = pickle.load(f)
複製程式碼

測試執行並檢查模型是否執行良好是個好習慣。首先使用一個列名陣列和一個資料陣列(使用不在訓練或測試資料集中的新資料)來構造資料幀。然後呼叫兩個函式 —— model.predictmodel.predict_proba 中的任意一個。我通常更喜歡 model.predict_proba,它返回預測結果為 0 或為 1 的概率,這有助於解釋某個範圍內(例如 0.25 到 0.75)的結果。最後使用一個示例 payload 構建 Pandas 資料幀,然後執行模型預測:

# 用資料幀測試模型
input_variables = pd.DataFrame([[1, 106, 70, 28, 135, 34.2, 0.142, 22]],
                                columns=headers, 
                                dtype=float,
                                index=['input'])

# 獲取模型的預測結果
prediction = model.predict(input_variables)
print("Prediction: ", prediction)
prediction_proba = model.predict_proba(input_variables)
print("Probabilities: ", prediction_proba)
複製程式碼

以下是 Flask API 的寫法。確保啟用 CORS,否則來自其他主機的 API 呼叫將無法成功。在要通過 REST API 暴露的函式前加上註釋,並提供端點的名稱和支援的 REST 方法(本例中為 POST)。從請求中獲取 payload 資料,接著是構造 Pandas 資料幀並執行模型 predict_proba 函式:

app = Flask(__name__)
CORS(app)

@app.route("/katana-ml/api/v1.0/diabetes", methods=['POST'])
def predict():
    payload = request.json['data']
    values = [float(i) for i in payload.split(',')]
    
    input_variables = pd.DataFrame([values],
                                columns=headers, 
                                dtype=float,
                                index=['input'])

    # 獲取模型的預測結果
    prediction_proba = model.predict_proba(input_variables)
    prediction = (prediction_proba[0])[1]
    
    ret = '{"prediction":' + str(float(prediction)) + '}'
    
    return ret

# 執行 REST 介面,port=5000 用於直接測試
if __name__ == "__main__":
    app.run(debug=False, host='0.0.0.0', port=5000)
複製程式碼

函式結果被構造成 JSON 字串並作為響應返回。我在 Docker 容器中執行 Flask,這就是為什麼使用 0.0.0.0 作為它執行的主機 IP。埠 5000 被對映為外部埠,可以允許來自外部的呼叫。

雖然直接在 Jupyter notebook 中啟動 Flask 介面也是可行的,但我還是建議將其轉換為 Python 指令碼並作為服務從命令列執行。使用 Jupyter nbconvert 命令將其轉換為 Python 指令碼:

jupyter nbconvert — to python diabetes_redsamurai_endpoint_db.ipynb

Flask 程式可以利用 PM2 程式管理器從後臺啟動。這種方式可以將端點作為服務啟動,並且能啟用多個執行在不同埠的程式(用於負載均衡)。PM2 啟動命令:

pm2 start diabetes_redsamurai_endpoint_db.py

[譯] 使用 Python Flask 框架釋出機器學習 API

pm2 monit 能夠展示執行中的程式的資訊:

[譯] 使用 Python Flask 框架釋出機器學習 API

用 Postman 呼叫 Flask 提供的機器學習分類模型 REST API:

[譯] 使用 Python Flask 框架釋出機器學習 API

更多資訊:

如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章