截住到目前为止, 我们已经开发了许多机器学习模型, 对测试数据进行了数值预测, 并测试了结果. 实际上, 生成预测只是机器学习项目的一部分, 尽管它是我认为最重要的部分. 今天我们来创建一个用于文档分类, 垃圾过滤的自然语言处理模型, 使用机器学习来检测垃圾短信文本消息. 我们的 ML 系统工作流程如下: 离线训练 ->将模型作为服务提供 ->在线预测.
1, 通过垃圾邮件和非垃圾邮件训练离线分类器.
2, 经过训练的模型被部署为服务用户的服务.
当我们开发机器学习模型时, 我们需要考虑如何部署它, 即如何使这个模型可供其他用户使用. Kaggle https://www.kaggle.com/ 和数据科学训练营非常适合学习如何构建和优化模型, 但他们并没有教会工程师如何将它们带给其他用户使用, 建立模型与实际为人们提供产品和服务之间存在重大差异.
在本文中, 我们将重点关注: 构建垃圾短信分类的机器学习模型, 然后使用 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 %}这是 http://jinja.pocoo.org/docs/2.10/templates/ 语法, 它用于访问从 HTML 文件中请求返回的预测.
我们就要大功告成了!
完成上述所有操作后, 你可以通过双击 appy.py 或从终端执行命令来开始运行 API :
cd SMS-Message-Spam-Detector
python App.py
你应该得到以下输出:
现在你可以打开 Web 浏览器并导航到 http://127.0.0.1:5000/ , 你应该看到一个简单的网站, 内容如下:
恭喜! 我们现在以零成本的代价创建了端到端机器学习 (NLP) 应用程序. 如果你回顾一下, 其实整个过程根本不复杂. 有点耐心和渴望学习的动力, 任何人都可以做到. 所有开源工具都使每件事都成为可能.
更重要的是, 我们能够将我们对机器学习理论的知识扩展到有用和实用的 Web 应用程序!
完整的工作源代码可在此存储库中找到, 祝你度过愉快的一周!
来源: https://yq.aliyun.com/articles/696952