1. 什么是API

当调包侠们训练好一个模型后,下一步要做的就是与业务开发组同学们进行代码对接,以便这些‘AI大脑’们可以顺利的被使用。然而往往要面临不同编程语言的挑战,例如很常见的是调包侠们用Python训练模型,开发同学用Java写业务代码,这时候,Api就作为一种解决方案被使用。

简单地说,API可以看作是顾客与商家之间的联系方式。如果顾客以预先定义的格式提供输入信息,则商家将获得顾客的输入信息并向其提供结果。

从本质上讲,API非常类似于web应用程序,但它没有提供一个样式良好的HTML页面,而是倾向于以标准数据交换格式返回数据,比如JSON、XML等。

接下来让我们看看如何将机器学习模型(在Python中开发的)封装为一个API。

首先需要明白什么是Web服务?Web服务是API的一种形式,只是它假定API驻留在服务器上,并且可以使用。Web API、Web服务——这些术语通常可以互换使用。

Flask——Python中的Web服务框架。它不是Python中唯一的一个Web框架,其它的例如Django、Falcon、Hug等。Flask框架带有一个内置的轻量级Web服务器,它需要最少的配置,因此在本文中将使用Flask框架来开发我们的模型API。

2. 创建一个简单模型

以一个kaggle经典的比赛项目:泰坦尼克号生还者预测为例,训练一个简单的模型。

以下是整个机器学习模型的API代码目录树:

首先,我们需要导入训练集并选择特征。因为本文主要是介绍机器学习模型API的编写,所以模型训练过程并不做为重点内容,因此我们只选择其中的'Age', 'Sex', 'Embarked', 'Survived' 这四个特征来构造训练集。

import pandas as pd

# 导入训练集并选择特征
url = "http://s3.amazonaws.com/assets.datacamp.com/course/Kaggle/train.csv"
df = pd.read_csv(url)
include = ['Age', 'Sex', 'Embarked', 'Survived']
df_ = df[include]

然后,是一个简单的数据处理过程。

这里主要是对类别型特征进行One-hot编码,对连续型特征进行空缺值填充。

categoricals = []
for col, col_type in df_.dtypes.iteritems():
if col_type == 'O':
categoricals.append(col)
else:
df_[col].fillna(0, inplace=True) df_ohe = pd.get_dummies(df_, columns=categoricals, dummy_na=True)

最后,是模型的训练以及持久化保存。

模型采用的是逻辑回归,使用sklearn.externals.joblib将模型保存为序列化文件.pkl。需要注意的是,如果传入的请求不包含所有可能的category变量值,那么在预测时,get_dummies()生成的dataframe的列数比训练得到分类器的列数少,这会导致运行报错发生。所以在模型训练期间还需要持久化训练集One-hot后的列名列表。

from sklearn.linear_model import LogisticRegression
from sklearn.externals import joblib dependent_variable = 'Survived'
x = df_ohe[df_ohe.columns.difference([dependent_variable])]
y = df_ohe[dependent_variable]
lr = LogisticRegression()
lr.fit(x, y) # 保存模型
joblib.dump(lr, 'model.pkl')
print("Model dumped!") # 把训练集中的列名保存为pkl
model_columns = list(x.columns)
joblib.dump(model_columns, 'model_columns.pkl')
print("Models columns dumped!")

到此,我们的model.py的代码部分构造完毕。

3. 基于Flask框架创建API服务

使用Flask部署模型服务,需要写一个函数predict(),并完成以下两件事:

  1. 当应用程序启动时,将已持久化的模型加载到内存中;
  2. 创建一个API站点,该站点接受输入变量的请求后,将输入转换为适当的格式,并返回预测。

更具体地说,需要API的输入如下(一个由JSON组成的列表):

[
{"Age": 85, "Sex": "male", "Embarked": "S"},
{"Age": 24, "Sex": '"female"', "Embarked": "C"},
{"Age": 3, "Sex": "male", "Embarked": "C"},
{"Age": 21, "Sex": "male", "Embarked": "S"}
]

而模型API的输出如下:

{"prediction": [0, 1, 1, 0]}

import traceback
import sys import pandas as pd
from flask import request
from flask import Flask
from flask import jsonify app = Flask(__name__) @app.route('/predict', methods=['POST']) # Your API endpoint URL would consist /predict
def predict():
if lr:
try:
json_ = request.json
query = pd.get_dummies(pd.DataFrame(json_))
query = query.reindex(columns=model_columns, fill_value=0)
prediction = list(lr.predict(query))
return jsonify({'prediction': str(prediction)})
except:
return jsonify({'trace': traceback.format_exc()})
else:
print('Train the model first')
return 'No model here to use'

