【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

容器化的数据科学与工程——第二部分:容器化的数据科学

  • 2016-05-29
  • 本文字数:3626 字

    阅读完需:约 12 分钟

(这是有关容器化世界里的数据科学与工程系列博客文章的第二部分,点看第一部分)。

首先要承认,数据科学家正在设计一些非常有意思(而且或许很有价值的)的模型、优化以及虚拟化等。不幸的是,由于很多模型不能被产业化,它们将永远也不会被使用。事实上,很多工业界正在发生的“数据科学”也同步而孤立的发生在数据科学家的笔记本上。而且,在数据科学的应用被实际部署的场景中,它们经常被部署为 python/R 脚本,上传到 AWS 并作为一个 cron 任务来运行。

正如下面所言,这是数据科学用于工业界的一个非常大的问题和障碍:

“只有一个问题——我所有的工作都是在本地机器的 R 中完成的。人们欣赏我的努力,但是由于它没有被“产品化”且框架不能和本地模型通信,他们不知道如何使用我的模型。非常大的教训!”—— Twitter 的数据科学家 Robert Chang
“数据工程师经常抱怨:数据科学家缩写的代码效率低、风格差;他们很少考虑想法产品化后的维护代价;他们经常要求一些努力很多、受益很小的不切现实的特性。类似的抱怨还有很多,但你已经知道要点在哪了。”——数据平台 Stitchfix 的经理 Jeff Magnusson

但是,请不要担心!有一个更好的方法:容器化你的数据科学应用,以方便部署、可移植以及框架内的集成

数据科学家应该关心 Docker 的原因

该问题的简单回答就是:数据科学家想让他们的模型、仪表盘、优化等等被实际使用。为了让数据科学的应用被使用并带来价值,它们需要走出笔记本电脑,并被实际部署。它们还需要能够与现有的架构兼容,并易于升级和迭代。

一个 Docker 化的数据科学应用是如何提供以下好处的呢?

  • _ 无论应用如何部署、部署在何处,你无需担心依赖问题。_ 部署数据科学的应用的一个难点就是,搞清楚机器上复杂的依赖关系(numpy、scipy、pandas、scikit-learn 和 statsmodels 等)。通过将这些应用容器化,你可以在不管依赖关系、部署机器上的操作系统类型以及现有包 / 库版本的情况下,利用一行命令轻易完成部署。
  • _ 随着公司框架的扩展或你需要扩展你的应用,你可以轻易移植或创建更多实例。_ 大家经常会在没有全面考虑服务最终部署位置、服务能力的实际需求等问题的情况下开发一个模型或应用。但是,当你将数据科学的应用容器化以后,你可以轻易的根据需求将它从 AWS 移植到 Azure。或者,你可以根据负载情况,创建更多的应用实例。
  • _ 你,作为一个数据科学家,可以保持公司的现代化架构。_ 替代在与 4 个不同的数据库直接交互的机器上的 cron 任务,容器化的数据应用可以利用 JSON API 和消息队列来与框架的其他部分进行交互。而且更让工程师觉得开心的是,当架构改变或升级时,应用也可以正常工作。你还可以将数据科学的工作和其他工程团队的 CI/CD 流水线集成在一起。(观众中的数据科学家不要担心:这并不难,而且我们会在下面给出一个例子)。

容器化数据科学应用的一个简单例子

接下来,让我们从一个 python 脚本开始了解容器化的数据科学应用。接下来,我会给出容器化数据科学应用的一个简单例子:

  1. 利用绝大部分数据科学家熟悉的技术( python scikit-learn ).
  2. 被容器化(也就是说,可以被编译为一个 Docker 镜像)。
  3. 通过 JSON API 与 Docker 容器以外的组件进行交互。

一个做预测的简单模型

这里,我们将利用著名的 Iris 数据集来构架一个 k-NN 分类模型(带 scikit-learn ):

复制代码
from sklearn import datasets
from sklearn.neighbors import KNeighborsClassifier
def predict(inputFeatures):
iris = datasets.load_iris()
knn = KNeighborsClassifier()
knn.fit(iris.data, iris.target)
predictInt = knn.predict(inputFeatures)
if predictInt[0] == 0:
predictString = 'setosa'
elif predictInt[0] == 1:
predictString = 'versicolor'
elif predictInt[0] == 2:
predictString = 'virginica'
else:
predictString = 'null'
return predictString

