将模型部署到生产环境是和团队的一项成就!在常规的软件工程开发周期中,现在可以坐下来放松一下;然而,在机器学习开发周期中,部署到生产环境只是工作的大约50%。模型如何在生产环境中与实时数据一起工作才是真正的考验。如果未能监控模型在生产环境中的性能,可能会导致性能下降,最终导致公司面临严重后果。
以一个信用卡欺诈检测系统为例,该系统在测试数据上的准确率为90%,但在生产环境中降至45%的准确率,未能检测到实际的欺诈行为;公司可能不得不支付巨额的金钱赔偿,并面临声誉受损。
希望已经阐明了机器学习项目生命周期在部署到生产环境后并没有结束;这只是开始。作为本文的一部分,将探讨监控模型的重要性以及实现监控的方法,并以一个机器学习案例研究为例,将其部署到生产环境中。
要理解这一点,需要了解两个概念:概念漂移和数据漂移。
概念漂移是指模型开发所基于的理念发生变化。以购物在大流行后的变化为例;人们使用信用卡在线购物的数量急剧增加,使信用卡欺诈检测系统陷入混乱。基本上,在概念漂移期间,输入(X)对目标(Y)的条件概率会发生变化,即P(Y|X)会发生变化。
模型的好坏取决于数据。如果测试数据集的底层分布与模型训练时的数据集不同,它自然不会在生产环境中像在开发环境中那样表现良好。让给一个例子;假设正在监控用户的社交媒体数据;突然之间,一个名为ByteTok的新应用程序病毒式传播,在两天内拥有数百万用户;由于该应用程序之前不可用,模型尚未见过该应用程序,因此无法做出良好的预测。
要监控数据漂移,可以检查输入是否看到以前未见过的分类值,或者数值是否超出了训练期间看到的范围。还可以监控训练和测试数据集中特征的个体分布。
在概念漂移和数据漂移的情况下,模型性能将遭受逐渐下降或突然冲击。
更好地管理概念和数据漂移的一种方法是设置警报,当均值的标准误差超过确定的某个阈值时。
1) 软件指标:软件指标包括接收到的 用户查询请求数量,这有助于了解用户的日常流量。还要检查服务器负载等。
2) 输入指标:输入指标涉及检查输入是否在训练集中看到的某个范围内。数据分布的变化。
3) 输出指标:检查模型是否预测了太多的空值,或者它是否无法自信地预测许多数据点的类别。
重训练可以通过两种不同的方法进行,手动重训练或自动重训练;手动重训练更为常见,因为大多数团队对未经人工干预就重训练模型持谨慎态度。
接下来,将看看使用flask和python在Heroku上完成的部署。在一个案例研究项目上工作,为了提供演示,将机器学习模型部署为一个Web应用程序。
案例研究的目的是预测基于受害者提供的描述的滥用类别。它涉及文本清理、文本向量化和模型调整和训练。
现在已经向介绍了机器学习后端做了什么,让解释一下部署模型所采取的步骤。首先,创建了一个HTML和CSS脚本来模拟应用程序的前端。如果想查看代码,将在最后链接GitHub仓库。
接下来,创建了机器学习模型的pickle;可以pickle任何python对象;pickle会序列化对象并将其写入文件,然后可以迁移或转换它,通常在深度神经网络训练期间,由于占用了大量的训练时间,建议将模型的进度存储在pickle文件中,并在下次从该点重新训练它。
然后创建了一个python脚本,该脚本使用HTTP的get方法来获取用户输入的英文文本描述;使用向量化和机器学习模型pickles,预测结果并适当地显示在屏幕上。
from flask import Flask, jsonify, request import joblib
import flask
# https://www.tutorialspoint.com/flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route('/index')
def index():
return flask.render_template('app.html')
@app.route('/predict', methods=['POST'])
def predict():
prediction = []
clf = joblib.load('finalized_model.pickle')
count_vect = joblib.load('vectorizer.pickle')
text = request.form.get('review_text')
#print(text)
pred = clf.predict(count_vect.transform([text]))
x = pred.toarray()
print(x)
if x[0,0]:
prediction.append('Commenting')
if x[0,1]:
prediction.append('Ogling')
if x[0,2]:
prediction.append('Groping')
if len(prediction) == 0:
return flask.render_template('app.html', prediction_text='It is not an abuse statement')
else:
return flask.render_template('app.html', prediction_text='Predicted categories of abuse are {}'.format(prediction))
#return jsonify(prediction)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)