手把手教程:用Python開發一個自然語言處理模型,並用Flask進行部署
截住到目前為止,我們已經開發了許多機器學習模型,對測試資料進行了數值預測,並測試了結果。實際上,生成預測只是機器學習專案的一部分,儘管它是我認為最重要的部分。今天我們來建立一個用於文件分類、垃圾過濾的自然語言處理模型,使用機器學習來檢測垃圾簡訊文字訊息。我們的ML系統工作流程如下:離線訓練->將模型作為服務提供->線上預測。
1、通過垃圾郵件和非垃圾郵件訓練離線分類器。
2、經過訓練的模型被部署為服務使用者的服務。
當我們開發機器學習模型時,我們需要考慮如何部署它,即如何使這個模型可供其他使用者使用。Kaggle和資料科學訓練營非常適合學習如何構建和優化模型,但他們並沒有教會工程師如何將它們帶給其他使用者使用,建立模型與實際為人們提供產品和服務之間存在重大差異。
在本文中,我們將重點關注:構建垃圾簡訊分類的機器學習模型,然後使用Flask(用於構建Web應用程式的Python微框架)為模型建立API。此API允許使用者通過HTTP請求利用預測功能。讓我們開始吧!
構建ML模型
資料是標記為垃圾郵件或正常郵件的SMS訊息的集合,可在此處找到。首先,我們將使用此資料集構建預測模型,以準確分類哪些文字是垃圾郵件。
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 df = pd.read_csv('spam.csv', encoding="latin-1") df.drop(['Unnamed: 2', 'Unnamed: 3', 'Unnamed: 4'], axis=1, inplace=True) df['label'] = df['class'].map({'ham': 0, 'spam': 1}) X = df['message'] y = df['label'] cv = CountVectorizer() X = cv.fit_transform(X) # Fit the Data X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42) #Naive Bayes Classifier 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))
Naive Bayes分類器不僅易於實現,而且提供了非常好的效能。在訓練模型之後,我們都希望有一種方法來保持模型以供將來使用而無需重新訓練。為實現此目的,我們新增以下行以將我們的模型儲存為.pkl檔案供以後使用。
from sklearn.externals import joblib
joblib.dump(clf, 'NB_spam_model.pkl')
我們載入並使用儲存的模型:
NB_spam_model = open('NB_spam_model.pkl','rb')
clf = joblib.load(NB_spam_model)
上述過程稱為“標準格式的持久模型”,即模型以特定的開發語言的特定格式持久儲存。下一步就是將模型在一個微服務中提供,該服務的公開端點用來接收來自客戶端的請求。
將垃圾郵件分類器轉換為Web應用程式
在上一節中準備好用於對SMS訊息進行分類的程式碼之後,我們將開發一個Web應用程式,該應用程式由一個簡單的Web頁面組成,該頁面具有允許我們輸入訊息的表單欄位。在將訊息提交給Web應用程式後,它將在新頁面上呈現該訊息,從而為我們提供是否為垃圾郵件的結果。
首先,我們為這個專案建立一個名為SMS-Message-Spam-Detector 的資料夾,這是該資料夾中的目錄樹,接下來我們將解釋每個檔案。
spam.csv
app.py
templates/
home.html
result.html
static/
style.css
子目錄templates是Flask在Web瀏覽器中查詢靜態HTML檔案的目錄,在我們的例子中,我們有兩個html檔案:home.html和result.html 。
app.py
app.py
檔案包含將由Python直譯器執行以執行Flask Web應用程式的主程式碼,還包含用於對SMS訊息進行分類的ML程式碼:
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.drop(['Unnamed: 2', 'Unnamed: 3', 'Unnamed: 4'], axis=1, inplace=True)
# Features and Labels
df['label'] = df['class'].map({'ham': 0, 'spam': 1})
X = df['message']
y = df['label']
# Extract Feature With CountVectorizer
cv = CountVectorizer()
X = cv.fit_transform(X) # Fit the Data
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)
#Naive Bayes Classifier
from sklearn.naive_bayes import MultinomialNB
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)
1、我們將應用程式作為單個模組執行,因此我們使用引數初始化了一個新的Flask例項,__name__是為了讓Flask知道它可以在templates所在的同一目錄中找到HTML模板資料夾()。
2、接下來,我們使用route decorator(@app.route('/'))來指定可以觸發home 函式執行的URL 。我們的home 函式只是呈現home.htmlHTML檔案,該檔案位於templates資料夾中。
3、在predict函式內部,我們訪問垃圾郵件資料集、預處理文字、進行預測,然後儲存模型。我們訪問使用者輸入的新訊息,並使用我們的模型對其標籤進行預測。
4、我們使用該POST方法將表單資料傳輸到郵件正文中的伺服器。最後,通過debug=True在app.run方法中設定引數,進一步啟用Flask的偵錯程式。
5、最後,我們使用run函式執行在伺服器上的指令碼檔案,我們需要確保使用if語句 __name__ == '__main__'。
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>
view raw
style.css檔案
在home.html的head部分,我們將載入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;
}
style.css檔案
result.html
我們建立一個result.html檔案,該檔案將通過函式render_template('result.html', prediction=my_prediction)返回呈現predict,我們在app.py指令碼中定義該檔案以顯示使用者通過文字欄位提交的文字。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>
result.html
從result.htm檔案我們可以看到一些程式碼使用通常在HTML檔案中找不到的語法例如,{% if prediction ==1%},{% elif prediction == 0%},{% endif %}這是jinja語法,它用於訪問從HTML檔案中請求返回的預測。
我們就要大功告成了!
完成上述所有操作後,你可以通過雙擊appy.py 或從終端執行命令來開始執行API :
cd SMS-Message-Spam-Detector
python app.py
你應該得到以下輸出:
現在你可以開啟Web瀏覽器並導航到http://127.0.0.1:5000/,你應該看到一個簡單的網站,內容如下:
恭喜!我們現在以零成本的代價建立了端到端機器學習(NLP)應用程式。如果你回顧一下,其實整個過程根本不復雜。有點耐心和渴望學習的動力,任何人都可以做到。所有開源工具都使每件事都成為可能。
更重要的是,我們能夠將我們對機器學習理論的知識擴充套件到有用和實用的Web應用程式!
完整的工作原始碼可在此儲存庫中找到,祝你度過愉快的一週!
作者:【方向】
原文連結
本文為雲棲社群原創內容,未經