今天我们要开发一个用来识别垃圾短信(邮件)的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应用程序
前面我们已经完成了垃圾邮件分类器的所有代码,是不是很简单?接下来,我们将开发一个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/,我们应该看到一个简单的网页,界面如下:
如果您能看到上述画面,那么恭喜您,您已经顺利完成了机器学习模型从开发到部署的全过程,而如果你回顾一下,整个过程并不复杂,只要您有点耐心和并且渴望学习,任何人都可以做到。 更重要的是我已经跨越了一大步,实现了从模型开发到实际应用的整个过程!
你可以在此下载所有代码文件。