1. 程式人生 > >手把手教程:用Python開發一個自然語言處理模型,並用Flask進行部署

手把手教程:用Python開發一個自然語言處理模型,並用Flask進行部署

今年企業對Java開發的市場需求,你看懂了嗎? >>>   

截住到目前為止,我們已經開發了許多機器學習模型,對測試資料進行了數值預測,並測試了結果。實際上,生成預測只是機器學習專案的一部分,儘管它是我認為最重要的部分。今天我們來建立一個用於文件分類、垃圾過濾的自然語言處理模型,使用機器學習來檢測垃圾簡訊文字訊息。我們的ML系統工作流程如下:離線訓練->將模型作為服務提供->線上預測。

1、通過垃圾郵件和非垃圾郵件訓練離線分類器。

2、經過訓練的模型被部署為服務使用者的服務。

當我們開發機器學習模型時,我們需要考慮如何部署它,即如何使這個模型可供其他使用者使用。Kaggle資料科學訓練營非常適合學習如何構建和優化模型,但他們並沒有教會工程師如何將它們帶給其他使用者使用,建立模型與實際為人們提供產品和服務之間存在重大差異。

在本文中,我們將重點關注:構建垃圾簡訊分類的機器學習模型,然後使用Flask(用於構建Web應用程式的Python微框架)為模型建立API。此API允許使用者通過HTTP請求利用預測功能。讓我們開始吧!

構建ML模型

資料是標記為垃圾郵件或正常郵件的SMS訊息的集合,可在此處找到。首先,我們將使用此資料集構建預測模型,以準確分類哪些文字是垃圾郵件。

樸素貝葉斯分類器是一種流行的電子郵件過濾統計技術。他們通常使用詞袋功能來識別垃圾郵件。因此,我們將使用Naive Bayes定理構建一個簡單的訊息分類器。

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應用程式!

完整的工作原始碼可在此儲存庫中找到,祝你度過愉快的一週!

作者:【方向】

原文連結

本文為雲棲社群原創內容,未經