轉載:手把手教你如何開發一個NLP機器學習模型,並將它部署在Flask的Web平臺上(譯)
此博客可操作性較強,可以讓想要將自己開發的機器學習模型,應用Flask(web輕量級框架)在網頁進行簡單部署。但是存在問題:每次預測都要加載一次模型,對於簡單的模型還好,但是當模型很大時,預測會很耗時。而且預測後的結果不能存入數據庫,進而對模型進行優化。
(下面代碼我修改了部分,使css可以顯示樣式。運行代碼即可執行,但是需要確認電腦有裝Python、Pycharm等,會用Pycharm添加模塊、包)
原博客鏈接:https://blog.csdn.net/weixin_42608414/article/details/87460705?utm_source=app
如果不知道怎麼在Pycharm上創建一個Flask項目,請看我的博客:https://blog.csdn.net/qq_37486501/article/details/104574882
最後項目部署好,會顯示如下界面:
今天我們要開發一個用來識別垃圾短信(郵件)的NLP機器學習模型,並將其部署在Flask的Web平臺上,我們的NLP機器學習系統的開發過程是這樣的:1.線下訓練模型–>2.將模型部署成一個web服務–>3.線上實現預測。
開發一個NLP模型,並在線下完成訓練
將訓練好的模型部署成一個web服務在線供用戶使用
當我們開發好一個機器學習模型後,如何來部署這模型,如何讓其他用戶方便的使用它呢?
目前有很多機器學習/深度學習的線上線下課程,它們的主要任務是在教會大家如何構建和優化機器學習/深度學習模型,但它們很少會教會工程師們當模型開發好以後,下一步該如何做?成功的開發一個模型與讓模型能夠爲實際用戶提供服務之間還是有很大的差異。
在本文中,我們將重點在於:構建垃圾短信分類的機器學習模型,然後使用Flask(Python的輕量級web框架)爲模型創建API。用戶可以通過HTTP請求來調用API,並實現對用戶的文本信息進行識別, 好了讓我們開始吧!
構建模型
我們的數據來自於Kaggle,可以在這裏下載,數據已經被標註了垃圾和非垃圾的兩類標籤。我們將使用此數據集構建預測模型,然後用模型準確識別出哪些文本是垃圾郵件。
樸素貝葉斯分類器是一種非常著名的電子郵件過濾統計技術。 它通常使用詞袋方法來識別垃圾郵件。因此我們將根據樸素貝葉斯定理構建一個簡單的消息分類器。
import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import classification_report
from sklearn.externals import joblib
#整理數據,查看數據
df = pd.read_csv('./data/spam.csv', encoding="latin-1")
df=df[['v1','v2']]
df.rename(columns={'v2':'message'}, inplace = True)
df['label'] = df['v1'].map({'ham': 0, 'spam': 1})
df.head()
#構造訓練集和測試集
X = df['message']
y = df['label']
cv = CountVectorizer()
X = cv.fit_transform(X)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)
#樸素貝葉斯分類器
clf = MultinomialNB()
clf.fit(X_train,y_train)
clf.score(X_test,y_test)
y_pred = clf.predict(X_test)
print(classification_report(y_test, y_pred))
樸素貝葉斯分類器不但使用起來非常方便而且預測精度非常高
模型訓練好以後,我們可以使用持久化的方法將模型保存起來,這樣下次使用模型時就不需要重新訓練模型,而直接加載模型就可以了,爲實現此目的,我們可以將模型保存爲.pkl文件以供以後使用。
#將模型持久化,以便以後使用
joblib.dump(clf, 'NB_spam_model.pkl')
我們可以再次加載模型,而不需要重新訓練模型
#加載模型
NB_spam_model = open('NB_spam_model.pkl','rb')
clf = joblib.load(NB_spam_model)
接下來我們要將該模型部署到Flask微服務中,並提供一個接口來接受客戶端的請求。
將垃圾郵件分類器轉變成Web應用程序(利用Flask)
前面我們已經完成了垃圾郵件分類器的所有代碼,是不是很簡單?接下來,我們將開發一個Web應用程序,該應用程序由兩個簡單的Web頁面組成,第一個頁面包含了用戶輸入消息的表單字段。 在將消息提交給Web應用程序後,預測結果將顯示在另外一個頁面上.(是垃圾郵件或不是垃圾郵件)
首先,我們爲這個項目創建一個名爲Spam-Detector的文件夾,下面是該文件夾中的目錄樹。 我們將解釋其中的每個文件。
spam.csv
app.py
templates/
home.html
result.html
static/
style.css
templates是模板文件夾,裏面存放了兩個靜態文件home.html和result.html,Flask會從模板文件夾中查找靜態頁面並將其展示在web瀏覽器中。
app.py
app.py文件包含將由Python解釋器執行以運行Flask Web應用程序的主要代碼,它包含用於對消息進行分類的機器學習代碼:
from flask import Flask,render_template,url_for,request
import pandas as pd
import pickle
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.externals import joblib
app = Flask(__name__)
@app.route('/')
def home():
return render_template('home.html')
@app.route('/predict',methods=['POST'])
def predict():
df = pd.read_csv('spam.csv', encoding="latin-1")
df=df[['v1','v2']]
df.rename(columns={'v2':'message'}, inplace = True)
df['label'] = df['v1'].map({'ham': 0, 'spam': 1})
X = df['message']
y = df['label']
cv = CountVectorizer()
X = cv.fit_transform(X)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)
clf = MultinomialNB()
clf.fit(X_train,y_train)
clf.score(X_test,y_test)
#Alternative Usage of Saved Model
# joblib.dump(clf, 'NB_spam_model.pkl')
# NB_spam_model = open('NB_spam_model.pkl','rb')
# clf = joblib.load(NB_spam_model)
if request.method == 'POST':
message = request.form['message']
data = [message]
vect = cv.transform(data).toarray()
my_prediction = clf.predict(vect)
return render_template('result.html',prediction = my_prediction)
if __name__ == '__main__':
app.run(debug=True)
- 我們把web應用程序作爲單個模塊運行; 因此我們使用參數__name__初始化了一個新的Flask實例,讓Flask知道它可以在它所在的同一目錄中找到HTML模板文件夾。
- 接下來,我們使用route decorator(@ app.route(’/’))來指定應該觸發home函數執行的URL。
- 我們的home函數只是呈現home.html HTML文件,該文件位於templates文件夾中。
- 在預測函數(predict)中,我們訪問垃圾郵件數據集,預處理文本,進行預測,然後存儲模型。 我們接收用戶輸入的新消息,並使用我們的模型對其標籤進行預測。
- 我們使用POST方法將表單數據中的用戶輸入信息傳輸給服務器。 最後,通過在app.run方法中設置debug = True進而激活了Flask的調試器。
- 最後,我們使用run函數僅在Python解釋器直接執行此腳本時在服務器上運行應用程序
home.html
以下是home.html文件的內容,該文件將呈現用戶可以輸入消息的文本框:
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
<!-- <link rel="stylesheet" type="text/css" href="../static/css/styles.css"> -->
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/styles.css') }}">
</head>
<body>
<header>
<div class="container">
<div id="brandname">
Machine Learning App with Flask
</div>
<h2>Spam Detector For SMS Messages</h2>
</div>
</header>
<div class="ml-container">
<form action="{{ url_for('predict')}}" method="POST">
<p>Enter Your Message Here</p>
<!-- <input type="text" name="comment"/> -->
<textarea name="message" rows="4" cols="50"></textarea>
<br/>
<input type="submit" class="btn-info" value="predict">
</form>
</div>
</body>
</html>
style.css
系統在加載home.html的title部分時,會同時加載了styles.css樣式文件。 CSS文件定義了HTML文件的外觀和樣式。 styles.css必須保存在一個名爲static的子目錄中,這是Flask查找靜態文件(如CSS)的默認目錄。
body{
font:15px/1.5 Arial, Helvetica,sans-serif;
padding: 0px;
background-color:#f4f3f3;
}
.container{
width:100%;
margin: auto;
overflow: hidden;
}
header{
background:#03A9F4;#35434a;
border-bottom:#448AFF 3px solid;
height:120px;
width:100%;
padding-top:30px;
}
.main-header{
text-align:center;
background-color: blue;
height:100px;
width:100%;
margin:0px;
}
#brandname{
float:left;
font-size:30px;
color: #fff;
margin: 10px;
}
header h2{
text-align:center;
color:#fff;
}
.btn-info {background-color: #2196F3;
height:40px;
width:100px;} /* Blue */
.btn-info:hover {background: #0b7dda;}
.resultss{
border-radius: 15px 50px;
background: #345fe4;
padding: 20px;
width: 200px;
height: 150px;
}
result.html
我們創建一個result.html文件,用來顯示機器學習模型預測結果,它是通過我們在app.py腳本中定義的predict函數中的render_template將預測結果返回給result.html, result.html文件包含以下內容:
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/styles.css') }}">
</head>
<body>
<header>
<div class="container">
<div id="brandname">
ML App
</div>
<h2>Spam Detector For SMS Messages</h2>
</div>
</header>
<p style="color:blue;font-size:20;text-align: center;"><b>Results for Comment</b></p>
<div class="results">
{% if prediction == 1%}
<h2 style="color:red;">Spam</h2>
{% elif prediction == 0%}
<h2 style="color:blue;">Not a Spam (It is a Ham)</h2>
{% endif %}
</div>
</body>
</html>
完成上述所有操作後,您可以通過雙擊appy.py文件,或從終端執行如下命令來運行我們的web app:
cd Spam-Detector
python app.py
現在您可以打開Web瀏覽器並導航到http://127.0.0.1:5000/,我們應該看到一個簡單的網頁,界面如下:
輸入後,點擊“predict”, 會跳轉界面,顯示預測結果:
demo項目資源鏈接:https://pan.baidu.com/s/1KJyr3LFUOQ_WwjEgvRycxA 密碼:sizw