我们已经在“/predict”API中包含了所有必需的元素,现在只需编写主类即可。

from sklearn.externals import joblib

if __name__ == '__main__':

    try:
port = int(sys.argv[1])
except:
port = 8000
lr = joblib.load('model.pkl') # Load "model.pkl"
print('Model loaded')
model_columns = joblib.load('model_columns.pkl') # Load "model_columns.pkl"
print('Model columns loaded')
app.run(host='192.168.100.162', port=port, debug=True)

到此,我们的机器学习模型API已经创建完毕,flask_api.py的代码部分也已构造完毕。但在进一步深入之前,让我们回顾一下之前的所有操作:

  1. 加载了泰坦尼克数据集并选择了四个特征。
  2. 进行了必要的数据预处理。
  3. 训练了一个逻辑回归分类器模型并将其序列化。
  4. 持久化训练集中的列名的列表。
  5. 使用Flask编写了一个简单的API,该API通过接收一个由JSON组成的列表,预测一个人是否在沉船中幸存。

4. API的有效性测试

首先运行我们的模型API服务,我们通过Pycharm来启动上一小节编写完成的flask_api.py:

可以看到,在启动API服务后,模型以及列名被顺利的加载到了内存中。

之后可以通过Postman软件模拟网页请求,通过传递测试数据来观察模型API是否能正常返回预测信息。具体操作如下:

可以看到,模型API顺利的接收到了POST请求并发送预测结果。

当然,除了Postman以外,我们也可以编写Python脚本request_api.py完成API测试:

import requests

years_exp = [{"Age": 22, "Sex": "male", "Embarked": "S"},
{"Age": 22, "Sex": "female", "Embarked": "C"},
{"Age": 80, "Sex": "female", "Embarked": "C"},
{"Age": 22, "Sex": "male", "Embarked": "S"},
{"Age": 22, "Sex": "female", "Embarked": "C"},
{"Age": 80, "Sex": "female", "Embarked": "C"},
{"Age": 22, "Sex": "male", "Embarked": "S"},
{"Age": 22, "Sex": "female", "Embarked": "C"},
{"Age": 80, "Sex": "female", "Embarked": "C"},
{"Age": 22, "Sex": "male", "Embarked": "S"},
{"Age": 22, "Sex": "female", "Embarked": "C"},
{"Age": 80, "Sex": "female", "Embarked": "C"},
{"Age": 22, "Sex": "male", "Embarked": "S"},
{"Age": 22, "Sex": "female", "Embarked": "C"},
{"Age": 80, "Sex": "female", "Embarked": "C"},
]
response = requests.post(url='http://192.168.100.162:8000/predict', json=years_exp)
result = response.json()
print('model API返回结果:', result)

同样我们顺利地接收到了模型的返回结果:

这证明我们的机器学习API已经顺利开发完毕,接下来要做的就是交给业务开发组的同学来使用了。

5. 总结

本文介绍了如何从机器学习模型构建一个API。尽管这个API很简单,但描述的还算相对清晰。

此外,除了可以对模型预测部分构建API以外,也可以对训练过程构建一个API,包括通过发送超参数、发送模型类型等让客户来构建属于自己的机器学习模型。当然,这也将是我下一步要做的事情。