该预测函数将基于输入特征``inputFeatures`(sepal length、sepal width、petal length 和 petal width)返回一种 Iris。在本例中,用于训练模型的数据集是静态的(也就是说,从 scikit-learn 数据集中加载)。然而,你可以很轻易的想到如何从一个数据集或利用消息、API 和数据库交互所聚合的值中动态加载。

传递预测的 JSON API

接下来,我们需要将这些预测传递到其他组件。为此,我将开发自己作为简单 JSON API 的应用。对于很多使用微服务架构的工程团队而言,这种应用只是一种普通的练习。而且它可以使得数据应用与其他现存的服务更好的协同工作。

这里,我们将在 API 中使用flashk-restful,你可以使用 twisted 或其他任何架构:

复制代码
from flask import Flask
from flask_restful import Resource, Api
from flask_restful import reqparse
from utils import makeprediction
app = Flask(__name__)
api = Api(app)
class Prediction(Resource):
def get(self):
parser = reqparse.RequestParser()
parser.add_argument('slength', type=float,
help='slength cannot be converted')
parser.add_argument('swidth', type=float,
help='swidth cannot be converted')
parser.add_argument('plength', type=float,
help='plength cannot be converted')
parser.add_argument('pwidth', type=float,
help='pwidth cannot be converted')
args = parser.parse_args()
prediction = makeprediction.predict([
args['slength'],
args['swidth'],
args['plength'],
args['pwidth']
])
print "THE PREDICTION IS: " + str(prediction)
return {
'slength': args['slength'],
'swidth': args['swidth'],
'plength': args['plength'],
'pwidth': args['pwidth'],
'species': prediction
}
api.add_resource(Prediction, '/prediction')
if __name__ == '__main__':
app.run(debug=False)

那么,我就得到了一个GET端点,使得我们可以利用其来获得针对一个特征集的预测。例如,路径

http://<host>:5000/prediction?slength=1.5&swidth=0.7&plength=1.3&pwidth=0.3将返回:

复制代码
{
"pwidth": 0.3,
"plength": 1.3,
"slength": 1.5,
"species": "setosa",
"swidth": 0.7
}

其中,在响应 JSON 中的species表示基于输入特征预测的种类。

构建 Docker 镜像的 Dockerfile

为了构建一个我们数据科学应用的“Docker 镜像”,我们西药一个Dockerfile。该Dockerfile将呆在 repo 的 root 中,并包含 Docker 镜像中的所有必须的文件和依赖关系。当我们运行 Docker 镜像时,运行我们所选择的一个命令:

复制代码
FROM ubuntu:12.04
# get up pip, vim, etc.
RUN apt-get -y update --fix-missing
RUN apt-get install -y python-pip python-dev libev4 libev-dev gcc libxslt-dev libxml2-dev libffi-dev vim curl
RUN pip install --upgrade pip
# get numpy, scipy, scikit-learn and flask
RUN apt-get install -y python-numpy python-scipy
RUN pip install scikit-learn
RUN pip install flask-restful
# add our project
ADD . /
# expose the port for the API
EXPOSE 5000
# run the API
CMD [ "python", "/api.py" ]

准备完毕,开始部署应用

以上就是构建第一个容器化的数据科学应用所需要的所有步骤(对于 Docker 的安装指令,参看 Docker 网站)。现在,让我们构建应用的“Docker 镜像”:

docker build --force-rm=true -t pythoniris

该命令将构建一个名为pythoniris的 Docker 镜像。我们可以根据需要标记该镜像(例如,pythoniris:latest),或将其和 Docker Hub 上的用户 / 账号(例如,dwhitena/pythoniris)关联起来(Docker Hub 是一个专门存储 Docker 镜像的公开仓库,类似于 Docker 镜像的 Github)。

如果你将镜像上传到 Docker Hub(或一个私有仓库),部署就像运行引用 Docker Hub 或仓库中的用户名 / 镜像名的 Docker 镜像一样容易。然而,假设你想首先在本地进行这些尝试,你可以通过如下命令来运行 Docker 镜像:

复制代码
docker run --net host -d --name myiris pythoniris

该命令将运行 Docker 镜像运行为一个名为myiris的容器、一个守护进程(-d),并使用与本地主机相同的网络接口(--net host)。现在,你的 JOSN API 就可以通过localhost:5000端口进行访问了。

可以看的出来,从 python 脚本到容器化的数据应用只需要一点点的付出。现在,请继续向前——研究数据科学、容器化数据科学和部署你的数据科学吧。

以上代码可以在 Github 中下载。


感谢陈兴璐对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2016-05-29 17:441870
用户头像

发布了 268 篇内容, 共 118.1 次阅读, 收获喜欢 24 次。

关注

评论

发布
暂无评论
发现更多内容

玩转TypeScript工具类型(下)

有道技术团队

typescript 大前端 网易有道

与springcloud整合的框架源码读取入口

Java 编程 架构 微服务

Tapdata 实时数据中台在智慧教育中的实践

tapdata

我愿意招什么样的产品经理?

石云升

产品经理 招聘 9月日更

直播预告|如何节省30%人工成本,缩短80%商标办理周期?

京东科技开发者

商标 企业服务 灵活用工

一部好看过武侠小说的热血互联网史!

博文视点Broadview

mydumper备份工具介绍与使用

Simon

MySQL

幻读是啥,会有什么问题?如何解决?

Java MySQL 数据库 面试 后端

网络攻防学习笔记 Day144

穿过生命散发芬芳

高可用 9月日更

银行数字化转型指南:《区域性银行数字化转型白皮书》完整版重磅发布

百度开发者中心

最佳实践 银行数字化转型

Percolator模型及其在TiKV中的实现

vivo互联网技术

数据库 Percolator 分布式,

主机安全是什么意思?安全体检包含哪些方面?

行云管家

运维 服务器 主机 主机安全 安全体检

基于Tensorflow + Opencv 实现CNN自定义图像分类

华为云开发者联盟

tensorflow KNN OpenCV CNN

乘着汽车智能化的浪潮,“汽车人”的职业方向选择(三)

SOA开发者

软件定义汽车 车载控制单元

FunTester框架Redis性能测试之list操作

FunTester

redis 性能测试 测试框架 压力测试 FunTester

iOS开发面试拿offer攻略之数据结构与算法篇附加安全加密

iOSer

ios 数据加密 iOS面试 iOS逆向 iOS算法

作为一线技术人员,如何更好地提升自己

谙忆

管理 成长 引航计划

深入理解掌握零拷贝技术

Linux服务器开发

网络协议 零拷贝 Linux服务器开发 Linux内核 用户态

2021年公有云市场的5大趋势

浪潮云

云计算

金融级分布式事务解决方案DTC

tom

为什么不推荐Python初学者直接看项目源码

Felix

Python 编程 开发 Programing 阅读代码

Alibaba内部“Java架构核心宝典”来袭,全新技术限时开源

Java 编程 程序员 架构 面试

二十不惑的年纪,我简直走了狗屎运(4面拿字节跳动offer)

Java 程序员 架构 面试 计算机

低代码应用:软件开发的一体化最新形态!

优秀

低代码

JavaScript进阶(七)call, apply, bind

Augus

JavaScript 9月日更

通俗易懂 即时通讯初学者入门 WhatsApp技术架构

OpenIM

Linux用户密码管理

在即

9月日更

千万级数据迁移与分表的技术方案-企业产品实战

谙忆

Java 后端 分库分表 引航计划

Go 语言网络库 getty 的那些事

apache/dubbo-go

dubbo Go 语言 Dubbo3

堡垒机作用之事后审计详细讲解-行云管家

行云管家

运维 网络安全 运维审计 事后审计

国庆高质量出行,可视化开启智慧旅游

ThingJS数字孪生引擎

大前端 物联网 可视化 旅游 数字孪生

容器化的数据科学与工程——第二部分:容器化的数据科学_大数据_张天雷_InfoQ精选文章