我记得我早期在机器学习领域的日子。我喜欢处理多个问题,对机器学习项目的各个阶段都很感兴趣。和我之前的许多人一样,我被模型整个生命周期的构建所吸引。
我和领域专家谈过,项目经理和所有相关人员确保他们的投入被包括在模型中。但后来我遇到了一个障碍——我到底该如何把我的模型交给我的客户呢?我不能给他们一个Jupyter notebook!
我所学的一切都集中在模型构建组件上。没有多少人会谈论如何部署你的机器学习模型。把你的模型投入生产意味着什么?它需要什么?
这些都是每个数据科学家需要回答的关键的职业定义问题。这就是为什么我决定写下这个教程来演示如何使用Flask来部署机器学习模型。
我们将首先了解模型部署的概念,然后讨论Flask是什么,如何安装它,最后,我们将深入到一个问题陈述中,学习如何使用Flask部署机器学习模型。
在典型的机器学习和深度学习项目中,我们通常从定义问题陈述开始,然后是数据收集和准备、数据理解和模型构建,对吧?
但是,最后,我们希望我们的模型能够提供给最终用户,以便他们能够利用它。模型部署是任何机器学习项目的最后阶段之一,可能有点棘手。如何将机器学习模型传递给客户/利益相关者?当你的模型投入生产时,你需要注意哪些不同的事情?你怎么能开始部署一个模型呢?
Flask的作用来了。
Flask是一个用Python编写的web应用程序框架。它有多个模块,使web开发人员更容易编写应用程序,而不必担心协议管理、线程管理等细节。
Flask是开发web应用程序的选择之一,它为我们提供了构建web应用程序所必需的工具和库。
在本教程中,我们将利用Flask的资源来帮助我们部署自己的机器学习模型。你会喜欢用Flask工作的!
安装Flask简单明了。在这里,我假设你已经安装了Python 3和pip。要安装Flask,需要运行以下命令:
sudo apt-get install python3-flask
就这样!准备好深入到问题陈述中去,离部署机器学习模型更近一步。
在本节中,我们将使用Twitter数据集。我们的目标是在推特上发现仇恨言论。为了简单起见,如果推特带有种族主义或性别歧视情绪,我们说它包含仇恨言论。
我们将创建一个包含如下文本框的网页(用户可以搜索任何文本):
对于任何搜索查询,我们将实时抓取与该文本相关的tweet,对于所有这些被抓取的tweet,我们将使用仇恨言语检测模型对种族主义和性别歧视tweet进行分类。
下面是我们刚才看到的步骤的示意图:
我们在映射到标签的CSV文件中有关于Tweets的数据。我们将使用logistic回归模型来预测tweet是否包含仇恨言论。
你可以在这里下载完整的代码和数据集。
https://github.com/lakshay-arora/Hate-Speech-Classification-deployed-using-Flask/tree/master
首先导入一些必需的库:
# 导入必需的库import pandas as pdfrom sklearn.feature_extraction.text import ENGLISH_STOP_WORDS, TfidfVectorizerfrom sklearn.linear_model import LogisticRegressionfrom sklearn.pipeline import Pipelinefrom sklearn.metrics import f1_scorefrom sklearn.model_selection import train_test_split
接下来,我们将读取数据集并查看顶行:
# 读取数据集data = pd.read_csv('dataset/twitter_sentiments.csv')# 查看顶行data.head()
数据集有31962行和3列:
现在,我们将使用scikit learn的train_test_split函数将数据分为训练和测试。我们只将20%的数据用于测试。我们将对标签列上的数据进行分层抽样,以便目标标签在训练和测试数据中的分布相同:
# 分为训练集和测试集train, test = train_test_split(data, test_size = 0.2, stratify = data['label'], random_state=21)# 获取大小train.shape, test.shape## >> ((25569, 3), (6393, 3))
现在,我们将使用TfidfVectorizer 创建tweet列的TF-IDF向量,并将参数lowercase设为True,以便它首先将文本转换为小写。我们还将保持max features为1000,并传递scikit learn 库中预定义的停用词列表。
首先,创建TFidfVectorizer的对象,构建模型并将模型与训练数据tweets匹配:
# 创建TfidfVectorizer对象tfidf_vectorizer = TfidfVectorizer(lowercase= True, max_features=1000, stop_words=ENGLISH_STOP_WORDS)# 拟合模型tfidf_vectorizer.fit(train.tweet)
利用模型对训练和测试数据的推文进行变换:
# #转换训练和测试数据train_idf = tfidf_vectorizer.transform(train.tweet)test_idf = tfidf_vectorizer.transform(test.tweet)
现在,我们将创建一个Logistic回归模型的对象。
请记住,我们的重点不是建立一个非常精确的分类模型,而是看我们如何部署这个预测模型来获得结果。
# 创建线性回归模型的对象model_LR = LogisticRegression()# 用训练数据拟合模型model_LR.fit(train_idf, train.label)# 预测训练数据的标签predict_train = model_LR.predict(train_idf)# 在测试数据预测模型predict_test = model_LR.predict(test_idf)# f1得分f1_score(y_true= train.label, y_pred= predict_train)## >> 0.4888178913738019f1_score(y_true= test.label, y_pred= predict_test)## >> 0.45751633986928114
让我们定义管道的步骤:
当我们对管道对象使用fit()函数时,这两个步骤都会执行。在模型训练过程之后,我们使用predict())函数来生成预测。
# 定义管道的阶段pipeline = Pipeline(steps= [('tfidf', TfidfVectorizer(lowercase=True, max_features=1000, stop_words= ENGLISH_STOP_WORDS)), ('model', LogisticRegression())])# 用训练数据拟合管道模型 pipeline.fit(train.tweet, train.label)
现在,我们将使用一个示例tweet测试管道:
# 示例tweettext = ["Virat Kohli, AB de Villiers set to auction their 'Green Day' kits from 2016 IPL match to raise funds"]# 使用管道预测标签pipeline.predict(text)## >> array([0])
我们已经成功地构建了机器学习管道,我们将使用joblib库中的dump函数保存这个管道对象。只需传递管道对象和文件名:
# 导入joblibfrom joblib import dump# 保存管道模型dump(pipeline, filename="text_classification.joblib")
它将创建一个文件“text_classification.joblib“. 现在,我们将打开另一个Python文件,并使用joblib库的load函数来加载管道模型。
让我们看看如何使用保存的模型:
# 导入joblibfrom joblib import load# tweet文本示例text = ["Virat Kohli, AB de Villiers set to auction their 'Green Day' kits from 2016 IPL match to raise funds"]# 加载保存的pipleine模型pipeline = load("text_classification.joblib")# 对tweet文本样本的预测pipeline.predict(text)## >> array([0])
我们需要做的第一件事是从Twitter开发人员网站获取API key, API secret key, access token,access token secret。这些密钥将帮助API进行身份验证。首先,转到这一页并填写表格。
https://developer.twitter.com/en/apps/create
一旦你填好表格,你就会拿到key。
现在,我们将安装tweepy,它是一个Python库,允许我们访问Twitter API。
!pip3 install tweepy
导入所需的库并添加从Twitter接收到的身份验证密钥。Tweepy试图使身份验证对你来说尽可能无痛。
要开始这个过程,需要创建OAuthHandler实例并传递API key和API secret key。然后使用access token和access token secret对实例进行身份验证。
# 导入所需库import tweepyimport timeimport pandas as pdpd.set_option('display.max_colwidth', 1000)# api keyapi_key = "Enter API Key Here"# api secret keyapi_secret_key = "Enter API Secret Key Here."# access tokenaccess_token = "Enter Access Token Here"# access token secretaccess_token_secret = "Enter Access Token Secret Here."# 授权API Keyauthentication = tweepy.OAuthHandler(api_key, api_secret_key)#对用户access token和access token secret授权authentication.set_access_token(access_token, access_token_secret)# 调用apiapi = tweepy.API(authentication, wait_on_rate_limit=True)
接下来,我们将定义一个函数“get_related_tweets”,它将接受参数text_query并返回与该特定文本查询相关的50条tweets。我们将使用搜索API从Twitter获取结果。
搜索API的一些参数是:
我们将为给定的文本查询请求50条tweet以及tweet创建时间、tweet id和tweet文本,函数将返回所有tweet的数据帧:
def get_related_tweets(text_query): # 存储推文的列表 tweets_list = [] # 推特数量 count = 50 try: # 从查询中提取单个tweets for tweet in api.search(q=text_query, count=count): print(tweet.text) # 添加到包含所有tweets的列表 tweets_list.append({'created_at': tweet.created_at, 'tweet_id': tweet.id, 'tweet_text': tweet.text}) return pd.DataFrame.from_dict(tweets_list) except BaseException as e: print('failed on_status,', str(e)) time.sleep(3)
在这里,我们将创建一个类似于以下内容的网页:
它将有一个文本框,用户可以在其中键入文本查询,然后单击“搜索”按钮以获取搜索文本查询的结果。
我们需要添加表单标记来收集搜索容器中的数据,在表单标记中,我们将方法post和name作为“search”传递。通过提供这个方法,我们的后端代码将能够知道我们已经收到了一些名为“search”的数据,在后端,我们需要处理这些数据并发送一些数据。
这只是HTML文件的一部分。你可以在此处下载完整的代码和与此项目相关的其他文件。
https://github.com/lakshay-arora/Hate-Speech-Classification-deployed-using-Flask/tree/master
我们已经完成了前端部分,现在我们连接模型和网页。第一步是加载保存的管道模型,我们将定义一个函数requestResults,该函数将获取所请求查询的tweets,并使用管道获取标签并返回要发送的最终结果。
# 导入所需库from flask import Flask, render_template, request, redirect, url_forfrom joblib import loadfrom get_tweets import get_related_tweets# 加载管道对象pipeline = load("text_classification.joblib")# 获取特定文本查询的结果def requestResults(name): # 获取推特文本 tweets = get_related_tweets(name) # 获取预测 tweets['prediction'] = pipeline.predict(tweets['tweet_text']) # 获取预测的不同标签的值计数 data = str(tweets.prediction.value_counts()) + '' return data + str(tweets)
现在,首先,创建Flask类的一个对象,该对象将以当前模块名作为参数。route函数将告诉Flask应用程序下一步要在网页上呈现哪个URL。
当Flask服务器运行时,Flask应用程序将路由到默认URL路径并调用home函数,它将呈现home.html文件。
现在,每当有人发送文本查询时,Flask将检测post方法并调用get_data函数,在这里我们将使用名称搜索获取表单数据,然后重定向到success函数。
最后,success函数将使用requestResults函数获取数据并将其发送回网页。
# 启动flaskapp = Flask(__name__)# 渲染网页@app.route('/')def home(): return render_template('home.html')# 当post方法检测到时,则重定向到success函数@app.route('/', methods=['POST', 'GET'])def get_data(): if request.method == 'POST': user = request.form['search'] return redirect(url_for('success', name=user))# 获取请求查询的数据@app.route('/success/')def success(name): return "" + str(requestResults(name)) + " "
现在,调用run函数启动Flask服务器:
app.run(debug=True)
我们已成功启动Flask服务器!打开浏览器并转到此地址-http://127.0.0.1:5000/。你将看到Flask服务器已呈现默认模板。现在搜索任何查询,如iplt20:
Flask服务器将接收与iplt20相关的数据和新tweets请求,并使用该模型预测标签并返回结果。
令人惊叹!在这里,在50条推文中,我们的模型预测了3条包含仇恨言论的推文。我们可以添加更多的功能,比如请求来自某个国家的推文。
这就是使用Flask执行模型部署的方法!部署机器学习模型听起来可能是一项复杂而繁重的任务,但是一旦你了解了它是什么以及它是如何工作的,你就已经完成了一半。
原文链接:https://www.analyticsvidhya.com/blog/2020/04/how-to-deploy-machine-learning-model-flask/