为你的机器学习模型创建API服务的更多相关文章

  1. Kubernetes入门(四)——如何在Kubernetes中部署一个可对外服务的Tensorflow机器学习模型

    机器学习模型常用Docker部署,而如何对Docker部署的模型进行管理呢?工业界的解决方案是使用Kubernetes来管理.编排容器.Kubernetes的理论知识不是本文讨论的重点,这里不再赘述, ...

  2. 使用Flask构建机器学习模型API

    1. Python环境设置和Flask基础 使用"Anaconda"创建一个虚拟环境.如果你需要在Python中创建你的工作流程,并将依赖项分离出来,或者共享环境设置," ...

  3. 使用ASP.NET web API创建REST服务(二)

    Creating a REST service using ASP.NET Web API A service that is created based upon the architecture ...

  4. 使用ASP.NET web API创建REST服务(三)

    本文档来源于:http://www.cnblogs.com/madyina/p/3390773.html Creating a REST service using ASP.NET Web API A ...

  5. ASP.NET---如何使用web api创建web服务

    1 首先创建asp.net web空项目,并且创建模拟数据,我在工程下面创建了一个Models文件夹,在文件夹Nodels下面创建类Product和Repository 具体如下: [Serializ ...

  6. ASP.NET Core Web API + Angular 仿B站(二)后台模型创建以及数据库的初始化

    前言: 本系列文章主要为对所学 Angular 框架的一次微小的实践,对 b站页面作简单的模仿. 本系列文章主要参考资料: 微软文档: https://docs.microsoft.com/zh-cn ...

  7. 用PMML实现机器学习模型的跨平台上线

    在机器学习用于产品的时候,我们经常会遇到跨平台的问题.比如我们用Python基于一系列的机器学习库训练了一个模型,但是有时候其他的产品和项目想把这个模型集成进去,但是这些产品很多只支持某些特定的生产环 ...

  8. 用PMML实现python机器学习模型的跨平台上线

    python信用评分卡(附代码,博主录制) https://study.163.com/course/introduction.htm?courseId=1005214003&utm_camp ...

  9. 如何对SAP Leonardo上的机器学习模型进行重新训练

    Jerry之前的两篇文章介绍了如何通过Restful API的方式,消费SAP Leonardo上预先训练好的机器学习模型: 如何在Web应用里消费SAP Leonardo的机器学习API 部署在SA ...

随机推荐

  1. cuda中threadIdx、blockIdx、blockDim和gridDim的使用

    threadIdx是一个uint3类型,表示一个线程的索引. blockIdx是一个uint3类型,表示一个线程块的索引,一个线程块中通常有多个线程. blockDim是一个dim3类型,表示线程块的 ...

  2. ECMAScript5新特性总结

    虽然ECMAScript5早就成为标准推出来了,但之前因为一直用的是ECMAScript3,并且工作中总是要求兼容IE的低版本,所以用的比较少.如今市场上大多数浏览器都能兼容ECMAScript5(I ...

  3. 在 Azure 中将基础结构自动化工具与虚拟机配合使用

    若要以一致的方式大规模创建和管理 Azure 虚拟机 (VM),通常需要某种形式的自动化. 可以通过许多工具和解决方案来自动完成整个 Azure 基础结构部署和管理生命周期. 本文介绍了一些可以在 A ...

  4. MySQL复制 slave_exec_mode 参数IDEMPOTENT 说明

      背景: 今天无意当中看到参数slave_exec_mode,从手册里的说明看出该参数和MySQL复制相关,是可以动态修改的变量,默认是STRICT模式(严格模式),可选值有IDEMPOTENT模式 ...

  5. Linux磁盘及分区之wwid和uuid

    背景描述,在Linux系统中,如果添加了新的SCSI磁盘或者映射SAN存储LUN操作,重启操作系统之后会出现磁盘标识符(sd*)错乱的情况. 例如之前添加的SAN存储LUN的磁盘标识符为/dev/sd ...

  6. 乘风破浪:LeetCode真题_034_Find First and Last Position of Element in Sorted Array

    乘风破浪:LeetCode真题_034_Find First and Last Position of Element in Sorted Array 一.前言 这次我们还是要改造二分搜索,但是想法却 ...

  7. FIO_工具_专业

    一.FIO工具安装: 1.查看fio是否安装 [root@localhost /]#rpm –qa|grep fio 2.源码安装(推荐) 官网地址:http://freecode.com/proje ...

  8. docker tomcat jvm 使用 visualVM监控

    1.  建立基础镜像 FROM centos MAINTAINER fengjian <fengjian@senyint.com> ENV TZ "Asia/Shanghai&q ...

  9. ELK (Elasticsearch+Logstash+Kibana)部署

    部署机器: 服务端:dev-server    X.X.X.X      ( logstash-1.5.4,elasticsearch-1.7.1,kibana-4.1.1 ) 客户端:dev-cli ...

  10. OpenCV——图像的矩(计算矩、轮廓面积、轮廓或曲线长度)

    图像矩描述了图像的全局特征 一阶矩与形状有关 二阶距显示曲线围绕直线平均值的扩展程度 三阶矩是关于平均值的对称性测量 由二阶和三阶矩可以导出7个不变矩,不变矩是图像的统计特性,满足平移.伸缩.旋转的不 ...