数据科学管理指南-全-

数据科学管理指南(全)

原文:annas-archive.org/md5/af2714833a80d52acced588e23e16243

译者:飞龙

协议:CC BY-NC-SA 4.0

序言

数据科学和机器学习可以改变任何组织并开辟新机会。任何数据科学项目都是研究、软件工程和业务专长的独特结合。需要大量的管理工作来指导解决方案从原型开发到生产阶段。传统的方法往往失败,因为它们考虑的条件和要求不同。本书提出了一种经过验证的数据科学项目管理方法,提供了指导您沿途前进的技巧和最佳实践。

在本书的帮助下,您将了解数据科学和人工智能的实际应用,并能够将其融入到您的解决方案中。您将经历数据科学项目的生命周期,探索每个步骤中常见的陷阱,并学习如何避免它们。任何数据科学项目都需要一个平衡且熟练的团队,本书将提供有关如何为您的组织招聘并培养一个高效数据科学团队的有益建议。本书还展示了如何通过使用 DevOps 高效管理和改进您的数据科学项目。

到本书结尾,读者将掌握解决日常工作中遇到的各种挑战所需的实践知识,并了解各种数据科学解决方案。

本书的读者对象

本书面向数据科学家、分析师和程序经理,旨在帮助他们通过高效整合数据科学工作流程,提高组织的生产力并改善业务。对基本数据科学概念的理解将有所帮助。

如何充分利用本书

本书旨在自成一体,适合非技术专业人士阅读。它不假设读者具有数据科学、机器学习和编程的知识。基本的统计学和数学优化理解将有帮助,但并非必需。

由于本书与软件开发、项目管理和 DevOps 方法进行比较,掌握这些主要概念的专业知识将对读者有所帮助。

数据科学项目的理想管理方法远未完成。事实上,它永远不会完美。不存在能够解决每种情况、每个业务问题的“灵丹妙药”。本书没有创建一套僵化复杂的管理流程,而是提供了实用的食谱和建议。我希望它能成为您进入数据科学世界的良好指南,使您的旅程尽可能顺利。

下载彩色图片

我们还提供了一份 PDF 文件,其中包含本书中使用的截图/图表的彩色图像。您可以在此处下载:static.packt-cdn.com/downloads/9781838826321_ColorImages.pdf.

使用的约定

本书中使用了多种文本约定。

CodeInText:表示文中的代码词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟网址、用户输入和 Twitter 账号。例如:“他们还使用了--gitlab标志来运行pyscaffold命令,以便在需要时能拥有一个现成的 GitLab CI/CD 模板。”

代码块设置如下:

├── AUTHORS.rst <- List of developers and maintainers.
├── CHANGELOG.rst <- Changelog to keep track of new features and fixes.
├── LICENSE.txt <- License as chosen on the command-line.
├── README.md <- The top-level README for developers.
├── configs <- Directory for configurations of model & application.
├── data

任何命令行输入或输出如下所示:

pip install -e .

粗体:表示新术语、重要词汇或您在屏幕上看到的词汇。例如,菜单或对话框中的词汇将在文中这样显示。以下是一个示例:“运行中的 Docker 镜像被称为Docker 容器。”

警告或重要说明如下所示。

提示和技巧如下所示。

联系我们

我们始终欢迎读者的反馈。

一般反馈:如果您对本书的任何部分有疑问,请在邮件主题中提及书名,并通过customercare@packtpub.com联系我们。

勘误:虽然我们已尽最大努力确保内容的准确性,但错误仍然可能发生。如果您在本书中发现错误,请告知我们。请访问 www.packtpub.com/support/errata,选择您的书籍,点击勘误提交表单链接,并填写详细信息。

盗版:如果您在互联网上遇到我们作品的任何非法复制品,请提供该材料的位置或网站名称。请通过copyright@packt.com与我们联系,并提供链接。

如果您有兴趣成为作者:如果您在某个领域拥有专长,并且有兴趣撰写或参与编写一本书,请访问 authors.packtpub.com

评论

请留下评论。在您阅读并使用本书后,何不在您购买书籍的网站上留下评论?潜在读者可以参考您的中肯意见来做出购买决策,我们也可以了解您对我们产品的看法,作者们也可以看到您对其作品的反馈。谢谢!

欲了解更多关于 Packt 的信息,请访问 packt.com

第一部分:什么是数据科学?

在深入探讨围绕机器学习算法构建系统的管理问题之前,我们需要先了解数据科学本身。数据科学和机器学习背后的主要概念是什么?如何构建和测试模型?在这个过程中常见的陷阱有哪些?有哪些类型的模型?我们可以通过机器学习解决哪些任务?

本节包含以下章节:

  • 第一章,数据科学可以做什么

  • 第二章,测试你的模型

  • 第三章,理解人工智能

第一章:数据科学可以做什么

我曾经告诉一位做软件开发的朋友关于欧洲最大的数据科学会议之一。他表现出浓厚的兴趣,并问我们是否可以一起去。我说,当然可以。让我们一起拓宽知识面吧。和你讨论机器学习一定会很棒。几天后,我们坐在一个大会议厅的中央。第一位演讲者登上了讲台,向我们讲解了他用来赢得多个数据科学竞赛的技术技巧。当下一位演讲者开始讲解张量代数时,我注意到我朋友眼中露出了一种疲惫的神情。

怎么了? 我问道。

我只是想知道他们什么时候会给我们展示机器人。

为了避免产生错误的期望,我们需要提前做好了解。在建造房屋之前,你最好知道锤子是如何使用的。对于任何管理者来说,了解自己管理的领域是至关重要的。软件开发经理需要理解计算机编程。工厂经理需要了解制造流程。数据科学经理也不例外。本书的第一部分将简单解释数据科学背后的主要概念。我们将一点一点地剖析并探索它。

数据科学变得越来越流行,许多商界人士和技术专家对理解数据科学并将其应用于解决问题的兴趣日益增加。人们通常通过他们收集的背景信息形成对数据科学的初步看法:新闻网站、社交网络等等。不幸的是,大多数这些信息源误导了我们,而不是给出数据科学和机器学习的真实面貌。

媒体并没有进行解释,而是描述了那些能够轻松解决我们所有问题的终极神奇工具。技术奇点就在眼前。普遍基本收入经济即将到来。好吧,前提是机器像人类一样学习和思考。事实上,我们离创造通用的、自我学习和自我改进的算法还远得很。

本章将探讨数据科学主要工具的当前可能性和现代应用:机器 学习深度 学习

在本章中,我们将涵盖以下主题:

  • 定义人工智能

  • 机器学习简介

  • 深度学习简介

  • 深度学习应用案例

  • 因果推断简介

定义人工智能

媒体和新闻将人工智能作为任何与数据分析相关的技术的替代流行词。事实上,人工智能是计算机科学和数学的一个子领域。一切始于 20 世纪 50 年代,当时一些研究人员开始探讨计算机是否能够学习、思考和推理。70 年过去了,我们依然没有答案。然而,我们在一种特定类型的人工智能上取得了显著进展,这种人工智能解决的是明确指定的狭窄任务:弱人工智能

科幻小说讲述了能够像人类一样推理和思考的机器。在科学语言中,它们被描述为强 AI。强 AI 能够像人类一样思考,其智力可能更为先进。创造强 AI 仍然是科学界的长期梦想。然而,实际应用都集中在弱 AI 上。强 AI 试图解决通用智能的问题,而弱 AI 则专注于解决单一的认知任务,例如视觉、语音或听觉。弱 AI 任务的例子种类繁多:语音识别、图像分类和客户流失预测。弱 AI 在我们的生活中扮演着重要角色,改变了我们工作、思考和生活的方式。我们可以在生活的各个领域找到弱 AI 的成功应用。医学、机器人学、市场营销、物流、艺术和音乐等领域都从弱 AI 的最新进展中受益。

定义数据科学

AI 与机器学习有什么关系?什么是深度学习?我们如何定义数据科学?这些热门问题最好通过图示来解答:

这张图包含了本书将讨论的所有技术主题:

  • AI 是一个广泛的科学领域,涵盖了与弱 AI 和强 AI 相关的所有内容。我们不会过多关注 AI,因为大多数实际应用都来自于它的子领域,我们将在接下来的第一章: 什么是数据科学?中对这些子领域进行定义和讨论。

  • 机器学习是 AI 的一个子领域,研究能够根据输入数据自适应其行为的算法,而不需要程序员的明确指令。

  • 深度学习是机器学习的一个子领域,研究一种特定的机器学习模型——深度神经网络。

  • 数据科学是一个多学科的领域,利用一系列工具从数据中提取知识,并支持决策制定。机器学习和深度学习是数据科学的主要工具之一。

数据科学的终极目标是通过从数据中提取知识来解决问题,并为复杂决策提供支持。解决问题的第一步是对其领域有一个良好的理解。在进行风险分析之前,你需要理解保险行业。在设计自动化质量保证流程之前,你需要了解商品制造过程的细节。首先,你需要了解领域。然后,你找到问题。如果跳过这一步,你很可能会解决错误的问题。

在确定了一个好的问题定义后,你开始寻求解决方案。假设你已经创建了一个能够解决任务的模型。一个单纯的机器学习模型通常不会引起任何人的兴趣。所以,它是没用的。为了让它变得有用,我们需要将我们的模型封装成一些能够被看到并且可以付诸实践的东西。换句话说,我们需要围绕模型创建软件。数据科学总是与创建软件系统密切相关。任何机器学习模型都需要软件。没有软件,模型就只是存在于计算机内存中,无法为任何人提供帮助。

所以,数据科学不仅仅是关于科学的。商业知识和软件开发同样重要。没有它们,任何解决方案都不完整。

数据科学的影响

数据科学具有巨大的潜力。它已经在影响我们的日常生活。医疗保健公司正在学习诊断并预测重大健康问题。企业利用它来寻找赢得新客户的新策略并个性化服务。我们在遗传学和粒子物理学中使用大数据分析。多亏了数据科学的进步,自动驾驶汽车如今已成为现实。

多亏了互联网和全球计算机化,我们每天都会创造大量的数据。日益增加的数据量使得我们能够实现人类劳动的自动化。

遗憾的是,对于每一个改善我们生活的应用案例,我们很容易能找到两个让生活变得更糟的例子。举个令人不安的例子,我们来看一下中国。中国政府正在实验一种新的社会信用体系。它使用监控摄像头大规模地追踪公民的日常生活。计算机视觉系统可以识别并记录你在上班通勤、在政府办公处排队、或者在聚会后回家的每一个动作。然后,根据你被监控的行为,计算出一个特殊的社会评分。这个评分会影响真实人的生活。特别是,公共交通费用可能会根据你的评分而变化;低分可能会禁止你申请某些政府工作。

另一方面,这项技术也可以用来帮助人们。例如,它可以用于在人群中追踪罪犯。你如何运用这项新技术,可能会让世界更接近乔治·奥威尔的1984,也可能让世界变得更安全。公众必须更加意识到这些选择,因为它们可能对我们的生活产生持久影响。

机器学习的另一个令人不安的应用案例是,某些企业使用基于机器学习的招聘算法。几个月后,他们发现这些算法引入了对女性的偏见。显而易见,我们没有给予数据科学伦理足够的关注。虽然像谷歌这样的公司创建了内部伦理委员会,但目前对于现代技术的不道德使用仍然没有政府监管。在这种程序到来之前,我强烈建议你考虑使用数据科学的伦理影响。我们都希望生活在一个更好的世界中。我们的未来以及我们孩子的未来,取决于我们每天做出的每一个小决定。

数据科学的局限性

像任何一套工具一样,数据科学也有其局限性。在深入开展一个充满雄心壮志的项目之前,考虑现有的可能性限制非常重要。一个看似容易解决的任务,在实践中可能是无法解决的。

对数据科学技术方面理解不足,可能会导致你项目中的严重问题。你可能会启动一个项目,结果发现根本无法解决任务。更糟糕的是,你可能在部署后才发现,所有的东西都没有按预期工作。根据你的使用场景,这可能会影响到现实中的人。理解数据科学背后的主要原理,将帮助你避免许多技术风险,这些风险可能在项目尚未启动时就已经决定了项目的命运。

机器学习简介

机器学习迄今为止是数据科学家最重要的工具。它使我们能够创建能够发现数据中成千上万变量模式的算法。我们现在将探讨不同类型和功能的机器学习算法。

机器学习是一个研究可以在没有特定指令的情况下,通过依赖数据中发现的模式来执行任务的算法的科学领域。例如,我们可以使用算法来预测得病的可能性或评估复杂制造设备故障的风险。每个机器学习算法都遵循一个简单的公式。在下面的图表中,你可以看到一个基于机器学习算法的高级决策过程。每个机器学习模型都会消耗数据,产生可以支持人类决策或完全自动化的决策的信息:

我们将在下一节中更详细地探讨每个模块的含义。

机器学习模型提供的决策和洞察

在使用机器学习解决任务时,你通常想要自动化决策过程或获取支持决策的见解。例如,你可能希望算法根据患者的病史和当前状况输出一个可能的疾病列表。如果机器学习完全解决了任务,或称“端到端”解决了任务,这意味着算法的输出可以用来做出最终决定,而不需要进一步思考;在我们的例子中,就是自动判断患者所患的疾病并开具合适的药物。这一决策的执行可以是手动的,也可以是自动的。我们说像这样的机器学习应用是端到端的。它们为任务提供了完整的解决方案。让我们以数字广告为例。一个算法可以预测你是否会点击广告。如果我们的目标是最大化点击量,我们可以做出自动化且个性化的决策,决定向每个用户展示哪个具体的广告,从而“端到端”地解决点击率最大化问题。

另一个选择是创建一个算法,提供给你一些见解。你可以将这些见解作为决策过程的一部分。通过这种方式,许多机器学习算法的输出可以参与到复杂的决策制定中。为了说明这一点,我们来看看一个仓库安全监控系统。它监控所有的监控摄像头,并从视频流中识别员工。如果系统无法识别某人是员工,它会发出警报。这个设置使用了两个机器学习模型:人脸检测和人脸识别。首先,人脸检测模型在每一帧视频中寻找人脸。接下来,人脸识别模型通过在面部数据库中搜索来识别某人是否为员工。每个模型都不能单独解决员工识别任务,但每个模型提供了一个见解,作为决策过程的一部分。

机器学习模型的数据

你可能已经注意到,我们示例中的算法处理的是不同类型的数据。在数字广告的例子中,我们使用了结构化的客户数据。而监控系统则使用了来自摄像头的视频流。事实上,机器学习算法可以处理不同类型的数据。

我们可以将全球的数据分为两类:结构化数据和非结构化数据。大多数数据是非结构化的。图像、音频录音、文档、书籍和文章都代表着非结构化数据。非结构化数据是我们现代生活的自然副产品。智能手机和社交网络促使了无尽数据流的产生。如今,你几乎不需要做什么就能拍照或录制视频。分析非结构化数据非常困难,以至于我们直到 2010 年才找到一种实用的解决方案。

结构化数据难以收集和维护,但它是最容易分析的。原因在于我们通常是为此目的收集这些数据。结构化数据通常存储在计算机数据库和文件中。在数字广告中,广告网络投入大量精力收集尽可能多的数据。数据对广告公司来说如黄金般珍贵。他们收集你的浏览历史、点击链接、在页面上停留的时间以及每个用户的许多其他特征。大量的数据使得精确的点击概率模型得以创建,从而个性化你的广告浏览体验。个性化增加了点击概率,从而提高了广告商的利润。

为了增加他们的数据供应,现代企业在构建业务流程时,使得尽可能多的结构化数据得以生成。例如,银行会记录你进行的每一笔金融交易。这些信息对于管理账户是必需的,但它们也作为信用评分模型的主要数据来源。这些模型利用客户的财务档案来估算其违约风险概率。

分析非结构化数据的难度来源于其高维度性。为了说明这一点,我们来看一个包含两列数字的数据表:xy。我们可以说,这个数据有两个维度。

该数据集中的每个值将在以下图表中显示:

正如你所看到的,给定x的值,我们可以准确地猜测出y的值。为此,我们可以查看该点在直线上的对应位置。例如,对于x = 10y将等于8,这与作为蓝点显示的实际数据点相匹配。

现在,让我们转到一张用 iPhone 拍摄的照片。这张图片的分辨率是 4,032 x 3,024 像素。每个像素将有三个颜色通道:红色、绿色和蓝色。如果我们将这张图片中的像素表示为数字,那么每张照片将有超过一千万个像素。换句话说,我们的数据维度达到了 1200 万。

在下面的截图中,你可以看到一个图像,它被表示为一组数字:

在高维数据上使用机器学习算法可能会变得棘手。许多机器学习算法会受到所谓“维度灾难”的困扰。要创建一个能够识别照片中物体的好模型,你需要一个比简单直线更复杂的模型。模型的复杂性增加了模型的数据饥饿,因此,在非结构化数据上表现良好的模型通常需要大量的训练数据样本。

机器学习的起源

在数据科学、机器学习和深度学习出现之前,统计学已经存在。所有与数据分析相关的领域都以统计学为核心。从最初开始,统计学就是许多领域的合金。这是因为统计学旨在解决实际问题。在 17 世纪,统计学家应用数学分析数据,以推断和支持经济和人口统计方面的决策。这听起来不像数据科学吗?有趣的是:第一个机器学习算法——线性回归——是由卡尔·弗里德里希·高斯在 200 多年前发明的。今天我们仍在使用它,并且它的实现存在于所有主要的机器学习和统计软件包中。

高斯发明的最小二乘算法是线性回归的基本形式。线性模型的一般形式要晚得多才引入。

机器学习的解剖学

让我们看看机器学习的常见用例。可以说最常见的用例是预测。预测算法告诉我们什么时候会发生某事,但不一定告诉我们为什么会发生。一些预测任务的例子包括:这位用户下个月会流失吗? 这个人患阿尔茨海默病的风险高吗? 下个小时会发生交通堵塞吗? 通常,我们希望得到解释而不是预测。解推任务意味着通过数据中的支持证据来回答“为什么?”的问题。为什么这个人赢得了选举? 为什么这种药有效而另一种无效? 统计推断帮助我们找到解释或证明我们行动效果的证据。当我们进行推断时,我们寻求对现在或过去的答案。当我们试图展望未来时,预测就成为主角。

有时,我们不关心预测未来或找到证据。我们希望机器能够识别数据中的复杂模式,比如图像中的对象,或者分析文本消息的情感。这组任务被称为识别。

机器学习涵盖了许多类型和模型的风味。但为什么我们需要如此多种不同算法的变体?答案在于一个定理,称为无免费午餐定理。它指出,在每个数据集上每个任务上都能始终给出最佳结果的模型是不存在的。每种算法都有其优点和缺点。它可能在一个任务上无懈可击,但在另一个任务上却表现糟糕。数据科学家的一个最重要目标之一是找到解决手头问题的最佳模型。

你可以用机器学习解决的主要任务类型

无免费午餐定理表明,没有一个模型能够在所有任务上表现良好。这导致我们有许多专门解决特定任务的算法。

例如,我们来看时尚零售仓库的需求预测。零售商在他们的商店里销售一套固定的衣服。在商品上架之前,它必须从制造商处购买并转移到仓库。假设他们的物流周期是两周。我们如何知道每个商品应该订购的最佳数量呢?很可能,我们已经有了每个商店的商品销售数据。我们可以利用这些数据创建一个预测模型,估算下两周内我们仓库中每个商品的平均客户需求。也就是说,我们预测下两周内每个商品的平均购买数量。最简单的模型是将过去两周每个商品的平均需求作为未来需求的估计值。像这样的简单统计模型在实际零售店中经常使用,因此我们不能过于简化。为了更具通用性,我们将我们想要预测的事物称为target变量。在前一个例子中,target变量是需求。为了建立预测模型,我们将使用过去两周的历史数据来计算每个商品的算术平均值。然后,我们用这些平均值作为未来值的估计。某种程度上,历史数据被用来教我们的模型如何预测target变量。当模型通过输入/输出示例学习执行特定任务时,我们称这个过程为监督学习。将我们的平均计算器称为监督学习算法有些夸张,但从技术上讲,没有什么能阻止我们这么做。

监督学习并不限于简单模型。一般来说,模型越复杂,所需的训练数据就越多。训练数据越多,模型就越好。为了说明这一点,我们将深入了解信息安全领域。我们的假想客户是一家大型电信公司。多年来,他们的网络经历了许多安全漏洞。幸运的是,专家记录并彻底调查了所有网络中的欺诈活动。安全专家在网络日志中标记了每一项欺诈活动。拥有大量带标签的训练数据后,我们可以训练一个监督学习模型,来区分正常活动和欺诈活动。这个模型将能够从大量进入的数据中识别出可疑行为。然而,只有专家正确标记了数据,这种情况才会发生。如果他们没有正确标记,模型是无法纠正的。这一原则被称为垃圾进,垃圾出。你的模型只能和你的数据一样好。

零售和安全领域的示例都使用了监督学习,但让我们更仔细地看看target变量。预测算法将需求作为target变量。需求是一个连续的数值,范围从 0 到无穷大。另一方面,安全模型具有固定数量的结果。

网络活动要么是正常的,要么是欺诈性的。我们称第一种类型的target变量为连续型,第二种类型为分类型。target变量的类型强烈指示了我们可以解决的任务类型。具有连续target变量的预测任务称为回归问题。而当结果的总数有限时,我们说我们解决的是分类问题。分类模型将数据点分配到不同类别,而回归模型则估算数量。

下面是一些示例:

  • 房价估算是一个回归任务。

  • 预测用户广告点击是一个分类任务。

  • 预测云存储服务中的硬盘利用率是一个回归任务。

  • 识别信用违约风险是一个分类任务。

如果你找到了一个良好的标注数据集,你可以认为自己很幸运。如果数据集很大,没有缺失标签,并且非常适合解决某个问题的端到端解决方案,那你就更幸运了。我们用于监督学习的标签是一种稀缺资源。完全没有标签的数据集比完全标注的数据集更常见。这意味着我们往往不能使用监督学习。但是没有标签并不意味着我们就注定失败。一个解决方案是手动标注数据。如果数据无法与公司外部共享,你可以将这个任务交给你的员工。如果数据可以共享,另一个更简单、更快捷的解决方案是使用众包服务,如 Amazon Mechanical Turk。在那里,你可以将数据标注外包给大量人群,每个数据点支付一小笔费用。

尽管标注数据很方便,但它并不总是可承受的,有时甚至是不可能的。一个target变量缺失或可以从数据本身推导出来的学习过程叫做无监督学习。虽然监督学习意味着数据已被标注,无监督学习则去除了这一限制,使得算法能够在没有指导的情况下从数据中学习。

例如,营销部门可能希望发现具有相似购买习惯的客户新细分群体。这些洞察可以用来量身定制营销活动,并增加每个细分市场的收入。发现数据集中的隐藏结构的一种方法是使用聚类算法。许多聚类算法可以处理未标注的数据。这一特点使它们特别有趣。

有时,标签隐藏在原始数据中。以音乐创作任务为例。假设我们想创建一个生成新音乐的算法。在这种情况下,我们可以使用监督学习而无需明确的标签。在这个任务中,序列中的下一个音符是一个很好的标签。从一个音符开始,模型预测下一个音符。取前两个音符,它会输出第三个音符。通过这种方式,我们可以根据需要添加任意数量的新音符。

现在,让我们看看是否可以将机器学习应用于游戏。如果我们以单个游戏为例,我们可以标注一些数据并使用监督学习。但将这种方法扩展到所有游戏在实践中是不可行的。在典型的游戏控制台上,你使用相同的控制器玩不同的游戏。试着回想一下你人生第一次玩游戏是什么时候。我猜那是马里奥。很可能你那时不知道该做什么。你可能试着按了一些按钮,看到一个角色跳跃。一步一步,你一定弄清楚了游戏规则并开始玩。我不会感到惊讶,如果你玩了一会儿后能很自信地通关第一关。

利用我们到目前为止获得的知识,我们能否设计出一种机器学习算法,能学会如何玩游戏?也许你会想用监督学习,但先想一想。当你第一次拿起控制器时,你没有任何训练数据。但我们能否创建一种算法,让它自己去弄明白游戏规则呢?

如果我们提前知道规则,为特定的计算机游戏写一个好的机器人是很容易的。几乎所有现代计算机游戏都有基于规则的人工智能或非玩家角色,能与玩家互动。有些游戏甚至有如此先进的人工智能,以至于整个游戏玩法都围绕这一特性展开。如果你感兴趣,可以看看外星人隔离,这款游戏于 2014 年发布。这些算法的最大限制是它们是特定游戏的。它们无法根据经验进行学习和行动。

直到 2015 年,深度学习研究人员发现了一种训练机器学习模型以类似人类的方式玩雅达利游戏的方法:观察屏幕并使用游戏控制器执行动作。唯一的不同是,算法并没有使用物理的眼睛或双手来玩游戏。它通过 RAM 接收每一帧游戏画面,并通过虚拟控制器进行操作。最重要的是,模型在每一帧中都会接收到当前的游戏得分。一开始,模型执行随机动作。有些动作会导致得分增加,并作为正反馈被接收。随着时间的推移,模型学习了输入/输出或帧/动作对,这些对应该获得更高的分数。结果令人震惊。在训练了 75 小时后,模型以业余水平玩打砖块。它没有任何游戏的先验知识,它看到的只是原始像素。过了一段时间后,算法学会了比人类玩得更好。完全相同的模型可以训练来玩不同的游戏。用于训练这些模型的学习框架被称为强化学习。在强化学习中,代理(玩家)学习一个策略(基于输入执行动作的具体方式),以最大化奖励(游戏得分)在一个未知环境(计算机游戏)中。

当然,这也有局限性。记住,在机器学习的餐厅里是没有免费的午餐的。虽然这个算法在大量游戏中表现良好,但在某些游戏中完全失败。特别是名为Montezuma's Revenge的游戏,直到 2018 年之前,它曾让每一个模型都陷入困境。这个游戏的问题在于,你需要在很长时间内执行一系列特定的动作,才能获得一个微小的奖励信号。

为了解决复杂环境中的任务,强化学习算法需要极其庞大的数据量。你可能已经看到过有关 OpenAI Five 模型战胜职业玩家的新闻,这是一款名为Dota 2的复杂多人电子竞技游戏。为了给你一个概念,OpenAI 团队使用了一个由 256 个 GPU 和 128,000 个 CPU 核心组成的集群来训练他们的智能体。每天,这个模型会和自己进行 180 年的对战。这个过程在一个大型计算集群上并行进行,因此实际所需时间要少得多。

另一个强化学习的重大胜利,当然是围棋。围棋的总行动数比我们宇宙中所有原子的总数还要大,这使得这个游戏非常难以用计算机解决。计算机科学家在 1997 年击败了最强的国际象棋选手。对于围棋,他们花费了另外 18 年。如果你感兴趣,谷歌拍摄了一部关于 AlphaGo 的纪录片,AlphaGo 是一个在围棋比赛中战胜世界冠军的算法。

当你可以完全模拟环境时,强化学习表现得很好,也就是说,你提前知道游戏规则。这个“先有鸡还是先有蛋”的问题使得应用强化学习变得棘手。然而,强化学习仍然可以用来解决现实世界中的问题。一组科学家使用强化学习来找到火箭发动机的最佳参数。这得益于发动机内部工作原理的完整物理模型。他们使用这些模型创建了一个仿真环境,在这个环境中,强化学习算法调整发动机的参数和设计,以找到最佳配置。

深度学习简介

在写这一节之前,我思考了许多我们可以在机器学习和深度学习之间划定界限的方式。它们每一个都在某些方面是相互矛盾的。事实上,你无法将深度学习与机器学习分开,因为深度学习是机器学习的一个子领域。深度学习研究一类特定的模型,称为神经网络。神经网络的数学基础第一次被提及可以追溯到 1980 年代,而现代神经网络的理论起源于 1958 年。然而,它们直到 2010 年代才显示出良好的效果。为什么?

答案很简单:硬件。训练大型神经网络需要大量的计算能力。但并不是任何计算能力都足够。事实上,神经网络在后台进行大量的矩阵运算。奇怪的是,渲染计算机图形也涉及许多矩阵运算,甚至如此之多,以至于每台计算机内部都有一个专用电路:GPU。Nvidia 意识到科学对快速矩阵运算的需求,因此开发了一个名为CUDA的专用编程框架。CUDA 不仅可以让你利用 GPU 的计算能力处理计算机图形,还可以用于一般计算任务。GPU 可以执行极为庞大的并行矩阵运算。现代显卡有成千上万的核心,因此可以并行执行成千上万的操作。而且每个操作的执行速度也非常快。现代 GPU 能够执行成千上万的并行浮点计算。GPU 专门针对解决某一特定任务比通用 CPU 更快。

这一切意味着科学家可以训练更大的神经网络。训练大型神经网络的艺术与科学被称为深度学习。深度这个词源于神经网络的特定结构,使得它们在预测中既高效又准确。我们将在第二章《测试你的模型》中更深入地了解神经网络的内部结构,测试你的模型

深度学习在解决非结构化数据集的任务时非常出色。为了说明这一点,我们来看一个名为ImageNet的机器学习竞赛。它包含超过 1400 万张图像,这些图像被分为 22,000 个不同的类别。要解决 ImageNet 问题,一个算法需要学习识别照片中的物体。尽管人类在这一任务上的准确率大约为 95%,但最好的神经网络模型在 2015 年就突破了这一水平。

传统的机器学习算法在处理非结构化数据时表现并不出色。然而,它们同样重要,因为在结构化数据集领域,传统机器学习模型与深度学习模型之间的性能差距并不大。许多数据科学竞赛的获胜者并没有使用深度神经网络,而是使用了更简单的模型,因为这些模型在结构化数据集上表现得更好。这些模型训练速度更快,不需要专用硬件,且消耗的计算能力较少。

更简单的模型并不意味着更容易应用。深度学习在结构化数据上也能取得良好的效果。然而,在实际应用中,可能需要花费更多的时间、金钱和计算能力。简化性指的是内部模型结构和模型中可变参数的数量。

为了区分其他机器学习算法与深度学习,专业人士通常将深度学习称为研究神经网络的领域,而机器学习则用于其他所有模型。将机器学习与深度学习划分开来是不正确的,但由于缺乏更好的术语,业界已达成对模糊定义的共识。

深入自然语言处理

我们每天都在写东西,无论是文档、推文、电子消息、书籍还是电子邮件,列举不胜枚举。使用算法来理解自然语言非常困难,因为我们的语言是模糊的、复杂的,并且包含许多例外和边界情况。最初的自然语言处理NLP)尝试是建立基于规则的系统。语言学家们精心设计了数百、数千条规则,以执行看似简单的任务,如词性标注。

从本节的标题来看,你可能已经猜到,一切都因深度学习而改变。深度学习模型能够在无需明确规定复杂的语法规则和解析器的情况下,执行更多的文本处理任务。深度学习模型席卷了 NLP 界。它们能够比上一代 NLP 模型以更高的质量执行多种 NLP 任务。深度神经网络可以将文本翻译成另一种语言,且接近人类的准确度。它们在进行词性标注时也相当准确。

神经网络在解决理解问题方面也做得很好:问答和文本摘要。在问答中,模型获得一段文本和关于其内容的问题。例如,给定本节的介绍内容,深度学习简介,一个问答模型可以正确回答以下问题:

  • 现代桌面 CPU 有多少个核心?(少于 10 个)

  • 神经网络起源于什么时候?(1980 年代)

文本摘要旨在提取来源中的要点。如果我们将本节的前几段输入到一个文本摘要模型中,我们将得到以下结果:

现在是时候区分机器学习和深度学习了。实际上,我们无法做到这一点,因为深度学习是机器学习的一个子领域。严格来说,深度学习研究一类特定的模型,叫做神经网络。神经网络背后的理论起源于 1980 年代。你可以在textsummarization.net/上试用一个文本摘要模型。

另一个交叉的 NLP 问题是文本分类。通过将许多文本标记为情感正面或负面,我们可以创建情感分析模型。正如你已经知道的那样,我们可以使用监督学习来训练这种模型。情感分析模型在衡量新闻反应或 Twitter 话题标签的整体情绪时,可以提供强有力的洞察。

文本分类也用于解决自动化的电子邮件和文档标签问题。我们可以使用神经网络处理大量的电子邮件,并为其分配合适的标签。

实用自然语言处理(NLP)的巅峰是创建对话系统或聊天机器人。聊天机器人可以用于自动化 IT 支持部门和呼叫中心的常见场景。然而,创建一个能够可靠且一致地解决任务的机器人并非易事。客户倾向于以相当意外的方式与机器人沟通,因此你将面临许多特殊情况需要处理。NLP 研究尚未达到提供能够解决任务的端到端对话模型的阶段。

通用聊天机器人使用多个模型来理解用户的请求并准备答案:

  • 意图分类模型确定用户的请求。

  • 实体识别模型从用户的消息中提取所有命名实体。

  • 响应生成模型从意图分类和实体识别模型获取输入,并生成响应。响应生成器还可以使用知识数据库查找额外信息,以丰富响应内容。

  • 有时,响应生成器会生成多个响应。然后,一个独立的响应排序模型会选择最合适的一个。

NLP 模型还可以根据初始输入生成任意长度的文本。最先进的模型输出的结果可以说与人类写作的文本几乎无法区分。

你可以在 OpenAI 关于 GPT-2 模型的博客文章中查看模型输出样本:openai.com/blog/better-language-models/#sample1

尽管结果非常有说服力,但我们还未找到文本生成模型的有用和实际应用。尽管作家和内容创作者可以通过使用这些模型将要点扩展成连贯的文本,然而不幸的是,这些模型缺乏控制输出的手段,使其在实践中难以使用。

探索计算机视觉

我们已经探索了深度学习如何理解文本。现在,让我们探索深度学习模型如何“看见”世界。2010 年,首次举办了 ImageNet 大规模视觉识别挑战赛。任务是创建一个分类模型,解决识别图像中物体的宏大任务。总共有大约 22,000 个类别可供选择。数据集包含超过 1400 万张标注的图像。如果有人坐下来为每张图像选择前 5 个物体,他们的错误率大约为 5%。

2015 年,一个深度神经网络在 ImageNet 上超越了人类表现。从那时起,许多计算机视觉算法被淘汰。深度学习不仅让我们能够分类图像,还能进行物体检测和实例分割。

以下两张图片有助于描述物体检测和实例分割之间的区别:

上面的照片展示了物体检测模型识别物体并为其加上边框。

在以下图像中,来自 github.com/matterport/Mask_RCNN,我们可以看到实例分割模型找到了物体的精确轮廓:

因此,深度学习在计算机视觉中的主要实际应用本质上是相同的任务,只不过在不同的分辨率级别上进行:

  • 图像分类:从预定的类别集合中确定图像的类别

  • 物体检测:为图像中的物体寻找边框,并为每个边框分配一个类别概率

  • 实例分割:对图像进行逐像素分割,从预定的类别列表中勾画出每个物体的轮廓

计算机视觉算法已经在癌症筛查、手写识别、人脸识别、机器人、自驾车等多个领域找到应用。

计算机视觉的另一个有趣方向是生成模型。虽然我们已经研究过的模型执行的是识别任务,生成模型则可以改变图像,甚至创造全新的图像。风格迁移模型可以改变图像的风格,使其看起来更像另一张图像。此类模型可用于将照片转换为看起来像艺术家作品的画作,具体如下:

训练生成模型的另一种有前景的方法叫做生成对抗网络GANs)。你需要使用两个模型来训练 GANs:生成器和判别器。生成器创建图像,判别器则试图区分真实图像和生成图像。随着时间的推移,生成器学会生成更逼真的图像,而判别器则学会识别图像生成过程中更微妙的错误。这种方法的结果不言而喻。最先进的模型能够生成逼真的人脸,如你可以在 Nvidia 的论文第 3 页中看到,arxiv.org/pdf/1812.04948.pdf。看一下以下的图像。这些照片并不真实,它们是由深度神经网络生成的:

我们还可以使用 GANs 执行条件图像生成。条件一词意味着我们可以为生成器指定一些参数。特别是,我们可以指定生成的物体类型或纹理。例如,Nvidia 的风景生成软件可以将一个简单的色彩编码图像(特定的颜色代表土壤、天空、水面和其他物体)转换为逼真的照片。

深度学习应用案例

为了展示深度学习在实际应用中的工作原理,我们将探讨产品匹配。

最新的定价对于大型互联网零售商至关重要。在竞争对手降低热门产品价格时,反应迟缓会导致巨大的利润损失。如果你知道自己产品目录的正确市场价格分布,你就能始终领先一步,超越竞争对手。要为某个单一产品创建这种价格分布,首先需要在竞争对手的网站上找到该产品的描述。虽然自动收集产品描述很容易,但产品匹配才是难点。

一旦我们拥有大量的非结构化文本,就需要从中提取产品属性。为此,我们首先需要判断两个描述是否指的是同一款产品。假设我们收集了一大批相似产品的描述数据集。如果我们将所有的产品描述进行随机排列,就会得到一个非相似产品描述的数据集。通过大量的相似和不相似产品描述示例,我们可以训练一个自然语言处理模型,用于识别相似的产品描述。我们也可以考虑比较零售商网站上的照片来寻找相似产品。为此,我们可以应用计算机视觉模型来进行匹配。即使有这两种模型,整体匹配精度可能仍然不足以满足我们的需求。提升精度的另一种方法是从文本描述中提取产品属性。我们可以训练词标注模型,或者开发一套匹配规则来完成这一任务。随着我们使用的数据源的多样性和描述性增加,匹配精度也会提高。

因果推断简介

到目前为止,我们讨论了预测模型。预测模型的主要目的是识别和预测,模型推理背后的解释优先级较低。相反,因果推断试图解释数据中的关系,而不是预测未来事件。在因果推断中,我们检查某个行为的结果是否并非由所谓的混杂变量(confounding variables)引起。这些变量可能通过结果间接影响行为。让我们通过几个问题来比较因果推断和预测模型,它们能够帮助回答的问题包括:

  • 预测模型:

    • 我们的销售什么时候会翻倍?

    • 这个客户购买某个特定产品的概率是多少?

  • 因果推断模型:

    • 这种癌症治疗有效吗?或者这个效果仅仅是由于数据中变量之间复杂的关系所导致的?

    • 我们的新版本推荐模型是否比旧版更好?如果是,它能比旧模型提高多少销售额?

    • 什么因素导致某些书籍成为畅销书?

    • 什么因素导致阿尔茨海默病?

在统计学界有一句名言:相关性不代表因果性。如果某些变量一起变化或具有相似的值,并不意味着它们以某种逻辑方式连接在一起。现实数据中有许多荒谬的非理性相关性实例,可以参考www.tylervigen.com/spurious-correlations

请看以下截图中的例子:

一些发现既让人困惑,又充满幽默感:

在数据驱动的决策影响到人们的生命时,寻找解释和衡量效果变得尤为重要。具体来说,当一种新药问世时,我们需要确认它是否真的有效。为了做到这一点,我们需要收集数据,并衡量使用新药与不使用新药的统计效果。

因果推断以一种相当雄心勃勃的方式提出了这个问题:衡量某种治疗效果的最简单方法是将我们的世界分成两部分。在第一部分,我们不应用治疗,假装该药物从未被发现。在第二部分,我们应用新治疗。不幸的是,创建新的宇宙远远超出了统计学家的能力范围。但他们提出了一个推理框架,允许你设计实验并收集数据,就像它们来自两个独立的宇宙。

最简单的方法是进行随机化实验:

  1. 首先,我们将从全球范围内随机抽取一个测试组。

  2. 然后,每个人会被随机分配到新药物或安慰剂(糖丸)中,概率为 50%。

  3. 一段时间后,我们可以衡量两个组之间治疗效果的差异。

像这样的研究执行起来非常复杂。试想每次需要测试一种新药物时,你都要从全世界的人群中随机抽取样本。而且,你不能把所有人都带到同一个地方,因为环境或气候的突然变化可能会影响治疗结果。如果治疗伴随有死亡风险,这项实验可能也会被视为不道德。因果推断可以让你设计更复杂的实验方案,并且在特定条件下,这些方案依然等同于随机实验。通过这种方式,你可以设计出既符合伦理又切实可行的研究,且具备统计学严谨性。

因果推断的另一个重要特性是它有一套可以在观察性数据上工作的技术。进行假设检验的实验并非总是可行的。因果推断可以用来将预测模型应用于测量未专门为此目的收集的观察性数据的效果。例如,我们可以使用客户数据来衡量和量化营销活动的效率。观察性研究执行起来很方便,因为它们不需要实验设置。然而,它们只能为你提供关于真实因果关系的强有力的推测。在做出数据驱动的决策之前,始终建议设计并进行一个适当的实验。

对测试组应用治疗的框架非常一般。它不仅限于医学研究,还可以衡量和解释任何变化的效果。问题——使用机器学习模型比完全不使用更好吗? 如果是,它带来多少好处? 常常占据数据科学家的心思。得益于因果推断,我们可以找到解决方案。在这个问题中,你可以将机器学习模型替换为治疗。

衡量真实效果的唯一方法是对真实用户测试这两种方法。虽然在物理世界中很难进行,纯随机实验在互联网上却相对简单。如果你在一家拥有大量客户的大型互联网公司使用机器学习模型,设计一个随机实验似乎很容易。你可以随机将软件的两个不同版本分配给每个用户,直到收集到足够大的数据样本。

然而,你应该警惕许多可能扭曲结果的因素:

  • 数据中的隐藏偏差被称为混杂因素。客户的生活方式、社会因素或环境暴露可能会影响你看似随机的用户样本。

  • 测试组选择中的缺陷称为选择偏差。例如,从单一地区随机选择测试参与者可能会影响研究结果。

  • 测量误差:错误或不一致的数据收集可能会导致误导性结果

总结

在本章中,我们探讨了人工智能、数据科学、机器学习、深度学习和因果推断的实际应用。我们将机器学习定义为一个研究使用数据支持决策并提供洞察的算法领域,而不依赖于具体指令。机器学习有三种主要方法:监督学习、无监督学习和强化学习。在实际应用中,使用机器学习解决的最常见任务是回归和分类。接下来,我们将深度学习描述为机器学习的一个子集,专注于研究神经网络算法。深度学习的主要应用领域是计算机视觉和自然语言处理(NLP)。我们还涉及了一个重要的话题——因果推断:研究用于发现数据中因果关系的一系列方法的领域。现在你已经对一般的数据科学能力有了深入了解。那么,机器学习模型能否成功解决你的特定问题呢?

在下一章,我们将通过进行模型测试来学习区分好的解决方案和不好的解决方案。

第二章:测试你的模型

如果你不使用好的测试方法,提出一个完美的机器学习模型并不简单。这个看似完美的模型会在你部署它的那一刻失败。测试模型的性能并非易事,但它是每个数据科学项目的必不可少的一部分。如果没有适当的测试,你无法确定模型是否能按预期工作,也无法选择最合适的方法来解决当前任务。

本章将探讨各种模型测试方法,并查看不同类型的度量标准,使用数学函数来评估预测的质量。我们还将介绍一套用于测试分类器模型的方法。

本章将涵盖以下主题:

  • 离线模型测试

  • 在线模型测试

离线模型测试

离线模型测试包括所有在模型部署之前进行的模型评估过程。在详细讨论在线测试之前,我们必须首先定义模型误差及其计算方法。

理解模型误差

每个模型都可能出错,因为收集的数据和模型本身都对问题的本质产生了影响。一个优秀模型的最佳例子就是你的大脑。你在实时使用建模——大脑通过解读眼睛记录的电磁脉冲来渲染你所看到的一切。虽然这种世界的图像并不完美,但它很有用,因为我们通过视觉通道接收到超过 90%的信息。剩下的 10%来自听觉、触觉和其他感觉。因此,每个模型M都试图通过猜测来预测真实值Y,![]。

真实值与模型近似值之间的差异构成了模型误差:

对于回归问题,我们可以衡量模型预测的量值误差。例如,如果我们使用机器学习模型预测房价,并且预测结果为$300,000,而实际价格为$350,000,我们可以说误差为$350,000 - $300,000 = $50,000。

对于分类问题,在最简单的设定下,我们可以将猜测的错误值设为 0,错误答案设为 1。例如,对于一个猫/狗识别器,如果模型预测一张狗的照片里有猫,则错误值为 1;如果给出了正确答案,则错误值为 0。

分解误差

你不会找到一个能够完美解决问题且没有任何错误的机器学习模型,无论这个错误多么微小。由于每个模型都会出错,理解这些错误的本质至关重要。假设我们的模型进行了预测,并且我们知道真实值。如果这个预测不正确,那么预测值与真实值之间就存在差异:

这种误差的另一部分来源于我们数据的缺陷,还有一些来自模型的缺陷。无论我们的模型多复杂,它只能减少建模误差。不可约误差超出了我们的控制范围,因此得名。

让我们在以下公式中来看它:

并非所有可约错误都是相同的。我们可以进一步分解可约错误。例如,看看下面的图:

每个目标的红色中心表示我们的目标(真实值),而蓝色的点表示模型的预测值。在目标中,模型的瞄准偏差——所有预测值都很接近,但远离目标。这样的误差被称为偏差。我们的模型越简单,偏差越大。对于简单的模型,偏差成分可能占主导地位:

在前面的图表中,我们尝试通过一条简单的直线来建模变量之间的复杂关系。这种模型具有较高的偏差。

模型误差的第二个成分是方差

所有的预测值似乎都聚集在真实目标附近,但散布太广。这种误差的来源是模型对数据波动的敏感性。如果模型具有高方差,测量中的随机性会导致非常不同的预测结果。

到目前为止,我们已经将模型误差分解成了以下三个部分:

偏差和方差出现在同一公式中并非偶然,它们之间存在关系。预测模型展示了一种叫做偏差-方差 权衡的特性——模型的偏差越大,误差中的方差成分就越小;反之,方差越大,偏差就越小。这个重要的事实将对构建集成模型产生深远影响,我们将在第三章 理解 AI中进行探讨。

通常,施加某种数据结构的模型具有较高的偏差(它们假设数据遵循某些规律)。偏差模型表现良好,只要数据不与模型的基本逻辑相矛盾。举个例子,想象一下一个简单的直线模型。例如,我们将房价预测为其平方英尺大小的线性函数:

注意,如果我们稍微改变一下面积,比如 0.1,那么预测结果不会有太大变化。因此,这个模型的方差很低。当模型对输入的变化敏感时,其方差会超过偏差。随着模型复杂度的增加和参数总数的增多,方差成分会增加。在下图中,你可以看到两个不同的模型如何拟合相同的数据集。第一个简单模型具有低方差,第二个复杂模型具有高方差:

在前面的图中,X 的微小变化可能导致 Y 的大幅波动。具有高方差的模型是鲁棒的,并且意味着数据结构较少。

理解过拟合

偏差-方差权衡与机器学习中的一个非常重要的问题密切相关,叫做过拟合。如果你的模型太简单,它会导致较大的误差。如果它过于复杂,它会过于记忆数据。一个过拟合的模型记住数据太好,像一个数据库一样工作。假设我们的住房数据集包含一些幸运的交易,其中之前的房屋因某些数据未捕捉的情况而价格较低。一个过拟合的模型会过于紧密地记住这些例子,并在未见数据上预测错误的价格值。

现在,理解了误差分解后,我们能否将其作为设计模型测试管道的基石?

我们需要确定如何测量模型误差,以使其能够反映模型在未见数据上的实际表现。答案来自问题本身。我们将把所有可用数据分成两组:训练集和测试集,如下图所示:

我们将使用训练集中的数据来训练我们的模型。测试集作为未见数据,你不应该在训练过程中使用测试集。当模型训练完成后,你可以将测试数据输入到模型中。现在你可以计算所有预测的误差。由于模型在训练过程中没有使用测试数据,因此测试集误差代表了模型在未见数据上的误差。这种方法的缺点是,你需要花费大量的数据,通常是多达 30%,来用于测试。这意味着训练数据减少,模型质量也会降低。还有一个警告——如果你过度使用测试集,误差度量可能会开始失真。例如,假设你做了以下操作:

  1. 训练一个模型

  2. 在测试数据上测量误差

  3. 改进模型以提高指标

  4. 重复步骤 1-3 十次

  5. 部署模型到生产环境

您的模型质量可能远低于预期。这是为什么呢?让我们更仔细地看看第 3 步。您查看了一个评分,并多次更改了您的模型或数据处理代码。事实上,您进行了几次手动学习迭代。通过反复提高测试得分,您间接地将测试数据的某些信息泄漏到了您的模型中。当在测试集上测得的指标值与实际数据上的指标值偏离时,我们称测试数据已经泄漏到我们的模型中。数据泄漏在造成损害之前往往很难察觉。为了避免数据泄漏,您应该时刻关注泄漏的可能性,批判性地思考,并遵循最佳实践。

我们可以使用独立的数据来防止测试集泄漏。数据科学家使用验证集来调整模型参数,并在选择最佳模型之前比较不同的模型。然后,测试数据仅作为最终检查,告知您模型在未见过的数据上的质量。在您测量了测试指标得分之后,唯一剩下的决定就是是否将模型投入真实世界的测试场景。

在下面的截图中,您可以看到数据集的训练/验证/测试划分示例:

不幸的是,当我们使用这种方法时,以下两个问题仍然存在:

  • 我们的测试集信息在多次迭代后可能仍然会泄漏到我们的解决方案中。即使使用了验证集,测试集泄漏也不会完全消失,它只是变得更慢。为了解决这个问题,您应该定期更换测试数据。理想情况下,每次模型部署周期时都应创建一个新的测试集。

  • 由于训练-评估-修改的反馈循环,您可能很快会对验证数据过拟合,以调整您的模型。

为了防止过拟合,您可以为每次实验随机选择训练集和验证集。将所有可用数据随机打乱,然后按照您选择的比例将数据划分为三部分,随机选择训练集和验证集。

对于训练、验证和测试数据的使用量没有通用规则。通常,更多的训练数据意味着更准确的模型,但这也意味着您将拥有更少的数据来评估模型的性能。对于中等大小的数据集(最多 100,000 个数据点),典型的划分是将 60-80%的数据用于训练模型,其余数据用于验证。

对于大型数据集,情况有所不同。如果您的数据集有 10,000,000 行,使用 30%作为测试集将包含 3,000,000 行数据。这个数量可能会过多。增加测试和验证集的大小将带来边际效益递减。对于某些问题,使用 100,000 个测试样本就能获得良好的结果,这相当于 1%的测试比例。数据越多,您用于测试的比例应该越低。

经常会遇到数据过少的情况。在这些情况下,使用 30%-40% 的数据进行测试和验证可能会显著降低模型的准确性。你可以在数据稀缺的情况下使用一种叫做交叉验证的技术。使用交叉验证时,不需要创建单独的验证集或测试集。交叉验证按以下方式进行:

  1. 你选择一个固定的迭代次数——例如,选择三次。

  2. 将数据集分成三部分。

  3. 对于每次迭代,交叉验证使用 2/3 的数据集作为训练数据,1/3 作为验证数据。

  4. 为每一对训练-验证集训练模型。

  5. 使用每个验证集计算指标值。

  6. 将所有指标值取平均,汇总成一个单一的数值。

以下截图以可视化的方式解释了交叉验证:

交叉验证有一个主要缺点:它需要显著更多的计算资源来评估模型质量。在我们的例子中,为了做一次评估,我们需要训练三个模型。而使用常规的训练/测试拆分,我们只需要训练一个模型。此外,交叉验证的准确性会随着迭代次数(也叫折数)的增加而提高。所以,交叉验证使你能够使用更多的数据进行训练,同时需要更多的计算资源。那么,我们如何在交叉验证和训练-验证-测试拆分之间做选择呢?

在交叉验证中, ![] 是由数据科学家设置的一个变量参数。最小值为 1,相当于一个简单的训练/测试拆分。最大值是 ![],即数据集中数据点的数量。这意味着如果我们有 ![] 个数据点,模型将被训练和测试 ![] 次。这个特殊的交叉验证情况叫做留一交叉验证。理论上,更多的折数意味着交叉验证会返回更准确的指标值。虽然留一交叉验证是最理论上准确的方法,但由于巨大的计算需求,它在实践中很少使用。实际上, ![] 的值通常在 3 到 15 折之间,具体取决于数据集的大小。你的项目可能需要使用更多的折数,所以把这个作为建议,而不是规则。

以下表格总结了一种常见的思考方式:

模型训练需要低到中等的计算资源和时间 模型训练需要大量计算资源并且耗时较长
小到中型数据集 交叉验证 任意
大数据集 任意 训练/验证/测试拆分

另一个与模型测试相关的重要方面是如何拆分数据。稍有错误的拆分逻辑可能会导致你所有的测试工作都白费。如果数据集中的所有观测值都是独立的,那么拆分就很简单。你可以使用随机数据拆分。但如果我们正在解决股票价格预测问题呢?当我们的数据行与时间相关时,我们不能将它们视为独立的值。今天的股价依赖于过去的股价。如果这不成立,股价就会随机从$0 跳到$1,000。在这种情况下,假设我们有两年的股票数据,从 2017 年 1 月到 2018 年 12 月。如果我们使用随机拆分,可能会出现模型在 2018 年 9 月训练,而在 2017 年 2 月进行测试的情况。这是毫无意义的。我们必须始终考虑观测值之间的因果关系和依赖性,并确保验证过程是正确的。

接下来,我们将学习关于指标的知识,它是我们用来总结验证和测试误差的公式。指标将使我们能够比较不同的模型,并选择最适合生产使用的候选模型。

使用技术指标

每个模型,无论多么复杂和精确,都不可避免地会犯错。我们自然会期望一些模型在解决特定问题时比其他模型表现更好。目前,我们可以通过将各个模型的预测与真实值进行比较来衡量误差。将这些误差总结成一个数字来衡量模型的表现会很有用。我们可以使用一个指标来实现这一点。不同的机器学习问题适合使用不同种类的指标。

特别地,对于回归问题,最常见的指标是均方根误差,或称RMSE

让我们来看看这个公式的各个元素:

  • N 是数据点的总数。

  • 预测值 - 实际值 衡量了地面真相和模型预测之间的误差。

  • 公式开头的 Sigma 符号表示求和。

另一种常用的回归误差衡量方法是平均绝对误差MAE):

请注意,MAE 与 RMSE 非常相似。与 MAE 相比,RMSE 的区别在于它使用平方根而不是绝对值,并且它会对误差进行平方。尽管 MAE 和 RMSE 看起来很相似,但它们之间还是存在一些技术性差异。数据科学家可以根据问题的需求选择最合适的指标,了解各个指标的权衡和局限性。你不需要学习所有的指标,但我希望强调一个差异,以便让你大致理解思考过程。RMSE 对大误差的惩罚比 MAE 更严重。这一特性来自于 RMSE 使用平方误差,而 MAE 使用绝对值。举个例子,MAE 中的误差为 4,而 RMSE 中的误差则会变成 16,因为它要进行平方计算。

对于分类问题,指标计算过程更为复杂。假设我们正在构建一个二分类器,用于估计一个人是否患有肺炎。为了计算模型的准确性,我们可能只需将正确答案的总数除以数据集中的行数:

在这里,![]是正确预测的数量,而![]是总的预测数量。准确率简单易懂且容易计算,但它有一个重大缺陷。假设患有肺炎的平均概率是 0.001%。也就是说,每 10 万人中只有一个人得病。如果你收集了 20 万人数据,那么数据集中可能只有两个阳性病例。假设你要求数据科学家构建一个基于患者数据来估计肺炎概率的机器学习模型,并且你要求准确率不低于 99.9%。假设某人创建了一个虚拟算法,始终输出零。

这个模型没有实际价值,但它在我们的数据上的准确性会很高,因为它只会犯两个错误:

问题在于准确率仅考虑答案的全局比例。当某个类别的数量远超其他类别时,准确率会输出误导性的值。

让我们通过构建混淆矩阵来更详细地查看模型预测:

模型预测:****有肺炎 模型预测:****没有肺炎
实际结果:****有肺炎 0 2
实际结果:****没有肺炎 0 199,998

通过查看这个表格,我们可以看到,虚拟模型对任何人都没有帮助。它没有将两个有病的人判定为阳性。我们称这些错误为假阴性FN)。该模型也正确地识别了所有没有肺炎的患者,或者说是真阴性TN),但它未能正确诊断出生病的患者。

现在,假设你的团队已经构建了一个真实的模型,并得到了以下结果:

模型预测:****有肺炎 模型预测:****没有肺炎
实际结果:****有肺炎 2 0
实际结果:****没有肺炎 30 199,968

这个模型正确地识别了两个病例,做出了两个真阳性TP)预测。这相较于之前的版本有了明显的改进。然而,模型也将 30 个实际没有肺炎的人误判为有肺炎。我们称这种错误为假阳性FP)预测。那么,30 个假阳性是否是一个显著的缺点呢?这取决于医生如何使用这个模型。如果所有被诊断的人都会被自动开具带有副作用的重药,假阳性就可能是一个严重问题。

如果我们仅将正向模型视为患病的可能性,情况可能没有那么严重。如果正向模型的回答仅表示患者必须经过一组特定的诊断程序,那么我们就能看到一个好处:为了达到相同的肺炎识别水平,治疗师只需要诊断 32 个患者,而之前需要检查 200,000 个案例。如果我们没有使用混淆矩阵,可能会错过模型的不良行为,这可能对人们的健康造成负面影响。

接下来,你的团队进行了另一个实验,并创建了一个新模型:

模型预测: 有肺炎 模型预测: 没有肺炎
实际结果: 有肺炎 0 2
实际结果: 没有肺炎 100,000 99,998

这个模型表现得更好吗?该模型可能会漏掉一个需要治疗的患者,同时将 100,000 个健康人分配到治疗组,导致医生做不必要的工作。实际上,只有在将结果展示给最终使用该模型的人之后,你才能做出最终决策。他们可能对什么是最佳选择有不同的看法。最好在项目的初期阶段通过与该领域的专家合作,创建一个模型测试方法文档来定义这一点。

你将在各个地方遇到二分类问题,因此对术语的良好理解非常重要。

你可以在下面的表格中看到所有新概念的总结:

模型预测: 1(阳性案例) 模型预测: 0(阴性案例)
实际结果: 1(阳性案例) 真阳性(TP) 假阴性(FN)
实际结果: 0(阴性案例) 假阳性(FP) 真阴性(TN)

需要特别注意的是,你可以控制单个模型的假阳性和假阴性反应的数量。分类器输出一个数据点属于某一类别的概率。也就是说,模型的预测是一个介于 0 和 1 之间的数字。你可以通过将其与阈值进行比较来决定一个预测是否属于正类或负类。例如,如果阈值是 0.5,则任何大于 0.5 的模型预测都属于类别 1,否则属于类别 0。

通过改变阈值,你可以改变混淆矩阵中各单元格之间的比例。选择一个较大的阈值,比如 0.9,假阳性反应的数量会减少,但假阴性反应的数量会增加。阈值选择对于二分类问题至关重要。一些环境,比如数字广告,对于假阳性会更宽容,而在其他环境中,比如医疗保健或保险,假阳性可能是无法接受的。

混淆矩阵为分类问题提供了深刻的洞察,但需要你投入时间和精力。这在你希望进行大量实验并比较许多模型时可能成为限制。为了简化这个过程,统计学家和数据科学家设计了许多度量方法,可以在不遇到像准确率度量那样的问题的情况下总结分类器的性能。首先,让我们检查一些总结混淆矩阵行和列的方法。然后,我们将探索如何将其浓缩为一个单一的统计量。

在下表中,你可以看到两种新的度量,用于总结不同类型的错误,精确度和召回率:

模型预测:1正类**) 模型预测:0负类**) 综合度量
实际结果:1正类**) 真正例 假负例
实际结果:0负类**) 假正例 真负例
综合度量 ,也称为真正例率TPR

精确度衡量你的模型识别出的正类(相关)案例的比例。如果模型预测了 10 个正类案例,并且其中 2 个预测为正类的实际情况为负类,那么它的精确度为 0.8。召回率表示正确预测正类案例的概率。如果在 10 个正类案例中,模型正确预测了全部 10 个(10 个真正例),并将 5 个负类案例错误标记为正类(5 个假正例),那么它的召回率为 0.67。召回率为 0.67 意味着,如果我们的模型预测正类案例,它将在 100 次预测中有 67 次是正确的。

对于二分类,精确度和召回率将我们必须处理的度量缩减为两个。这是更好的,但仍不是理想的。我们可以通过使用一种称为F1-score的度量,将所有内容汇总为一个单一的数值。你可以使用以下公式计算 F1:

F1 对于完美分类器为 1,对于最差的分类器为 0。由于它同时考虑了精确度和召回率,它不会像准确率那样存在相同的问题,因此它是分类问题的更好默认度量。

更多关于不平衡类别的信息

在前面的示例中,你可能已经注意到,许多预测问题存在一种现象,即某一类出现的频率远高于其他类。识别癌症等疾病、估算信用违约的概率或检测金融交易中的欺诈行为都是不平衡问题的例子——正例远少于负例。在这种情况下,评估分类器性能变得很棘手。像准确率这样的指标开始显得过于乐观,因此你需要依赖更先进的技术指标。在这种情境下,F1 得分提供了更为真实的数值。然而,F1 得分是从类别分配(在二分类情况下为 0 或 1)计算得出的,而不是类别概率(在二分类情况下为 0.2 和 0.95)。

大多数机器学习模型输出的是某个样本属于某个类别的概率,而不是直接的类别分配。特别是,癌症检测模型可能会基于输入数据输出一个 0.32(32%)的疾病概率。然后,我们必须决定是否将患者标记为患有癌症。为此,我们可以使用阈值:所有低于或等于该阈值的值将被标记为 0(没有癌症),而所有大于该阈值的值将被标记为 1(患有癌症)。阈值会极大地影响结果模型的质量,尤其是对于不平衡数据集。例如,较低的阈值可能会导致更多的 0 标签,然而这种关系并不是线性的。

为了说明这一点,我们可以使用一个训练好的模型并为测试数据集生成预测。如果我们通过设置不同的阈值来计算类别分配,然后为每个类别分配计算精度、召回率和 F1 得分,我们可以在单一图表中描绘出每个精度和召回率值:

上面的图表是使用yellowbrick库制作的,该库包含许多用于模型选择和解释的有用可视化工具。你可以在这里看到这个库的功能:www.scikit-yb.org/en/latest/index.html

在上面的图表中,你可以看到每个阈值(从 0 到 1 之间)对应的精度(蓝色)、召回率(绿色)和 F1 得分(红色)。根据这个图表,我们可以看到 0.5(这是许多机器学习库中的默认值)可能不是最好的选择,像 0.45 这样的阈值可能会产生更为优化的指标值。

图中展示的另一个有用概念是队列率(以品红色显示),它表示在测试数据集中被标记为正类的实例所占比例。对于 0.45 的阈值(图中以虚线表示),你可以看到队列率为 0.4。也就是说,大约 40%的所有案例将被标记为欺诈。根据模型将被使用的业务流程,正类案例可能需要进一步由人工调查。在某些情况下,人工检查会消耗大量时间或资源,但对于更低的队列率,误判一些正类实例是可以接受的。在这种情况下,即使模型性能较低,你可能也会选择队列率更低的模型。

所有关于精确度、召回率和阈值的信息可以进一步总结为一个叫做精确度-召回率曲线下的面积PR AUC)的单一数值。这个指标可以用来快速判断大量不同模型,而无需手动评估模型在不同阈值下的质量。另一个常用于二分类器评估的指标是受试者工作特征曲线下的面积ROC AUC)。通常情况下,你会希望在数据集不平衡时使用 PR AUC,在数据集平衡时使用 ROC AUC。

这种差异来自于这些指标的计算方式,但为了简洁起见,我们将在这里省略技术细节。计算 AUC 指标比本章介绍的其他指标要复杂一些。欲了解更多信息,请查看www.chioka.in/differences-between-roc-auc-and-pr-auc/en.wikipedia.org/wiki/Receiver_operating_characteristic

选择精确度、召回率、F1 值和队列率的合适平衡并没有固定的规则。这些值应该根据业务流程进行深入的调查。单纯依赖技术指标来选择模型可能会导致灾难,因为最适合你的客户的模型不一定是最准确的模型。在某些情况下,高精确度可能比召回率更为重要,而在其他情况下,队列率可能是最重要的。在这种情况下,我们需要引入另一种指标,它将充当技术指标和业务需求之间的桥梁:业务指标。

应用业务指标

尽管技术指标在模型开发过程中至关重要,但它们并不适用于商业语言。充满混淆表格和 F1 分数的数据,通常难以打动你的客户或利益相关者。他们更关心的是模型能解决什么问题,而不是其内部细节。他们不会对假阳性率感兴趣,但如果你提到模型在下个季度能为他们节省多少资金,他们会愿意听。因此,设计商业指标非常重要。你的项目需要一个对所有关键利益相关者(无论是否具备数据科学经验)都非常清晰的质量衡量标准。如果你身处商业环境,开始的好方法是看看你通过机器学习试图改进的业务流程的关键绩效指标KPI)。你很可能会找到一个现成的商业指标。

在这一点上,我们总结了技术指标的介绍。测试分类和回归模型的方法有很多,每种方法都有其优缺点。列举并描述所有这些方法将需要一本书的篇幅,而且没有必要,因为我们已经达到了目标。通过本章的新概念,你现在已经理解了如何在实际条件下测试之前评估机器学习模型的一般流程。现在,你可以使用离线模型测试来检查模型的质量,然后再进行部署。接下来,我们将探索在线测试,以完善你对模型质量评估的理解。

在线模型测试

即使是一个优秀的离线模型测试流程,也无法保证模型在生产环境中的表现完全相同。总是有一些风险会影响模型的性能,比如以下几种:

  • 人类:我们会犯错误,并可能在代码中留下 bug。

  • 数据收集:选择性偏差和不正确的数据收集程序可能会破坏真实的指标值。

  • 变化:现实世界中的数据可能会发生变化,偏离你的训练数据集,从而导致模型出现意外的行为。

在不久的将来,确认模型性能的唯一方法是进行实时测试。根据环境的不同,此类测试可能会带来很大的风险。例如,评估飞机发动机质量或病人健康状况的模型,在我们对其性能没有足够信心之前,是不适合进行实际测试的。

当进行现场测试时,你将希望在得出统计有效结论的同时,最小化风险。幸运的是,为此目的存在一种统计框架,称为假设检验。在进行假设检验时,你通过收集数据并执行统计测试来检查某个想法(假设)的有效性。假设你需要检查你的新广告模型是否增加了广告服务的收入。为此,你将所有客户随机分成两组:一组使用旧的广告算法,另一组则看到由新算法推荐的广告。收集了足够的数据后,你会比较这两组并衡量它们之间的差异。你可能会问,为什么我们需要去麻烦统计学呢?

因为我们只能借助统计学回答以下问题:

  • 我应该如何将个体排序(抽样)到每个组别中?我的抽样过程会扭曲测试结果吗?

  • 每个组别的最小客户数量是多少?数据中的随机波动会影响我的测量结果吗?

  • 我应该运行测试多长时间才能得出一个有信心的答案?

  • 我应该使用什么公式来比较每个组别中的结果?

假设检验的实验设置故意将目标分为两组。我们也可以尝试只使用单组。举例来说,我们可以先用旧模型做一组测量。第一部分实验结束后,再部署新算法并测量其效果。然后,我们比较两个连续测量之间的差异。可能会出现什么问题?事实上,我们得到的结果并没有什么意义。我们的测量之间可能发生了许多变化,比如以下这些:

  • 用户偏好

  • 用户的整体情绪

  • 我们服务的受欢迎程度

  • 平均用户画像

  • 用户或企业的其他任何属性

所有这些隐藏的影响因素可能以不可预测的方式影响我们的测量结果,这就是为什么我们需要两个组别:实验组和对照组。我们必须以这样的方式选择这些组别,确保它们之间的唯一区别就是我们的假设。假设应该出现在实验组中,而在对照组中缺失。例如,在医学试验中,对照组是那些接受安慰剂的人。假设我们想测试一种新止痛药的正面效果。以下是一些不良测试设置的例子:

  • 对照组仅由女性组成。

  • 实验组和对照组位于不同的地理位置。

  • 你使用偏见性采访来预先选择实验参与者。

创建组别的最简单方法是随机选择。真正的随机选择在现实世界中可能很难实现,但如果你处理的是互联网服务,这就很容易了。在那里,你可以随机决定每个活跃用户使用哪一版本的算法。务必始终与经验丰富的统计学家或数据科学家共同设计实验设置,因为正确的测试执行起来非常困难,尤其是在离线环境中。

统计检验验证原假设的有效性,即你获得的结果是否是偶然的。相反的结果称为备择假设。例如,这是我们广告模型测试的假设设置:

  • 原假设:新模型不会影响广告服务收入。

  • 备择假设:新模型会影响广告服务收入。

通常,统计检验衡量原假设为真的概率。如果这种概率很低,那么备择假设为真。否则,我们接受原假设。如果根据统计检验,新的模型不会影响服务收入的概率为 5%,那么我们会在 95%的置信水平下接受备择假设。这意味着模型以 95%的概率影响广告服务收入。拒绝原假设的显著性水平取决于你愿意承担的风险级别。对于广告模型,95%的显著性可能足够,而对于测试患者健康状况的模型,则需要不低于 99%的显著性。

最典型的假设检验是比较两个均值。如果我们在广告模型示例中使用此检验,我们将测量新排名算法前后的平均收入。实验结束后,我们可以通过检验统计量来接受或拒绝原假设。

进行假设检验所需收集的数据量取决于多个因素:

  • 置信水平:你需要的统计置信度越高,所需的数据量就越大,以支持证据。

  • 统计功效:这衡量了在存在显著差异时检测到该差异的概率。你的测试统计功效越高,出现假阴性结果的概率越低。

  • 假设差异和总体方差:如果你的数据方差很大,你需要收集更多的数据以检测显著差异。如果两个均值之间的差异小于总体方差,你则需要更多的数据。

你可以通过以下表格看到不同测试参数如何决定它们对数据的需求:

置信水平 统计功效 假设差异 总体方差 推荐样本量
95% 90% $10 | $100 22 次广告展示给客户
99% 90% $10 | $100 30 次广告展示给客户
99% 90% $1 | $100 2,976 次广告展示给客户

尽管假设检验功能强大,但它也有局限性:你需要等到实验结束后才能应用其结果。如果你的模型很差,就无法在不妥协测试过程的情况下减少损害。另一个局限是,每次只能用单一的假设检验来测试一个模型。

在可以权衡统计严谨性、速度和风险规避的情况下,有一种替代方法叫做 多臂老丨虎丨机MABs)。为了理解 MABs 的工作原理,假设你身处赌场中,那里有许多老丨虎丨机。你知道其中一些机器的回报比其他机器更好。你的任务是通过最少的试验次数找到最好的老丨虎丨机。因此,你尝试不同的老丨虎丨机(多臂)的手臂(bandits),以最大化你的奖励。你可以将这个情境扩展到测试多个广告模型:对于每个用户,你必须找到最有可能增加广告收入的模型。

最流行的 MAB 算法叫做 epsilon-贪婪 bandit。尽管名字如此,这种方法的内部机制其实很简单:

  1. 选择一个小的数字,称为 epsilon。假设我们选择了 0.01。

  2. 选择一个介于 0 和 1 之间的随机数。这个数字将决定 MAB 是进行探索还是利用可能的选择集。

  3. 如果数字小于或等于 epsilon,则随机做出选择,并在执行与选择相关的行为后记录奖励。我们称这个过程为探索(exploration)——MAB 以较低的概率随机尝试不同的行为,以发现它们的平均奖励。

  4. 如果你的数字大于 epsilon,根据你收集的数据做出最佳选择。我们称这个过程为利用(exploitation)——MAB 利用它所收集的知识执行预期奖励最好的行动。MAB 通过对每个选择的所有记录奖励进行平均,选择期望奖励最大的选项。

通常,我们从较大的 epsilon 值开始,然后逐渐将其减小到更小的值。这样,MAB 在开始时会探索大量的随机选择,并在最后利用最有利的行动。探索频率逐渐减少,接近零。

当你首次启动 MAB 时,它从随机行为中收集奖励。随着时间的推移,你会看到所有选择的平均奖励趋向于它们的真实值。MAB 的主要优势在于它可以实时改变行为。当有人等待假设检验结果时,MAB 给你呈现的是一个不断变化的画面,同时不断向最佳选择收敛。Bandits 是最基本的强化学习算法之一。尽管它们很简单,但可以提供良好的结果。

现在我们有两种新的测试方法可供使用。我们该如何选择其中之一呢?不幸的是,这没有简单的答案。假设检验和 MAB(多臂老丨虎丨机)对数据、采样过程和实验条件提出了不同的约束。在做决定之前,最好请教经验丰富的统计学家或数据科学家。数学约束并不是唯一影响选择的因素;环境也很重要。MABs 在可以从整个群体的随机个体中测试不同选择的情况下容易应用。当测试大型在线零售商的模型时,这可能非常方便,但在临床试验中是不可能的,那里你最好使用假设检验。让我们看看选择 MABs 和假设检验的经验法则:

  • MABs 更适合在需要用有限资源测试多个备选方案的环境中使用。使用 MAB 时,你在统计严谨性和效率之间做出权衡。MABs 可能需要很长时间才能收敛,随着时间推移逐渐改进。

  • 如果你只有一个备选方案,或者你的试验涉及较大风险,或者你需要统计学严谨的答案,你应该使用假设检验。假设检验需要固定的时间和资源来完成,但比 MABs 带来更大的风险。

在在线环境中测试模型对于确保离线测试结果在部署阶段之后保持有效至关重要,但仍然存在我们尚未覆盖的危险区域。数据的突然和意外变化可能会严重影响甚至破坏已部署的模型,因此监控输入数据质量也非常重要。

在线数据测试

即使成功地进行了在线测试,你也无法完全防范模型操作中出现的意外问题。机器学习模型对输入数据非常敏感。好的模型具有一定的泛化能力,但数据或生成数据的基本过程发生显著变化时,模型预测可能会失准。如果在线数据与测试数据有显著偏差,在进行在线测试之前,你无法确定模型的性能。如果测试数据与训练数据不同,那么你的模型就无法按预期工作。

为了克服这个问题,你的系统需要实时监控所有输入数据并检查其质量。以下是一些典型的检查:

  • 必填数据字段中的缺失值

  • 最小值和最大值

  • 分类数据字段的可接受值

  • 字符串数据格式(日期、地址)

  • 目标变量统计(分布检查、平均值)

总结

在本章中,我们回答了一个非常重要的问题:什么才是模型正确工作的标准?我们探讨了错误的性质,并研究了可以量化和衡量模型错误的指标。我们区分了离线和在线模型测试,并为两者定义了测试流程。我们可以通过训练/验证/测试数据集划分和交叉验证来进行离线模型测试。对于在线测试,我们可以选择假设检验和多臂老丨虎丨机(MABs)。

在下一章中,我们将深入探讨数据科学的内部运作。我们将深入了解机器学习和深度学习背后的主要概念,帮助读者直观地理解机器是如何学习的。

第三章:理解人工智能

现在你已经对数据科学能做什么以及我们如何检查其效果有了很好的理解。我们已经介绍了数据科学的主要领域,包括机器学习和深度学习,但算法的内部机制仍然难以通过雾霾般的视角看清。在本章中,我们将讨论算法。你将直观地理解如何通过数学和统计学来定义学习过程。深度神经网络将不再是那么神秘,常见的机器学习术语也不会让你害怕,而是提供理解和启发,帮助你完成不断增长的潜在项目清单。

阅读本章不仅对你有益,你的新知识还将简化与同事的沟通,使会议更加简短且有目的,团队合作更高效。我们将从每个机器学习问题的核心开始:定义学习过程。为了做到这一点,我们将从数据科学的两大根基——数学和统计学开始。

在本章中,我们将涵盖以下主题:

  • 理解数学优化

  • 用统计学思维

  • 机器是如何学习的?

  • 探索机器学习

  • 探索深度学习

理解数学优化

首先,我们将探讨数学优化的概念。优化是机器学习问题的核心组成部分。事实证明,学习过程不过是一个简单的数学优化问题。关键在于如何正确地定义它。为了给出一个好的定义,我们首先需要理解数学优化的工作原理,以及它能解决哪些问题。

如果你在商业领域工作,我敢打赌你每天都会听到“优化”这个词。优化意味着提高效率、削减成本、增加收入并最小化风险。优化涉及采取一系列行动、衡量结果,并决定是否达到了更好的状态。

例如,为了优化你每天上班的路线,你可以最小化从家到办公室的总驾车时间。假设对你而言,唯一重要的是时间。因此,优化就是时间的最小化。你可以尝试不同的方案,比如走另一条路,或者改用公共交通而不是开车。为了选择最佳路线,你将使用相同的量度来评估所有路线,即从家到办公室的总时间。

为了更好地理解优化问题的定义,我们来看看另一个例子。我们的朋友乔纳森厌倦了银行的日常工作,于是他开始了一个兔子农场。结果发现兔子繁殖得很快。一开始,他买了四只兔子,不久后就有了 16 只。一个月后,它们的数量达到了 256 只。所有这些新兔子带来了额外的费用。乔纳森的兔子销售率低于兔子繁殖的速度。乔纳森聪明的农场朋友阿隆对他的兔子繁殖速度印象深刻,于是提议以折扣价购买所有多余的兔子。现在,乔纳森需要找出应该卖给阿隆多少只兔子,以便保持在以下边界内:

  • 他不会陷入不能将兔子卖给迫切需要兔子的人这一境地。兔子的繁殖率不应低于兔子销售预期。

  • 他在兔子照料方面的总支出保持在预算范围内。

如你所见,我们定义了另一个优化问题,兔子农场开始让人想起了乔纳森之前离开的银行工作。这个优化任务虽然也很复杂,但它与第一个问题不同,看起来更加困难。在第一个问题中,我们尝试最小化通勤时间;而在这个问题中,我们需要寻找一个最小的兔子销售数量,以确保不违反其他条件。我们将这种类型的问题称为约束优化。额外的约束让我们能够在复杂的环境中模拟更为现实的场景。举几个例子,约束优化可以解决规划、预算和路由问题。最后,乔纳森对他的兔子农场感到失望,并将其卖给了阿隆。他随后继续寻找一个完美的职业,希望它不会像银行工作那样结束。

有一个地方,盈亏不再让你抓狂;那就是技术大学的数学系。为了得到一个职位,他们要求你通过一项考试。第一个任务是找到一个函数的最小值,

以下是该函数的图表:

在检查图表时,你会注意到这个函数的值不小于 0,所以答案显然是 0。下一个问题看起来像是之前的问题,但有一些变化——找到该函数的最小值 其中 是一个任意数值。为了解决这个问题,你绘制了一些图表,并发现最小值始终是 a

最后的问题将问题推向极限。它说你不会得到关于 的公式,但你可以去找老师,要求获取一些 在某些 下的值,并且可以重复多次。这样无法绘制图像。在其他图像中,最小值总是最低点。那么我们如何在不查看图像的情况下找到这个点呢?为了解决这个问题,我们首先假设我们有该函数的图像。

首先,我们将在函数的两个任意点之间画一条直线,如下图所示:

我们将这两个点之间的距离称为 。如果我们将 越变越小,这两个点会越来越接近,直到它们在视觉上合并成一个点:

上面图中的直线被称为切线。它有一个非常方便的特性,切线的斜率可以帮助我们找到函数的最小值或最大值。如果这条线是平的,那么我们就找到了函数的最小值或最大值。如果附近的点都比较高,那么应该是最大值。如果附近的点都比较低,那么这就是最小值。

以下图展示了一个函数(用蓝色表示)及其最大值,并附有切线(用橙色表示):

绘制一堆线条和点很快会变得单调无趣。幸运的是,有一种简单的方法可以计算这条线的斜率,方法是计算从 之间的斜率。如果你回忆一下勾股定理,你很快就能找到答案:![]。我们可以通过这个公式轻松找到斜率。

恭喜,我们刚刚发明了第一个数学优化算法——梯度下降。像往常一样,名字听起来吓人,但直观理解很简单。为了更好地理解函数优化,假设你正站在一座大山丘上,眼睛闭着,你需要从山丘上走下来。你可能会通过移动脚步来测试周围的区域。当你感受到某个方向在下降时,你就会朝着那个方向迈步,然后继续重复这个过程。用数学术语来说,这座山丘就是一个函数,。每次你评估斜率时,实际上是在计算函数的梯度,。你可以沿着这个梯度找到函数的最小值或最大值。这就是为什么它叫做梯度下降。

你可以通过使用梯度下降法来解决最终任务。你可以选择一个起始点,![],请求获取![]的值,并使用小数字![]计算斜率。通过观察斜率,你可以决定你的下一个选择![]应该大于还是小于![]。当斜率变为零时,你可以通过查看附近的几个值来测试当前的![]值是否为最小值或最大值。如果每个值都小于![],那么![]就是最大值。否则,它就是最小值。

和往常一样,有一个警告。让我们来分析一下这个函数:

如果我们从点A开始梯度下降,我们将最终找到一个真实的最小值。但如果我们从点B开始,我们将停留在局部最小值。使用梯度下降时,你永远无法确切知道自己是否处于局部最小值或全局最小值。检查的一种方法是从相隔较远的不同点重复下降。避免局部最小值的另一种方法是增加步长,![]。但要小心;如果![]太大,你将一次次跳过最小值,永远无法到达真正的目标——全局最小值。

就像在机器学习中一样,有许多数学优化算法,它们各有优缺点。梯度下降是最简单且最容易入门的一种。尽管它很简单,但梯度下降在训练机器学习模型时被广泛使用。

在继续之前,让我们回顾一下几个关键点:

  • 数学优化是机器学习的核心组成部分。

  • 优化问题有两种类型:有约束和无约束。

  • 梯度下降是一种简单且广泛应用的优化算法。为了理解梯度下降背后的直觉,可以回想一下下坡比喻。

现在你已经掌握了数学优化的主要原理,我们可以研究统计学领域——机器学习的祖父学科。

用统计学思维

统计学处理关于数据的一切,具体来说,包括数据的收集、分析、解释、推断和展示。它是一个广阔的领域,包含了许多分析数据的方法。全面覆盖这个领域超出了本书的范围,但我们将深入探讨一个在机器学习中占据核心地位的概念——最大似然估计MLE)。一如既往,别怕术语,因为背后的概念既简单又直观。为了理解 MLE,我们需要深入了解概率论,这也是统计学的基石。

首先,让我们看看为什么在我们已经拥有如此强大的数学工具时,还需要概率。我们使用微积分来处理无穷小尺度上的函数,并衡量它们的变化。我们发展了代数来解方程,而且我们有其他许多数学领域来帮助我们解决几乎任何我们能想到的难题。我们甚至提出了范畴论,它为所有数学提供了一个通用的语言,但几乎没有人能理解它(包括 Haskell 程序员)。

难点在于我们生活在一个混乱的宇宙中,事物无法精确测量。当我们研究现实世界中的过程时,我们需要了解许多随机事件,这些事件会扭曲我们的实验结果。 不确定性无处不在,我们必须驾驭并利用它满足我们的需求。这时,概率论和统计学就派上了用场。概率让我们能够量化和衡量不确定事件,从而做出明智的决策。丹尼尔·卡尼曼在他广为人知的著作《思考,快与慢》中指出,我们在解决统计问题时的直觉往往非常糟糕。概率思维帮助我们避免偏见,理性地行动。

频率主义概率

想象一下,有个陌生人建议你玩一个游戏:他给你一枚硬币,你抛掷它。如果是正面,你赢得$100;如果是反面,你输了$75。在玩这个游戏之前,你肯定会想检查一下它是否公平。如果硬币偏向反面,你可能很快就会亏钱。我们该如何处理这个问题呢?让我们做一个实验,其中我们记录 1 表示正面,0 表示反面。好玩的地方在于,我们需要抛掷 1,000 次,才能确保我们的计算是正确的。假设我们得到了以下结果:600 次正面(1),400 次反面(0)。如果我们计算正面和反面出现的频率,我们会得到 60%和 40%。我们可以将这些频率解读为硬币正面或反面出现的概率。这就是频率主义的概率观。事实证明,我们的硬币实际上偏向正面。这个游戏的期望值可以通过将概率与其对应的数值相乘并加总得出(下列公式中的数值为负,因为$40 是潜在的损失,而不是收益):

玩得越多,得到的越多。即使连续几次掷骰子不幸运,你也可以确定,回报很快会趋于平均。因此,频率派概率衡量某个事件与所有其他可能事件的比例。

条件概率

了解某个事件发生的条件概率是非常有用的,特别是当另一个事件已经发生时。我们将事件  给定事件  的条件概率表示为 。以下雨为例:

  • 给定我们听到雷声,下雨的概率是多少?

  • 给定晴天,下雨的概率是多少?

在下图中,您可以看到不同事件同时发生的概率:

从这个欧拉图中,我们可以看到 ,这意味着每当我们听到雷声时,必定下雨(是的,这并不完全准确,但为了简化问题,我们假设它是正确的)。

那么  呢?从视觉上看,这个概率很小,但我们如何用数学公式来精确计算呢?条件概率的定义如下:

用语言来说,我们将下雨晴天的联合概率除以晴天的概率。

依赖事件与独立事件

如果一个事件的发生概率不影响另一个事件的发生概率,我们就称这对事件是独立的。例如,掷骰子连续两次得到 2 的概率。这两个事件是独立的。我们可以这样表述:

那么为什么这个公式有效呢?首先,我们将第一次和第二次投掷的事件重命名为 A 和 B,以去除符号混乱,然后明确地将掷骰子的概率重写为我们到目前为止所看到的两个投掷的联合概率:

现在将  与  相乘和相除(没有变化,它们可以被约去),并回顾条件概率的定义:

如果我们从右到左读出前面的表达式,我们发现 。基本上,这意味着 A 与 B 是独立的!同样的推理适用于 

贝叶斯概率观点

在这一点之前,我们总是将概率衡量为频率。频率主义方法并不是定义概率的唯一方式。虽然频率主义者将概率视为比例,但贝叶斯方法考虑了先验信息。贝叶斯理论基于一个简单的定理,让我们可以基于先前的知识计算条件概率:

在这个例子中,先验值是 。如果我们不知道真实的先验值,我们可以用基于经验的估计值来进行近似计算。这就是贝叶斯定理的魅力所在。你可以用简单的组件计算复杂的条件概率。

贝叶斯定理具有巨大的价值和广泛的应用领域。贝叶斯理论甚至有自己的一支统计学分支和推理方法。许多人认为,贝叶斯观点更接近我们人类对不确定性的理解,特别是先验经验如何影响我们的决策。

分布

概率与一组结果或事件有关。我们用概率描述的许多问题都有共同的属性。在下图中,你可以看到钟形曲线:

钟形曲线或高斯分布集中在最可能的结果集周围,两端的尾部表示最不可能的结果。由于其数学特性,钟形曲线在我们的世界中无处不在。测量许多随机人的身高,你会看到钟形曲线;观察你草坪上所有草的高度,你会再次看到它。计算你所在城市的居民具有某种收入的概率,你又会看到它。

高斯分布是最常见的分布之一,但还有许多其他分布。概率分布是一种数学法则,它告诉我们不同可能结果的概率,这些结果通过数学函数表达。

当我们测量硬币投掷事件的相对频率时,我们计算了所谓的经验概率分布。硬币投掷也可以被表述为伯努利分布。如果我们想要计算在n次试验后得到正面的概率,我们可以使用二项分布。

引入一个与变量类似的概念,在概率环境中可能会使用——随机变量。随机变量是统计学的基本构件。每个随机变量都有一个分布。随机变量通常用大写字母表示,我们使用~符号来指定分配给变量的分布:

这意味着随机变量X根据伯努利定律分布,成功(正面)的概率为 0.6。

从数据样本计算统计量

假设你正在研究人类身高,并且渴望发表一篇令人惊叹的科学论文。为了完成你的研究,你需要测量你所在地区普通人的平均身高。你可以通过两种方式完成这个任务:

  • 收集你所在城市每个人的身高并计算平均值

  • 应用统计学

统计学允许我们在不为每个人收集完整数据集的情况下推理出种群的不同属性。从真实种群中选择随机数据子集的过程称为抽样。统计量是使用样本中的值来总结数据的任何函数。几乎每个人每天都使用的无处不在的统计量是样本均值或算术平均数:

我们已经收集了一组随机样本共 16 人的平均身高。在下表中,我们可以看到四天内的身高情况:

日期 身高 平均值
星期一 162 cm, 155 cm, 160 cm, 171 cm 162.00 cm
星期二 180 cm, 200 cm, 210 cm, 179 cm 192.25 cm
星期三 160 cm, 170 cm, 158 cm, 176 cm 166.00 cm
星期四 178 cm, 169 cm, 157 cm, 165 cm 167.25 cm
总计 171.88 cm

我们收集了每天四个身高的样本,总共 16 个身高。你的统计学朋友弗雷德告诉你,他已经收集了 2000 人的样本,该地区的平均身高约为 170 厘米。

要调查这个问题,我们可以看看每个新数据点对你的样本平均值造成了怎样的影响:

注意,第 2 天的平均值出乎意料地高。可能我们碰巧遇到了四个高个子。数据中的随机波动称为方差。

我们可以使用以下公式来测量样本方差:

样本方差总结了我们的数据,因此我们可以将其视为另一个统计量。方差越大,计算准确平均值之前需要收集的样本量就越多,这个平均值将接近真实值。这种现象有个名字——大数定律。你做的测量越多,你的估计就越准确。

统计建模

统计学不仅仅是计算总结性数字。统计学中最有趣的一个方面是建模。统计建模研究了对数据进行一组统计假设的数学模型。更清楚地说,让我们回到我们的天气例子。我们收集了一个包含描述当前天气的随机变量的数据集:

  • 平均风速

  • 空气湿度

  • 空气温度

  • 当地某区域天空中看到的鸟类总数

  • 统计学家的心情

使用这些数据,我们希望推断哪些变量与降雨相关。为此,我们将建立一个统计模型。除了之前的数据,我们还记录了一个二元降雨变量,如果下雨则取值 1,反之取值 0。

现在,我们对数据做出一组假设:

  • 降雨概率遵循伯努利分布。

  • 降雨概率取决于我们收集到的数据。换句话说,数据与降雨概率之间存在某种关系。

你可能觉得以概率的方式思考降雨很奇怪。那么,如何理解说上周三降雨的概率是 45%呢?上周三是过去的日期,所以我们可以检查数据,看看是否下雨。关键在于理解,在我们的数据集中,有许多类似周三的天数。假设我们收集到了以下值:

星期几 风速 湿度 温度 结果
周一 5 m/s 50% 30°C 不下雨
周二 10 m/s 80% 25°C 下雨
周三 5 m/s 52% 28°C 下雨
周四 3 m/s 30% 23°C 不下雨
周五 8 m/s 35% 27°C 不下雨

在这个例子中,周一和周三非常相似,但它们的降雨结果不同。在足够大的数据集中,我们可能会找到两行数据完全相同但结果不同。为什么会这样?首先,我们的数据集并没有包括所有可以描述降雨的变量。收集到这样一个数据集是不可能的,因此我们假设我们的数据与降雨相关,但并没有完全描述降雨。测量误差、事件的随机性以及不完全的数据使得降雨具有概率性。你可能会想,降雨本质上是概率性的?还是每一场降雨都是预定的?为了验证降雨事件是否是确定性的,我们必须收集一个完整的宇宙状态的每日快照,这显然是不可能的。统计学和概率论帮助我们理解这个世界,即使我们只有不完全的信息。例如,假设我们在数据集中有 10 天和上周三相似。所谓相似,意味着我们收集到的所有变量只有很小的差异。在这 10 天中,有 8 天下雨,2 天晴天。我们可以说,在类似上周三的日子里,降雨的概率是 80%。这是我们使用这些数据能够给出的最准确的答案。

在做出数据假设后,我们可以进行建模。我们可以假设存在一个数学模型M,它使用数据来估计降雨概率。也就是说,模型M使用数据d来学习数据与降雨概率之间的关系。该模型将通过给出最接近我们数据集中实际结果的降雨概率来推断这种关系。

模型M的主要目标不是做出准确的预测,而是找到并解释关系。这就是我们可以区分统计学和机器学习的地方。机器学习旨在找到准确的预测模型,而统计学则使用模型来找到解释和理解。目标不同,但让模型从数据中学习的基本概念是相同的。现在,我们终于可以揭示模型M是如何从数据中学习的。我们将解开其中的“魔法”,并留下机器学习背后数学的直观理解。

机器是如何学习的?

算法是如何学习的?我们如何定义学习?作为人类,我们一生中学习了很多东西。这是我们的一项自然任务。在生命的最初几年,我们学会了如何控制自己的身体、走路、说话以及识别不同的物体。我们不断获得新的经验,这些经验改变了我们的思维、行为和行动方式。计算机代码能像我们一样学习吗?为了接近机器学习,我们首先需要找到一种将经验直接传递给算法的方法。

在实际情况下,我们希望教算法执行各种特定任务,比我们自己做得更快、更好、更可靠。目前,我们将专注于预测和识别任务。因此,我们希望构建能够识别模式并预测未来结果的算法。下表展示了预测和识别任务的一些例子:

识别任务 这是不是一个高收入的客户?这座房子在当前市场上的价格是多少?图像中的那些物体是什么?
预测任务 这个客户在未来 6 个月内可能会偿还债务吗?我们下个季度将销售多少?这个投资有多大风险?

第一个想法可能是像人类一样进行学习,并通过语言、图像和示例集提供解释和示例。不幸的是,在这种方式下学习时,我们需要执行许多复杂的认知任务,例如听、写和说。单靠计算机算法无法像我们一样收集新的经验。那么,如果我们用数字数据的简化模型来表示我们的世界呢?例如,预测 Acme 公司客户流失的任务可以仅使用关于客户购买和产品评级的数据来完成。数据集越完整,客户流失模型的准确性就越高。

让我们看另一个例子。我们将建立一个机器学习项目成本估算器。这个模型将使用项目的属性来计算成本估算。假设我们已经收集了公司中每个项目的以下数据属性:

属性名称 属性类型 属性描述 可能的值
属性数量 整数 项目数据集中数据属性的数量 0 到 ∞
数据科学家数量 整数 客户为项目实施要求的数据科学家数量 0 到 ∞
集成 整数 客户要求的与客户软件系统的集成 0 表示项目范围内没有集成,1 表示项目范围内有集成
是否为大型公司 整数 表示客户是否拥有大量员工 0 = 客户公司员工人数大于 1001,1 = 客户公司员工人数少于或等于 100
总项目成本 整数 总成本(单位:美元) 0 到 ∞

含有这些属性的示例数据集如下表所示:

属性数量 数据科学家数量 集成 是否为大型公司 总项目成本
10 1 1 0 135,000
20 1 0 1 140,000
5 2 1 0 173,200
100 3 1 1 300,000

我们能想象的最简单模型是所谓的线性模型。它将数据属性与变量系数相乘后求和,以计算项目成本估算值:

在这个简化的场景中,我们并不知道成本变量的真实值。然而,我们可以使用统计方法,并从数据中进行估算。让我们从一组随机参数开始:

  • 基本成本 = 50,000

  • 每个数据属性的成本 = 115

  • 每个数据科学家的成本 = 40,000

  • 集成成本 = 50,000

  • 客户关系复杂度成本 = 5,000

如果我们使用数据集中每个项目的参数,我们将得到以下结果:

总项目 1 成本 = 50,000 + 115 x 10 + 40,000 x 1 + 50,000 x 1 + 50,000 x 0 = 141,150

总项目 2 成本 = 50,000 + 115 x 20 + 40,000 x 1 + 50,000 x 0 + 50,000 x 1 = 142,300

总项目 3 成本 = 50,000 + 115 x 5 + 40,000 x 2 + 50,000 x 1 + 50,000 x 0 = 180,575

总项目 4 成本 = 50,000 + 115 x 100 + 40,000 x 3 + 50,000 x 1 + 50,000 x 1 = 281,500

你可能已经注意到,这些值与我们数据集中真实项目的成本有所不同。这意味着,如果我们将此模型应用于任何真实项目,我们的估算将会有误。我们可以通过多种方式来衡量这个误差,但让我们选择其中最受欢迎的一种方法:

有很多方法可以量化预测误差。它们每种方法都引入了不同的权衡和限制。误差度量的选择是构建机器学习模型时最重要的技术之一。

对于整体误差,我们可以取所有项目的单个误差的算术平均值。我们计算出的这个数字叫做均方根误差RMSE)。

该度量的确切数学形式并不重要。RMSE 背后有直接的逻辑。虽然我们可以通过对线性模型施加若干技术约束来推导 RMSE 公式,但数学证明不在本书的范围内。

结果表明,我们可以使用优化算法调整我们的成本参数,以使得 RMSE 最小化。换句话说,我们可以找到最适合的成本参数,使得数据集中的所有行的误差最小。我们称这个过程为最大似然估计(MLE)。

最大似然估计(MLE)提供了一种估计统计模型参数的方法,给定数据。它的目标是最大化给定数据下参数的概率。虽然听起来可能有些困难,但如果我们将定义重新表述为一个问题:我们应该设置什么参数,使得我们得到的结果最接近数据?MLE 帮助我们找到这个问题的答案。

让我们专注于另一个例子,来获得一个更普遍的方法。假设我们开始了一个咖啡订阅服务。客户在我们的手机应用程序中选择她最喜欢的咖啡口味,并填写地址和支付信息。之后,我们的快递员每天早晨为她送上一杯热咖啡。应用程序中内置了反馈系统。我们通过推送通知向客户推广季节性优惠和折扣。去年的订阅用户增长了很多:现在有将近 2,000 人在使用该服务,每月还有 100 多人订阅。然而,我们的客户流失率正在快速增长,令人担忧。营销优惠似乎没有产生太大的效果。为了解决这个问题,我们决定建立一个机器学习模型,提前预测客户流失。通过知道客户将流失,我们可以定制个性化的优惠,将他们重新转化为活跃用户。

这一次,我们将在定义上更加严谨和抽象。我们将定义一个模型M,该模型接受客户数据X和历史流失结果Y。我们将Y称为目标变量。

以下表格描述了我们数据集的属性:

属性名称 属性类型 属性描述 可能的值
订阅月数 整数 用户已订阅我们服务的月数 0 到 ∞
启动的特殊优惠 整数 用户上个月激活的特殊优惠数量 0 到 ∞
工作日订购杯数 浮动数 用户上个月在工作日平均订购的杯数 1.0 到 5.0
周末订购杯数 浮动数 用户上个月在周末平均订购的杯数 1.0 到 2.0

这种表格被称为数据字典。我们可以利用它来了解模型中输入输出的数据,而无需查看代码或数据库。每个数据科学项目都必须有一个最新的数据字典。本书稍后将展示更完整的数据字典示例。

我们的目标变量Y可以通过以下方式描述:

目标变量名称 目标变量类型 目标变量描述 目标变量可能的值
用户流失 整数 指示用户是否在上个月停止使用我们的服务 0 或 1

给定客户描述 ,模型输出流失概率 。在 上加帽子表示 不是一个真实的流失概率,而只是一个可能包含误差的估计值。这个值不会严格等于零或一。相反,模型会输出一个介于 0% 和 100% 之间的概率。例如,对于某个客户 ,我们得到了一个 76% 的流失概率 。我们可以这样解读这个值:根据历史数据,该客户的流失预期为 76%。或者,100 个像客户 的客户中,将有 76 个客户流失。

一个机器学习模型必须具有一些可变的参数,这些参数可以调整以更好地匹配流失结果。现在我们已经使用了公式,我们不能继续进行而不引入至少一个希腊字母。我们模型的所有参数将由 表示。

现在,我们一切准备就绪:

  • 历史客户数据 和流失结果 ,我们将其称为训练数据集

  • 机器学习算法 ,接受客户描述 ,输出流失概率

  • 模型参数 ,可以通过最大似然估计(MLE)来调整。

我们将使用 MLE 在训练数据集 上估计我们模型的参数 。我在 上加了一个帽子,表示理论上可能存在最优的参数集 ,但实际上我们有数据限制。因此,我们能得到的最佳参数集只是一个可能包含误差的真实估计。

现在,我们终于可以使用我们的模型来预测客户流失。

概率

概率的确切解释在很大程度上依赖于我们用来估计该概率的模型 M。一些模型可以用来给出概率解释,而其他模型则没有这样的特性。

注意,我们没有明确地定义我们使用的机器学习模型M的类型。我们定义了一个从数据中学习的抽象框架,它不依赖于特定的数据或具体的算法。这就是数学的魅力,它打开了无限的实际应用。通过这个抽象框架,我们可以提出许多具有不同权衡和能力的模型M。这就是机器如何学习的方式。

如何选择模型

机器学习模型有很多种类型,估计方法也各不相同。线性回归和最大似然估计(MLE)是最简单的例子之一,它们展示了许多机器学习模型背后的基本原理。有一个叫做无免费午餐定理的定理,指出没有任何一个模型能在每个任务和每个数据集上都给出最佳结果。我们的机器学习框架是抽象的,但这并不意味着它能产生完美的算法。有些模型适合某些任务,但在其他任务中表现糟糕。一个模型可能在图像分类上比人类做得更好,但它在信用评分上却会失败。选择最适合某个任务的最佳模型的过程需要深厚的知识,涉及多个学科,如机器学习、统计学和软件工程。它依赖于许多因素,如统计数据特性、我们试图解决的任务类型、商业约束和风险。这就是为什么只有专业的数据科学家才能处理机器学习模型的选择和训练。这个过程涉及很多复杂细节,解释所有这些内容超出了本书的范围。有兴趣的读者可以参考本书末尾的书单,在那里你可以找到一些免费的书籍,详细解释机器学习的技术细节。

探索机器学习

现在你已经理解了如何使用数学和统计学来定义学习过程的一般思路,我们可以深入探索机器学习的内部工作原理。机器学习研究的是能够在没有明确指令的情况下学习并执行特定任务的算法和统计模型。正如每个软件开发经理应该具备一定的计算机编程专业知识一样,数据科学项目经理也应该理解机器学习。掌握任何机器学习算法背后的基本概念将帮助你更好地理解项目的局限性和需求。这将有助于你与团队中的数据科学家之间的沟通与理解。了解基本的机器学习术语将使你能够用数据科学的语言进行交流。

现在我们将深入探讨流行机器学习算法背后的主要直觉,为了突出重点,我们将省略技术细节。

定义机器学习的目标

当我们谈论机器学习时,我们谈论的是准确的预测和识别。统计学家通常使用简单但可解释的模型,并以严格的数学基础来解释数据并证明观点。机器学习专家则构建更复杂的模型,这些模型较难解释,通常像黑盒一样工作。因此,许多机器学习算法更注重预测质量而非模型可解释性。趋势变化缓慢,尽管越来越多的研究人员开始研究模型解释和预测说明的主题,机器学习的主要目标仍然是创建更快、更准确的模型。

使用生命周期来构建机器学习模型

在创建机器学习模型时,我们通常遵循一组固定的阶段:

  • 探索性数据分析:在这一阶段,数据科学家使用一系列统计和可视化技术,以更好地理解数据。

  • 数据准备:在此部分,数据科学家将数据转换为适合应用机器学习算法的格式。

  • 数据预处理:在此阶段,我们清洗已准备好的数据并进行转换,以便机器学习算法能够正确使用数据的每一部分。

  • 建模:在这一部分,数据科学家训练机器学习模型。

  • 测试:在此阶段,我们使用一组衡量模型性能的指标来评估模型。

这一过程会重复多次,直到我们达到足够好的结果。你可以将生命周期应用于训练多种机器学习模型,接下来我们将探索这些模型。

线性模型

最基本的机器学习模型类型是线性模型。我们在上一部分已经详细介绍了线性模型的示例。线性模型的预测可以通过查看模型的系数来解释。系数越大,它对最终预测的贡献越大。虽然简单,但这些模型往往不是最准确的。线性模型快速且计算效率高,这使得它们在数据量大且计算资源有限的环境中非常有价值。

线性模型快速、高效、简单且可解释。它们可以解决分类和回归问题。

分类和回归树

分类与回归树 (CART) 采用一种非常直观的预测方法。CART 根据训练数据构建决策树。如果我们将 CART 用于信用违约风险任务,我们可能会看到这样的模型:

要进行预测,算法从树的顶部开始,并根据数据中的值做出连续的选择。对于二元分类,树的底部会显示类似客户的正例比例。

尽管简单,CART 模型也有两个缺点:

  • 低预测准确度。

  • 对于一个数据集,可能有许多不同的树。某一棵树的预测精度可能远远优于其他树。

但 CART 如何选择列和数值进行分裂呢?我们将探索 CART 在二分类中的一般逻辑:

  1. 首先,它选取一列数据,并根据该列的每个值将数据分为两部分。

  2. 然后,它计算每次分裂中正例的比例。

  3. 步骤 1步骤 2对数据中的每一列都会重复进行。

  4. 我们根据每次分裂对数据的划分效果对其进行排名。如果分裂能够完美划分数据,那么正例将完全出现在某一侧,且低于某个阈值,负例则出现在另一侧。举例来说,如果年龄 > 25是一个完美的分裂,那么所有年龄小于 25 的客户将会有信用违约,而所有年龄大于 25 的客户将拥有完美的信用历史。

  5. 根据步骤 4,为当前树的层级选择最佳的分裂。数据集根据分裂值被分为两部分。

  6. 对于每一个新的数据集部分,步骤 1步骤 5都会重复执行。

  7. 该过程会持续进行,直到算法达到停止标准。例如,我们可以通过查看决策树的深度或用于下一次分裂的数据点最小数量来停止建树。

我们也可以将 CART 应用于回归问题,尽管算法会稍微复杂一些。CART 简单且易于解释,但它生成的模型非常弱,很少在实际中应用。然而,该算法的特性和实现技巧使得我们能够将其最弱的部分转化为其主要优势。我们将在接下来的部分学习如何利用这些特性。

集成模型

假设你拥有一家零售店的特许经营。业务正在增长,你准备开设一家新店。问题是,应该在哪个地方开设新店呢?选择店铺位置极为重要,因为它是永久性的,并且决定了将进入你店铺的当地顾客群体。

你有几种选择来做出这个决策:

  1. 自己决定。

  2. 向最有能力的员工请教建议。

  3. 向许多稍微经验不足的员工请教意见。

选项 12分别代表一个或两个人作出决策。选项 3则包括几位专家的意见。从统计学角度看,选项 3更有可能做出更好的决策。即使是世界级的专家也可能犯错。多个专业人员之间相互共享信息,更有可能成功。这就是为什么生活在大社区中和在大型组织中工作能够取得更好成果的原因。

在机器学习中,这一原则同样适用。许多模型可以共同做出一个决策,从而形成集成模型。与单一模型相比,模型集成往往更为准确,包括最先进的模型。然而需要小心的是,你需要构建多个模型来创建集成模型。大量模型会迅速增加计算资源需求,因此需要在预测准确性和速度之间做出权衡。

基于树的集成方法

一个特别有用的集成模型是决策树。实际上有一个完整的机器学习模型类别,专门用于创建不同的树集成方法。这类模型在 Kaggle 结构化数据竞赛中是最常获胜的,因此理解它是如何工作的非常重要。

决策树是构建集成模型的好候选者,因为它们具有较高的方差。由于树构建算法中的随机性,每棵决策树与前一棵树都会有所不同,即使数据集没有发生变化。每次我们构建决策树时,可能会得出与之前不同的结果。因此,每棵树会犯不同的错误。回想以下图示:

事实证明,决策树具有极低的偏差和较高的方差。想象一下,许多不同的树为每个个体做出数百个预测,从而创建了一个集成。假设我们对所有预测结果进行平均,会发生什么呢?我们将会更接近真实答案。当决策树用于集成时,它们能够处理复杂的数据集并具有较高的预测准确性。

在下图中,你可以看到多个树如何创建一个集成:

如果你在处理结构化数据,务必在进入其他机器学习领域(包括深度学习)之前尝试决策树集成模型。十有八九,结果会让你和你的客户都感到满意。媒体通常忽视这种算法的价值。集成模型鲜有赞誉,但它无疑是解决实际应用机器学习问题时最常用的算法家族。务必给树集成模型一个机会。

聚类模型

机器学习的另一个有用应用是聚类。与我们在本节中研究的其他机器学习问题不同,聚类是一个无监督学习问题。这意味着聚类算法可以处理没有标签的数据。为了说明这一点,我们来看一个营销部门的核心任务——客户细分。为每个客户制定营销策略可能是不可能的。例如,如果你经营一个大型零售店网络,你可能希望根据客户的兴趣在不同的商店应用不同的折扣,以提升销量。为此,营销部门创建客户细分,并根据每个细分市场量身定制营销活动。

在下图中,你可以看到六个客户被分配到两个不同的细分市场:

我们可以通过将所有客户的购买历史记录并应用聚类算法将相似的客户分组,从而自动化客户细分。该算法会将每个客户分配到一个单独的细分市场,从而进一步分析这些细分市场。在探索每个细分市场中的数据时,您可能会发现一些有趣的模式,这些模式将为针对特定客户群体的新营销方案提供洞察。

我们可以以临时的方式将聚类算法应用于数据,因为它们不需要预先标记。然而,情况可能会变得复杂,因为许多算法受到维度灾难的困扰,无法处理数据中的许多列。

最流行的聚类算法是 K-means。其最简单的形式,算法只有一个参数:要在数据中找到的簇数。K-means 从几何角度进行聚类。想象每一行数据都是空间中的一个点。对于我们来说,这个概念在具有两个或三个点的数据集上非常容易理解,但它在超过三维空间时也能很好地工作。将数据集布置在几何空间中后,我们可以看到一些点会彼此更接近。K-means 寻找中心点,其他点围绕这些中心点聚集。

它通过以下迭代过程完成此任务:

  1. 它采用当前的簇中心(对于第一次迭代,它选择随机点)。

  2. 它遍历所有数据行,并将它们分配给最接近的簇中心点。

  3. 它通过对步骤 2中的所有点的位置进行平均来更新簇中心。

算法在以下图示中进行了说明:

到此为止,我们已经完成了机器学习的介绍。虽然还有许多其他机器学习算法需要研究,但描述它们超出了本书的范围。我相信您会发现,回归、决策树、集成模型和聚类的知识涵盖了令人惊讶的大部分实际应用,并且将对您大有帮助。现在,我们准备进入深度学习的部分。

探索深度学习

深度神经网络通过对图像分类和围棋游戏的表现优于我们,给人一种极其复杂模型的印象,这些模型的内部结构灵感来源于我们大脑的结构。事实上,神经网络背后的核心思想是容易理解的。虽然最初的神经网络确实受到了我们大脑物理结构的启发,但这种类比如今已经不再成立,神经网络与人类大脑内部的物理过程的关系主要是历史性的。

为了揭开神经网络的神秘面纱,我们将从基本的构建块开始:人工神经元。一个人工神经元不过是由两个数学函数组成。第一个函数接受一堆数字作为输入,并通过它的内部状态——权重,来组合这些数字。第二个函数是激活函数,它接受第一个函数的输出并应用特定的变换。激活函数告诉我们这个神经元对于某一特定输入组合的活跃程度。在下面的图中,你可以看到一个人工神经元是如何将输入转换为输出的:

在下图中,我们可以看到最流行的激活函数的图像:

如果输出小于 0,函数将输出 0。如果输出大于 0,它将回显其输入。简单吧?试着为这个函数起个名字。我知道,命名是困难的。名字应该简单,同时传达出事物核心概念的深刻洞察。当然,数学家们早就知道这一点,正如我们之前看到过的,提出了一个完美而清晰的名字——修正线性单元ReLU)。一个有趣的事实是,ReLU 并不符合激活函数的基本要求,但它仍然比其他替代品给出了更好的结果。其他激活函数在特定情况下可能更好,但没有一个能比 ReLU 更合理地作为默认选择。

另一个你需要了解的重要激活函数是 sigmoid。你可以在下面的截图中看到它:

在 ReLU 登上王座之前,sigmoid 曾是一个受欢迎的激活函数选择。尽管它作为激活函数的价值已经减弱,但 sigmoid 仍然因为另一个原因而重要。它经常出现在二分类问题中。如果你仔细观察图表,你会发现它能将任何数字映射到 0 和 1 之间的范围。这一特性使得 sigmoid 在建模二分类问题时非常有用。

请注意,我们在二分类问题中使用 sigmoid,并不是因为它方便地将任何数字映射到 0 和 1 之间的某个值。这个有用特性的背后原因是 sigmoid,也称为逻辑函数,与伯努利概率分布紧密相关。该分布描述了在概率p介于 0 和 1 之间的事件。例如,伯努利分布可以描述一个抛硬币事件,其p = 0.5,即 50%。正如你所看到的,任何二分类问题都可以自然地通过伯努利分布来描述。要理解这一点,可以看看下面这些问题:客户点击广告的概率是多少? 客户在欠债时违约的概率是多少? 我们可以将这些情况建模为伯努利分布。

现在,我们知道人工神经元的主要组成部分:权重和激活函数。为了让神经元工作,我们需要将它的输入与神经元的权重结合起来。为此,我们可以回想线性回归。线性回归模型通过将每个属性与一个权重相乘并将它们相加来组合数据属性。然后,应用激活函数,你就会得到一个人工神经元。如果我们的数据行有两个列,分别叫做 ab,那么神经元将有两个权重,。一个具有 ReLU 激活函数的神经元公式如下所示:

请注意, 是一个特殊的权重,称为偏置,它与任何输入无关。

因此,一个人工神经元只是一些乘法和加法:

或者,为了给你一个更具体的实际计算例子,看看下面的内容:

将数字结合的操作,即将每个项与常数相乘并将结果相加,在机器学习和统计学中无处不在。它被称为两个向量的线性组合。你可以把一个向量看作是一个固定的数字集合。在我们的例子中,第一个向量将是数据行,第二个向量将包含每个数据属性的权重。

构建神经网络

我们准备构建我们的第一个神经网络。让我们从一个例子开始:我们的公司在客户留存方面遇到了困难。我们知道很多关于客户的信息,并且可以创建一个能让他们想要留下的优惠。问题是,我们无法识别哪些客户会流失。因此,我们的老板,简,要求我们构建一个流失预测模型。这个模型将接受客户数据,并预测下个月流失的概率。有了这个概率估计,简就可以决定是否需要为该客户创建个性化的营销优惠。

我们决定使用神经网络来解决这个客户流失预测问题。我们的网络将由多个神经元层组成。每一层的神经元将与下一层的神经元相连接:

这可真是很多箭头,不是吗?两个神经元之间的连接意味着一个神经元将把它的输出传递给下一个神经元。如果一个神经元接收多个输入,它们会被全部加起来。这种类型的网络被称为全连接神经网络FCNN)。

我们已经了解了如何使用神经网络进行预测,但我们如何学习应该做出什么样的预测呢?仔细观察,神经网络不过是一个具有大量权重的大型函数。模型的预测是通过使用权重和通过神经元输入传入的信息来决定的。因此,要拥有一个准确的神经网络,你必须设置正确的权重。我们已经知道,可以通过数学优化和统计学来最小化预测误差,方法是改变函数的参数。神经网络不过是一个带有可变权重的大型复杂数学函数。因此,我们可以使用最大似然估计(MLE)和梯度下降来进行优化。我将以粗体字给出每个阶段的正式名称,随后是每个阶段的直观解释:

  1. 网络初始化:一开始,我们可以用随机值来初始化权重。

  2. 前向传播:我们可以从训练数据集中选取一个例子,并使用当前的权重集进行预测。

  3. 损失函数计算:我们衡量预测值与真实值之间的差异。我们希望这个差异尽可能接近 0。也就是说,我们希望最小化损失函数。

  4. 反向传播:我们可以使用优化算法调整权重,使得预测更加准确。一个叫做反向传播的特殊算法可以计算每一层神经元的更新,从最后一层到第一层。

  5. 步骤 14 会重复进行,直到达到所需的准确度水平,或直到网络停止学习:

反向传播是训练神经网络时最广泛使用的学习算法。它通过计算预测误差来确定我们应该如何调整网络中每个权重,以使预测值更接近真实值。反向传播的名称来源于算法更新权重的特定方式:它从最后一层开始,逐层将变化传播到每个神经元,直到到达网络输入层。当输入经过网络计算输出预测时,我们称之为前向传播。当我们通过传播误差来改变权重时,我们称之为反向传播。

如今,有许多不同类型的构建模块可以用来组成神经网络。有些特定的神经元类型在处理图像数据时效果更好,而其他类型则能利用文本的序列性质。许多专门的层被发明出来,以提高训练速度并抵抗过拟合。专门用于解决特定任务的神经网络层组合被称为神经网络架构。所有神经网络架构,无论它们有多复杂或多深,仍然遵循反向传播的基本规律。接下来,我们将探讨深度学习在特定领域的应用。

计算机视觉简介

首先,我们来看看计算机视觉。让我们从一个例子开始。我们的客户乔(Joe)喜欢动物。他是六只猫和三只狗的快乐主人。作为一个快乐的主人,他也喜欢拍摄宠物的照片。多年来,乔的电脑上积累了大量的照片档案。乔决定需要整理他那个包含 50,000 张宠物照片的可怕照片文件夹。为了帮助乔,我们决定创建一个神经网络,输入一张图片,然后判断照片中是否有猫或狗。下面的图示展示了神经网络分类器如何处理一张猫的照片:

首先,我们将图像转换为三张数字表格,分别表示每个像素的红色、绿色和蓝色通道。如果我们尝试像以前那样使用普通的全连接神经网络(FCNN),结果会让人失望。深度神经网络在计算机视觉任务中表现出色,因为它有一种特定类型的神经元,叫做卷积滤波器或卷积。卷积神经网络CNN)是由法国机器学习研究员 Yann LeCun 发明的。在 CNN 中,单个神经元可以查看图像的一个小区域,比如 16x16 个像素,而不是将整个像素集作为输入。这个神经元可以遍历图像的每个 16x16 的区域,检测它通过反向传播学习到的图像特征。然后,这个神经元可以将信息传递给后续的层。在下面的插图中,您可以看到一个卷积神经元遍历小的图像块并尝试检测类似毛发的图案:

卷积神经网络(CNN)显著的成就之一是,单个神经元可以重用少量的权重,依然能够覆盖整个图像。这一特性使得 CNN 比传统神经网络更加快速和轻量化。这个理念直到 2010 年代才得以实现,那时 CNN 在 ImageNet 比赛中超越了所有其他计算机视觉方法。在这场比赛中,算法必须学习如何将照片分类到 21,000 个可能的类别中。CNN 的发展历程较长,因为我们缺乏足够的计算能力来训练包含大量参数的大型数据集上的深度神经网络。为了获得良好的准确率,CNN 需要大量的数据。例如,ImageNet 比赛包括 1,200,000 张训练图像。

在最初的层次,卷积神经网络(CNN)通常会检测图像中的简单模式,如边缘和轮廓。随着层次的加深,卷积滤波器变得更加复杂,能够检测出眼睛、鼻子等特征。

在接下来的可视化中,您可以看到神经网络不同层次上卷积滤波器的一个示例:

许多神经元学习识别对任何计算机视觉任务有用的简单模式。这一观察引导我们得出一个非常重要的思想:一个训练良好以执行一项任务的神经网络可以重新训练以执行另一项任务。此外,对于第二项任务,您将需要更少的训练数据,因为网络已经从先前的训练数据集中学到了许多有用的特征。特别是,如果您想从头开始训练一个 CNN 分类器以处理两类图像,您将需要标记成千上万张图像以达到良好的性能水平。然而,如果您使用在 ImageNet 上预训练过的网络,您可能只需使用 1,000 到 2,000 张图像就能获得良好的结果。这种方法称为迁移学习。迁移学习不仅限于计算机视觉任务。近年来,研究人员在其他领域如自然语言处理、强化学习和声音处理中也取得了显著进展。

现在您已经了解了深度卷积神经网络的工作原理,我们将继续到语言领域,深度学习已经改变了一切。

自然语言处理简介

在深度学习革命之前,自然语言处理(NLP)系统几乎完全基于规则。语言学家们创建了复杂的解析规则,试图定义我们语言的语法,以自动化诸如词性标注或命名实体识别之类的任务。不同语言之间的人类级别翻译和自由形式问题回答在科幻领域。NLP 系统难以维护且开发周期长。

就像计算机视觉一样,深度学习席卷了自然语言处理(NLP)领域。基于深度学习的 NLP 算法成功实现了不同语言之间接近人类水平的翻译,可以测量文本的情感倾向,能够学习从文本中检索信息,并能生成自由形式的问题答案。深度学习的另一个重大好处是统一的方法。一个词性标注模型架构可以适用于法语、英语、俄语、德语等多种语言。虽然需要为所有这些语言准备训练数据,但基础模型是相同的。使用深度学习,我们无需试图硬编码我们复杂的语言规则。尽管许多任务,如长篇写作和人类水平的对话,对深度学习仍然是不可征服的,但 NLP 算法在商业和日常生活中提供了巨大帮助。

对于 NLP 深度学习而言,一切始于一个想法:单词的含义由其邻居定义。也就是说,要学习一门语言和单词的含义,你只需要理解文本中每个单词的上下文。这个想法可能看起来过于简单以至于不真实。为了验证其有效性,我们可以创建一个神经网络,通过接收周围单词作为输入来预测一个单词。为了创建训练数据集,我们可以使用任何语言的任何文本。

如果我们采用两个单词的上下文窗口,那么我们可以为这个句子生成以下训练样本:

如果,我们,取,a → will

我们可以通过训练→生成

Following, training, for, this → samples

以此类推…

接下来,我们需要想出一种方法将所有单词转换为数字,因为神经网络只能理解数字。一种方法是将文本中所有独特的单词分配给一个数字:

Following → 0

Training → 1

Samples → 2

For → 3

This → 4

然后,我们通过神经网络中的一组权重来表示每个词。具体来说,我们从每个词的两个介于 0 和 1 之间的随机数字开始。

我们将所有数字放入如下表格中:

词标识符 词向量
0 0.63, 0.26
1 0.52, 0.51
2 0.72, 0.16
3 0.28, 0.93
4 0.27, 0.71
N 0.37, 0.34

现在我们有了一种方法,将文本中的每个词转换为一对数字。我们将把我们生成的所有数字作为神经网络的权重。它将接收四个词作为输入,将它们转换为八个数字,并使用它们来预测中间词的标识符。

例如,对于训练样本FollowingTrainingForThisSamples

输入:

Following → 0 → 0.63, 0.26

训练→1→0.52, 0.51

For → 3 → 0.28, 0.93

This → 4 → 0.27, 0.71

输出:

2 → Samples

我们将与一个词相关的每一对数字称为词向量。我们的神经网络将输出一个从零到一的概率向量。这个向量的长度将与我们数据集中的独特词汇总数匹配。然后,具有最大概率的数字将代表最有可能根据模型完成输入的词。

在这个设置中,我们可以应用反向传播算法调整词向量,直到模型将正确的词与它们的上下文匹配。在我们的例子中,你可以想象每个词都位于一个坐标网格上。词向量的元素可能代表XY坐标。如果你从几何的角度看待单词,你可能会得出结论,你可以通过加或减词向量得到另一个词向量。在现实世界中,这样的向量包含的不仅仅是两个元素,而是 100 到 300 个元素,但直觉是一样的。经过多次训练迭代后,你会看到显著的结果。

尝试使用词向量计算以下内容:

King - Man + Woman = ?

你将得到一个词向量表示“Queen”一词。通过学习将词放入它们的上下文中,模型学会了不同词之间的关系。

我们构建的模型叫做 Word2Vec。我们可以通过两种方式训练 Word2Vec 模型:

  • 使用其周围的上下文预测一个词。这个设置叫做连续词袋模型CBOW)。

  • 使用词预测周围的上下文。这个设置叫做Skipgram

这两种方法除了模型的输入和输出规范外,没有任何区别。

词向量也被称为词嵌入。词嵌入比简单的数字标识符包含更多关于单词的信息,NLP 模型可以利用这些信息来提高准确性。例如,你可以通过以下步骤训练一个情感分类模型:

  1. 创建一个包含用户评论及其情感的训练数据集,情感标记为负面(0)和正面(1)。

  2. 将用户评论嵌入到词向量的集合中。

  3. 使用该数据集训练深度学习分类器。

目前最先进的模型很少使用通过训练单独模型创建的词嵌入。较新的架构允许在任务执行过程中动态学习任务特定的词嵌入,无需使用 Word2Vec。然而,我们在这一章中讨论了词嵌入,因为它们能帮助我们理解计算机如何理解文本的含义。尽管现代模型更复杂且更强大,但这个思想仍然保持不变。

嵌入的概念起源于 NLP,但现在已被广泛应用于推荐系统、人脸识别、包含大量类别数据的分类问题以及许多其他领域。

要训练一个使用词嵌入的分类器,你可以使用卷积神经网络(CNN)。在 CNN 中,每个神经元都会逐步扫描输入文本的单词窗口。卷积神经元学习权重,将附近单词的词向量结合成更紧凑的表示形式,这些表示会被输出层用来估计句子的情感。

你可以在以下截图中看到单个卷积神经元如何处理一个句子:

CNN 在固定窗口中处理文本,这是一个过于简化的观点。实际上,句子开头的单词可能会影响句子的结尾,反之亦然。另一种架构叫做递归神经网络RNNs),它可以处理任意长度的序列,将信息从开始传递到结束。这是可能的,因为所有的递归神经元都与自身连接:

自连接允许神经元在每次迭代中将其输入反馈到自身,拉动其内部状态:

上面的截图展示了一个单一的递归神经元在展开的过程。随着每个新单词的到来,递归神经元会改变它的前一个状态。当最后一个单词被处理时,它会返回其内部状态作为输出。这是最基本的递归架构。实际应用中使用的神经网络具有更复杂的内部结构,但递归连接的思想依然存在。当谈到递归网络时,你可能会听到关于长短期记忆网络LSTMs)的讨论。虽然它们在细节上有所不同,但 RNN 和 LSTM 的思路是相同的。

总结

在本章中,我们揭示了机器学习和深度学习的内部工作原理。我们学习了数学优化和统计学的主要概念。我们将这些概念与机器学习联系起来,最终学习了机器是如何学习的,以及我们如何使用优化算法来定义学习。最后,我们介绍了流行的机器学习和深度学习算法,包括线性回归、树集成、卷积神经网络(CNN)、词嵌入和递归神经网络。本章结束了我们对数据科学的介绍。

在下一章,我们将学习如何建立和维持一个能够交付复杂跨职能项目的数据科学团队。

第二部分:构建和维持团队

数据科学对大多数组织来说是一项创新。然而,每项创新都需要深入和细致的思考——并非所有的想法都同样优秀,也并非所有想法都有足够的资源来实现。本章帮助你识别最好的想法,并将其简化为最小可行产品。

另一个重要的考虑因素是,如何成功地将你的想法推销给所有可能从中受益的利益相关者。

将现代数据分析算法与业务领域专业知识相结合,是每个项目的必要步骤。本章概述了在业务中使用科学方法的重要性。它帮助你回答以下问题:如何为你的业务找到一个高效的数据科学应用?什么是业务指标和技术指标,我们应该如何定义它们?我们如何引入与业务目标高度契合的项目目标?

本节包含以下章节:

  • 第四章,理想的数据科学团队

  • 第五章,进行数据科学面试

  • 第六章,打造您的数据科学团队

第四章:理想的数据科学团队

既然你正在阅读这本书,那么你很可能已经理解团队合作的重要性。通过团队合作,你可以比单独完成任务更高效地完成复杂的项目。当然,一个人也能独自建造房屋,但与他人合作,他们会更快地完成房屋,且结果会更好。

当你与团队合作时,每个人都可以专注于执行几种密切相关的工作类型。为了探索不同的专业领域,我们来看一个建造房屋的例子。建造屋顶需要一套技能,而安装电力则完全不同。作为管理者,你需要对所有专业领域有一个基本的了解,以便理解完成任务所需的所有组件。在什么是数据科学?这一部分,你已了解数据科学的核心概念。接下来,我们将利用这些知识来推导数据科学团队中的角色和专业领域。本章我们将定义、探索并理解不同团队角色以及每个角色的关键技能和责任。我们还将通过两个案例研究来进行说明。

本章我们将涵盖以下主题:

  • 定义数据科学团队角色

  • 探索数据科学团队角色及其职责

定义数据科学团队角色

数据科学团队需要交付复杂的项目,其中系统分析、软件工程、数据工程和数据科学的结合用于实现最终解决方案。在这一部分,我们将探索数据科学项目的主要角色。项目角色描绘了一组相关的活动,可以由专家执行。角色与专家并非严格的一对一对应关系,因为许多专家具备处理多个角色的能力。

一个普通的数据科学团队将包括业务分析师、系统分析师、数据科学家、数据工程师和数据科学团队经理。更复杂的项目可能还需要软件架构师以及后端/前端开发团队的参与。

下面是每个团队角色的核心职责:

  • 项目利益相关者:代表对项目感兴趣的人,换句话说,就是你的客户。他们为项目生成并优先排序高层次的需求和目标。

  • 项目用户:使用你所构建解决方案的人。应该让他们参与需求规格的制定过程,从而提供系统可用性的实际视角。

让我们来看一下分析团队的核心职责:

  • 业务分析师:团队中的主要业务专家。他们帮助塑造业务需求,并帮助数据科学家理解问题领域的细节。他们以业务需求文档BRD)或用户故事的形式定义业务需求,并可能在敏捷团队中担任产品负责人。

  • 系统分析师:他们定义、塑造并维护软件和集成需求。他们创建软件需求文档SRD)。在简单的项目或概念验证PoC)中,这一角色可以由其他团队成员来担任。

  • 数据分析师:数据科学项目中的分析通常需要构建复杂的数据库查询并进行数据可视化。数据分析师通过创建数据集市和交互式仪表盘来支持其他团队成员,并从数据中提取洞见。

让我们来看一下数据团队的核心职责:

  • 数据科学家:他们创建模型,进行统计分析,并处理与数据科学相关的其他任务。对于大多数项目,选择并应用现有的算法就足够了。一位专注于将现有算法应用于解决实际问题的专家被称为机器学习深度学习工程师。然而,某些项目可能需要进行研究并创建新的最先进模型。对于这些任务,机器学习或深度学习研究员会是更合适的人选。对于计算机科学背景的读者,我们可以将机器学习工程师和研究科学家之间的区别,粗略地描述为软件工程师和计算机科学家之间的区别。

  • 数据工程师:他们负责所有数据准备和数据处理。在简单的项目中,具有数据工程技能的数据科学家可以担任这一角色。然而,在有较为复杂的数据处理需求的项目中,不要低估数据工程师的重要性。大数据技术栈非常复杂,在大规模部署和使用时需要专业的技术人员,而没有人比数据工程师更适合处理这项任务。

  • 数据科学团队经理:他们协调数据团队的所有任务,规划活动并控制截止日期。

让我们来看看软件团队的核心职责:

  • 软件团队应负责构建移动、Web 和桌面应用程序的所有额外需求。根据项目的复杂程度,软件开发可以由一个开发人员、一支团队,甚至多个团队来完成。

  • 在包含多个系统的大型项目中,你可能需要软件架构师的帮助。

现在我们来看看角色如何协作以构建最终解决方案的一般流程:

让我们来看一下每个步骤的流程和交付成果:

  1. 业务分析师根据查询项目相关方和用户来记录业务需求。

  2. 系统分析师根据业务需求并查询项目相关方和用户来记录系统(技术)需求。

  3. 数据分析师通过创建所请求的数据集市和仪表盘来支持团队。这些可以在开发过程中以及生产环境中供团队的每个人使用。如果数据分析师使用商业智能工具,他们可以直接为最终用户构建仪表盘。

  4. 数据科学家(研究员)使用文档化的需求和原始数据来构建模型训练管道,并记录应该用于准备训练、验证和测试数据集的数据处理要求。

  5. 数据工程师基于步骤 3中制作的原型构建生产级数据管道。

  6. 数据科学家(工程师)使用处理过的数据来构建用于训练和预测管道的生产级模型以及所有必要的集成,包括模型 API。

  7. 软件团队使用完整的模型训练和预测管道来构建最终解决方案。

请注意,依据项目的复杂性,这一过程可以简化或更加细化。例如,大型项目可能需要将分析专家分为两组:数据分析和软件分析。然后,软件团队会有单独的需求文档。较简单的项目可能会将一些步骤或角色合并,或者省略它们。

在接下来的部分,我们将探讨如何根据项目复杂度来组建团队并为专家分配项目角色。

探讨数据科学团队的角色及其职责

要完成一个数据科学项目,你将需要一位数据科学家。那么,单一专家能否主导一个项目呢?为了回答这个问题,我们可以将数据科学项目拆解为各个阶段和任务,这些阶段和任务在所有项目中或多或少都会出现。

在开始项目之前,你需要一个想法,使你的客户能够实现他们的目标并简化他们的生活。在商业中,你将着眼于提升公司内的关键业务流程。有时,想法已经确定,你可以直接进入实施阶段,但更多时候,你的团队将是这个过程的推动者。因此,我们理想中的专家必须能够提出一个能为客户带来价值的数据科学项目的想法。

接下来,我们将研究两个项目示例,看看如何通过小团队甚至一个跨职能专家来处理简单项目,而更大规模的项目则需要更具多样性的团队,每个团队成员负责一到两个特定的角色。

案例研究 1 – 将机器学习应用于银行防止欺诈

为了探讨数据科学项目可能的样子,我们将看一个案例研究。玛丽在一家银行担任数据科学家,银行的欺诈分析部门开始对机器学习ML)产生兴趣。她在创建机器学习模型并通过构建 API 将其集成到现有系统中有着丰富经验。玛丽也有将工作成果展示给客户的经验。

这个部门的主要活动之一是检测和防止信用卡欺诈。他们通过使用基于规则的欺诈检测系统来实现这一目标。该系统监控银行中发生的所有信用卡交易,并检查是否有任何一系列交易应被视为欺诈行为。每一个检查都是硬编码并预先设定的。他们听说机器学习相较于传统的基于规则的欺诈检测系统有着更多的优势。所以,他们要求 Mary 实现一个欺诈检测模型,作为现有系统的插件。Mary 已询问现有欺诈检测系统的数据集和操作员,并且部门确认将提供来自系统本身的所有必要数据。他们所需要的只是一个可工作的模型和简单的软件集成。员工们已经熟悉常见的分类指标,因此他们被建议使用 F1 分数和 k 折交叉验证。

在这个项目设置中,项目相关方已经完成了业务分析阶段。他们有了想法和成功标准。Mary 可以从单一系统中轻松获取数据源,并且相关方可以将任务定义为分类问题。他们还定义了一个清晰的测试结果的方法。软件集成要求也很简单。因此,项目的角色流程简化为几个步骤,所有步骤都由单一的数据科学家角色执行:

结果是,Mary 列出了以下完成任务的步骤:

  1. 创建一个机器学习模型。

  2. 进行测试。

  3. 创建一个模型训练管道。

  4. 创建一个简单的集成 API。

  5. 记录并将结果传达给客户。

这个项目看起来简单且定义明确。根据这个描述,我们可以相信 Mary 可以独立完成这项工作,几乎不需要监督。

案例研究 2——在零售公司中为机器学习找到应用场景

现在,让我们看一下另一个案例。我们朋友 Jonathan 所在的零售公司要求他提出如何利用数据科学和分析来改善他们的业务。Jonathan 在零售行业工作多年,因此他非常了解业务方面的内容。他还读过一些书籍并参加过几次数据科学的活动,因此他理解数据科学的实际能力。凭借对商业和数据科学的双重了解,Jonathan 能够看到数据科学如何改变他的工作环境。在列出一系列想法后,他将从业务角度评估这些想法。复杂度最低且价值最高的项目将成为实施候选项。

这家零售公司在全国拥有超过 10,000 家店铺,确保所有店铺的服务质量已变得越来越困难。每家店铺都有固定的全职员工。然而,每家店铺的访客数量不同,这个数字取决于店铺的地理位置、节假日以及可能的许多未知因素。因此,一些店铺人满为患,而一些店铺的访客量很低。Jonathan 的想法是改变员工的聘用策略,以提高客户满意度并平衡员工的工作负担。

他建议不聘请固定的店铺团队,而是让团队具有弹性。他希望创建一个特殊的移动应用,使得店铺能够迅速调整员工名单。在这个应用中,店长可以为员工创建任务,任务时间可以从一小时到一年不等。一组员工可以看到附近店铺的所有空缺岗位。如果某个具备必要技能的员工看到感兴趣的任务,他们可以接受并前往店铺。一个算法将为店长准备任务建议,店长会将工作项分配给员工池。这个算法会使用多个机器学习模型来推荐任务。一个模型将预测每个店铺的预期客户需求。第二个模型是计算机视觉算法,它将衡量店铺内的排队长度。通过这种方式,每个店铺将使用适量的员工,并根据需求水平进行调整。通过这个新应用,店铺员工将能够规划假期并请求临时替代人员。计算表明,这个模型将为 50,000 名员工提供服务,每位员工每周平均工作 40 小时,同时为 10,000 名兼职员工提供服务,每位兼职员工每周平均工作 15 小时。管理层认为这个模型在经济上更具可行性,并同意在一家店铺进行系统测试。如果测试成功,他们将继续推广新政策。

下一步他们要求 Jonathan 提出一个实施计划。他现在需要将项目分解为一系列任务,以便在一家店铺部署系统。Jonathan 准备了以下分解方案:

  1. 收集并记录移动应用、预测模型和计算机视觉模型的初步需求。

  2. 收集并记录系统的非功能性需求和服务水平协议(SLA)。

  3. 决定开发、测试和生产所需的硬件资源。

  4. 寻找具有训练数据的数据源。

  5. 创建用于从源系统导出数据的数据适配器。

  6. 创建软件系统架构。选择技术栈。

  7. 创建开发、测试和生产环境。

  8. 开发一个预测模型(完整的机器学习项目生命周期)。

  9. 开发一个线长识别模型(完整的机器学习项目生命周期)。

  10. 开发一个移动应用。

  11. 将移动应用与模型进行集成。

  12. 将系统部署到测试环境并执行端到端的系统测试。

  13. 将系统部署到生产环境。

  14. 在一店铺启动系统测试。

这个计划中的每一个点都可以进一步分解成 10-20 个附加任务。这个项目的完整任务分解可能轻松包含 200 个点,但我们将在这个层面停止,因为这足以用于讨论。

事实上,计划会不断变化,因此 Jonathan 决定使用一个软件开发项目管理框架,比如 SCRUM,来管理截止日期、需求变更和利益相关者的期望。

现在让我们看看 Jonathan 需要在哪些领域具备专业知识才能完成这个项目。他需要在以下几个领域熟练:

  • 零售业务

  • 软件项目管理

  • 需求收集

  • 软件与硬件架构

  • 数据工程

  • 数据科学

  • 机器学习

  • 深度学习与计算机视觉

  • 移动应用开发

  • 后端软件开发

  • 软件集成

  • 软件测试

  • 开发运维

Jonathan 是否具备完成工作软件系统所需的所有技能?我们可以确定有一些人能够做到这一点,但更有可能遇到的是在多个密切相关的领域拥有专长的专家。特别是,数据工程师很可能擅长数据库、数据库管理和软件集成。许多数据科学家也擅长后端软件开发。有些人精通创建数据可视化仪表板。在项目的角色流动方面,可以使用完整的图表来指导此项目。

在一个平均的数据科学项目中,预计会填充以下团队角色:

  • 数据科学家

    • 机器学习或深度学习工程师

    • 机器学习或深度学习研究员

  • 数据工程师

  • 数据分析师

  • 系统分析师

  • 商业分析师

  • 后端软件开发工程师

  • 前端软件开发工程师

  • 技术团队领导

  • 项目经理

根据项目的复杂性,你可以将一些角色合并。项目规模越大,团队的多样性和规模也会越大。接下来,我们将了解数据科学团队角色的关键技能和责任。

数据科学家的关键技能

数据科学家是一个相对较新的职业,对其职责的模糊定义很常见。这种不确定性会导致许多问题。招聘网站上泛泛的职位描述对优秀候选人没有吸引力。如果你不先在心中明确这个定义,求职者就无法了解该职位所需的要求。如果某人去一个工作岗位时不知道对他们有什么期望,情况会变得更糟。没有清晰的目标,或者至少没有明确的下一个里程碑定义,你的团队就会迷失方向。为团队角色定义清晰的责任是让团队能够高效运作的基础。

一个理想的数据科学家通常被描述为以下三者的结合:

  • 领域专业知识:这包括数据科学家所在工作环境的知识,如医疗、零售、保险或金融等。

  • 软件工程:即使是最先进的模型,如果只能呈现纯数学抽象,也无法带来改变。数据科学家需要知道如何将他们的想法转化为可用的形式。

  • 数据科学:数据科学家需要精通数学、统计学以及至少一项或多项数据科学的关键领域,如机器学习、深度学习或时间序列分析。

理解每个专业领域在这个列表中的存在是非常重要的。我们将从领域专业知识开始。你很难找到一个世界级的商业专家,同时还能训练最先进的深度学习模型。幸运的是,你不需要寻找“独角兽”。数据科学家需要领域专业知识,主要是为了理解数据。在处理需求和利益相关者的期望时,它也很有用。对保险业务有基本到中等程度的理解,可以在构建模型的整个过程中帮助数据科学家。

例如,我们来看一下商业专业知识如何帮助为保险公司构建模型:

  • 与保险专家使用相同的语言交流有助于发现他们的痛点和需求,这样数据科学家可以调整他们的目标,以实现更好的结果。

  • 保险专业知识将帮助探索和理解公司数据库中的原始数据。

  • 保险专业知识有助于数据预处理。它帮助数据科学家为机器学习模型构建数据集。

因此,领域专业知识不是数据科学家的首要技能,但基本到中等水平的理解可以大幅提升结果。

下一个组成部分是软件工程专业知识,这常常被忽视。算法通常与组织的最关键流程相联系,因此这些算法的可用性和稳定性要求很高。数据科学家从不创建抽象模型。即便在研究机构,数据科学家也会写代码。而且,离实际应用越近,好的代码就越重要。良好的编程技能使数据科学家能够编写结构良好、文档齐全且可复用的代码,其他团队成员也能理解。软件工程专业知识使他们能够构建在高负载下不易失败的系统,并能够从简单的概念验证测试扩展到全组织范围的部署。

最后,但同样重要的是数据科学技能。它们是构建有效模型所必需的关键工具。然而,数据科学是一个非常广泛的领域。一定要了解你需要使用哪些算法,并明白你需要什么样的专家。计算机视觉专家并不一定适合电影推荐项目。如果你雇佣了一位数据科学家,这并不意味着他们在机器学习和数学统计的所有领域都非常精通。

发现面试过程的目的

首先,你应该弄清楚为什么需要进行面试。让我们做一个快速的练习。问问自己为什么,然后写下答案,直到没有更多可以说的。之后,回忆一下你上一次进行的面试。它与你的目标是否一致?结果应该为你提供一个即时的改进方向。

从雇主的角度来看,面试的唯一目的是找到一位合格的候选人来填补职位。从员工的角度来看,面试的目的是找到一个好的团队、一个有趣的项目、一家可靠的公司来合作,以及令人满意的薪酬。我们常常忘记,面试是一个对话,而不仅仅是对技能的考验。

不幸的是,面试的主要目标没有一个明确且普遍的定义。这是因为每个目标对每个职位来说都是独一无二的。你应该根据对你面试的职位的详细理解来定义这个目标。如果你在寻找一位数据科学家,那么要严格定义你希望他们做什么。新团队成员将解决哪些任务?仔细思考一下这个职位的第一天工作将是什么样的。核心职责是什么?哪些技能是有用的但不是强制性的?基于这些,你可以开始为候选人草拟一套期望的技能要求。要具体。如果你要求候选人了解 SQL,一定要有明确的理由来支持这一要求。

如果你的面试目标是找到一位理想的、全球顶尖 0.1 百分位的世界级专家,那么再想一想。主要目标是找到一个能够胜任工作的人。这个人可能必须是世界上最优秀的专家。如果是这样,这个要求应该加以解释和证明。为了达成这一理解,你需要描述这份工作将是什么样的。在你决定描述完成之后,重新编写它,考虑到候选人。它应该简短、易读,并完整地展示这份工作的内容以及期望是什么。职位描述的模糊性通常源于缺乏这种理解。我们只是需要一个人,他们的职位描述是这样写的。你的职位描述应该写成我们确切知道我们需要什么,你可以依赖我们。如果你做不到这一点,难道你真的需要发布一个新的职位吗?

对你的目标的具体理解将在多个方面有所帮助:

  • 你将了解应该寻找什么样的专家。

  • 寻找职位候选人的人会清楚地知道你对他们的期望。这将使判断他们的经验是否相关变得更容易。

  • 清晰的目标定义将帮助你设计有针对性和富有洞察力的面试问题。

如果你的需求列表看起来过长,尝试简化它。也许你过于热衷,列出的某些技能并不是必需的。或者,你可以考虑招聘两位具有不同背景的人?如果你发布的职位描述包含广泛的跨职能要求,一定要有背后的理由。

如果你的职位描述很复杂,那么你会发现以下几点:

  • 招聘候选人的时间将更长,因为你要求更多的技能和经验。

  • 候选人会期待更高的薪资。

  • 面试过程可能会很长,并且可能会延续到多个回合。

  • 你可以选择的候选人将会更少。

所有这些限制条件应该有充分的支持理由。如果没有,考虑简化。

拥有一个好的目标并不意味着一切,还需要良好的执行。我们现在将从候选人的角度来讨论面试过程中的偏见和同理心问题。

数据工程师的关键技能

随着项目变得更加复杂,数据管理变得更加困难。你的系统可能会从多个来源消耗数据,其中一些是实时数据流,而另一些可能是静态数据库。系统需要处理的大量数据也可能非常庞大。这一切导致了创建一个数据处理子系统,用于管理和协调所有数据流。管理大量数据并创建能够快速处理大数据量的系统,需要使用专门的、适合此任务的软件技术栈。

因此,数据工程师这一独立角色应运而生。数据工程师的关键知识领域如下:

  • 软件工程

  • 大数据工程:包括分布式数据处理框架、数据流技术和各种编排框架。数据工程师还需要熟悉与数据处理相关的主要软件架构模式。

  • 数据库管理与数据仓储:关系型数据库、NoSQL 数据库和内存数据库。

软件工程技能对数据工程师非常重要。数据转换代码往往存在设计不当的问题。遵循软件设计的最佳实践将确保所有数据处理任务都是模块化的、可重用的,并且易于阅读。

处理大数据涉及创建高度并行的代码,因此了解分布式处理系统也是必不可少的。主要的软件平台,如 Hadoop 生态系统、Apache Spark 和 Apache Kafka,都需要深入理解其内部机制,以编写高效且稳定的代码。

理解经典的关系型数据库系统和数据仓库方法论对数据工程师来说也是一项重要的技能。关系型数据库在大公司中是非常常见的数据存储选择。SQL 的普及程度让我们可以把它视为数据的通用语言。因此,你可以预期关系型数据库管理系统RDBMS)将会是你项目中的常见数据来源。关系型数据库非常擅长存储和查询结构化数据,因此如果数据量适中,你的项目很可能也会使用它们。掌握流行的 NoSQL 数据库经验也是一种便利。

数据科学经理的关键技能

本节将介绍数据科学经理需要具备的几个关键技能,具体包括:

  • 管理:数据科学团队经理应该具备对主要软件管理方法论的良好理解,如 SCRUM 和 Kanban。他们还应了解管理数据科学项目的各种方法和具体策略。

  • 领域专长:他们应该对业务领域有很好的了解。如果缺乏这一点,任务分解和优先级排序就变得不可能,项目也必然会偏离轨道。

  • 数据科学:对数据科学和机器学习背后基本概念的良好理解至关重要。没有这些理解,你就像是在不知道房子是什么的情况下建造房子。这将有助于简化沟通,并帮助创建良好的任务分解和故事情节。

  • 软件工程:基础软件工程知识将确保经理能够关注项目中的关键方面,如软件架构和技术债务。优秀的软件项目经理有开发经验。这些经验教会他们编写自动化测试、重构和构建良好的架构。不幸的是,许多数据科学项目因为糟糕的软件设计选择而受到影响。走捷径在短期内看似可行,但从长远来看,这些选择最终会反噬项目。随着项目的规模逐渐扩大,团队增加,整合数量增加,新的需求出现,糟糕的软件设计会让项目停滞不前,最后只剩下一个选择——彻底重写系统。

向开发团队寻求帮助

创建数据产品与创建新软件系统密切相关。大规模项目可能会有很多软件需求,包括构建 UI、开发者 API 和在系统中创建基于角色的工作流。如果你感觉数据科学团队无法独立完成所有任务,一定要向软件开发团队寻求帮助,团队中需要有软件工程师、分析师和架构师。如果你除了构建机器学习模型外,只需要构建几个 REST 服务、数据集成任务和一个简单的管理 UI,那么数据科学团队应该能胜任。但如果你需要处理比这更复杂的任务,请确保扩展你的团队。

概述

在本章中,我们首先介绍了数据科学家的定义。然后,我们通过两个示例来探讨数据科学家是否可以单独工作,或者是否需要团队合作。接下来,我们研究了数据科学家、数据工程师和数据科学经理需要具备的各种技能和素质。我们还简要地探讨了在什么情况下需要向开发团队寻求帮助。

最后,我们定义了数据科学团队的关键领域,包括分析、数据和软件。在这些领域中,我们定义了项目角色,帮助你组建一个平衡且强大的团队。我们可以通过小型团队解决简单的项目,团队成员共享不同角色的责任。但当项目复杂性增加时,组织结构也需要随之扩展。我们还强调了遵循软件工程最佳实践的重要性,并寻求软件开发团队的帮助。

认识到明确责任和期望对于交付复杂的数据科学项目至关重要,我们将在下一章中使用这些理念,探讨如何为数据科学团队制定有效的招聘流程。

第五章:进行数据科学面试

在这一章中,你将学到如何进行高效的数据科学面试。我们将探讨如何将招聘过程与实际工作经验结合起来,让你所寻找的候选人清楚地了解他们将要做什么样的工作。本章的建议将帮助你摆脱不必要的面试仪式,使招聘过程更加高效。

你已经有多久没有经历技术面试了?那是一段愉快的经历吗?如果你通过了面试,你能判断面试问题与日常工作之间的相关性吗?我敢打赌那段经历很糟糕。常见的抱怨是,所有面试都让人感到有压力,且问题不相关。技术面试存在着深刻的缺陷。我们以为自己是在用一种理性的思维方式将候选人筛选出来,只挑选那些能够胜任工作的卓越专家。实际上,面试是有偏见的。面试的成功与实际工作的成功几乎没有任何相关性。如果随机选择候选人,比许多公司现有的招聘流程取得更好的结果,我也不会感到惊讶。

在这一章中,我们将涵盖以下主题:

  • 技术面试的常见缺陷

  • 在面试中引入价值观和伦理

  • 设计良好的面试

技术面试的常见缺陷

如果你有软件工程背景,面试官是否常常要求你在白板上反转二叉树,或者找到最大子数组和?如果你来自数据科学背景,你曾经在纸上或白板上列出过多少个中心极限定理的证明?如果你是团队领导,你自己是否也问过这样的题目?我并不是说这些问题不好,恰恰相反。掌握核心计算机科学算法和能够推导证明对某些工作可能很重要。但我们问这些问题的目的是什么呢?我们想了解坐在对面的人什么呢?对大多数公司来说,能否回答这些问题根本不相关。那么,问这些问题的原因是什么呢?嗯,因为刻板印象认为程序员必须懂算法,数据科学家必须懂数学和统计;这种思维方式是合乎逻辑且直接的。当我们这样思考时,我们会想象出一个通用的集体形象:一个超级程序员和一个数据科学奇才。反转二叉树可能对某些公司某些项目有用,但它为什么对你们公司有用呢?

在阅读本章时,我要求你保持开放、批判和诚实的心态。本文不会给你能改善面试的秘密知识,而是会给你一些工具。如果你愿意投资这些工具,你将获得更加直接、简单和愉快的面试,进而找到合适的人选。

寻找你不需要的候选人

大多数公司都在寻找顶尖的开发人员、杰出的数据科学家,并且团队成员都是全球最优秀的人才。我们来看一下来自一个真实招聘网站的数据科学家职位描述。

候选人的主要工作重点将是利用大型公司数据集应用不同的技术(数据挖掘/统计分析/构建预测系统/推荐系统)。应用机器学习模型并测试不同操作的有效性。候选人必须具备强大的技术专长,能够使用一套广泛的数据挖掘/数据分析工具。候选人必须能够构建和实现数学模型、算法以及仿真。我们寻找具备以下技能的候选人:

  • 与业务案例合作:寻找机会并利用公司数据创造商业解决方案。

  • 从公司数据库中挖掘和分析数据,推动产品开发和销售技巧的优化和改进。

  • 评估新数据来源和数据收集的有效性与准确性。

  • 在需要时,利用第三方信息来源扩展公司数据。

  • 使用预测建模来增加收入生成、广告定向以及其他业务成果。

  • 分析业务案例,确定数据来源(内部/外部)以及使用的数据挖掘/分析方法。

  • 开发数据标准化引擎,通过提取转换加载ETL)过程对数据源进行数据清洗/去重。

  • 创建、训练并测试预测模型,解决已定义的业务问题。

  • 开发适用于数据集的算法。

  • 设计收集数据的数据结构模型。

  • 促进从概念验证POC)到生产环境的解决方案构建。

  • 与业务负责人合作,收集更多有关业务案例的信息。

  • 处理由核心业务生成的数据。

  • 准备以敏捷方式工作(每日站会、冲刺计划、冲刺回顾、 retrospectives)。

  • 在一个快速适应创意变革的环境中,运用敏捷原则工作。

  • 积极与组织内不同开发团队合作。

  • 准备适应新的工具/库/技术/平台。

  • 对机器学习技术和算法有出色的理解,如k-近邻算法kNNs)、朴素贝叶斯、支持向量机SVM)、决策树、聚类、人工神经网络。

  • 对数学统计有深刻理解(如分布、统计检验、回归等)。

  • 有创建和使用高级机器学习算法与统计方法的经验,如回归、仿真、情景分析、建模、聚类、决策树、神经网络等。

  • 熟练使用查询语言,如 SQL。

  • 有与数据架构、数据模型、数据仓库/数据湖相关的工作经验。

  • 能够在最小监督下工作。

  • 强大的数据分析能力。

  • 具有创意和分析思维,具备强大的问题解决能力。

  • 拥有技术或专业服务背景,最好在 AWS、Azure、安全或 AI/ML 等一个或多个领域。

  • 对咨询业务有深入理解。

  • 强大的结构化工作方法、多任务处理和时间管理能力。

  • 自我驱动的独立工作伦理,推动内部和外部的责任感。

  • 具有使用常见数据科学工具包和库的经验,如 pandas、Keras、SciPy、scikit-learn、TensorFlow、NumPy、MatLab 以及其他流行的数据挖掘技术。

  • 使用统计计算语言(如 R、Python 等)处理和分析大数据集的经验。

  • 熟悉并具有 SQL 语言的知识和经验。

  • 具有使用 Azure/AWS 服务的经验。

  • 有 C++/C#经验者优先。

  • 根据这个描述,候选人必须掌握 4 到 5 种编程语言,达到能够启动 POC 并完成一个可投入生产的系统的水平。此外,还必须具备机器学习、深度学习、ETL 和业务分析等技能。候选人应能够学习列表中没有的任何新技术,并且应具备自我驱动和独立工作的能力。

如果你仔细想想,这就是理想的候选人:一支单兵作战的部队,一匹独角兽。这样的人成为存在吗?是的,但他们极为稀有。每家公司都需要这样的人来完成项目并实现目标吗?我会大胆回答:不需要。公司并不是为了找到最适合目标的人,而是寻找适合所有可能目标的人。追求普遍性和包罗万象,这样的招聘过程将是漫长、疲惫和充满压力的。阅读完这份冗长的要求清单后,候选人无法了解这份工作到底是什么样子。所有的描述都模糊且难以理解。这个职位描述没有透露这份工作是什么样子的。职位描述应清晰列出以下方面:

  • 候选人的未来职责

  • 承担这些职责的要求

当职位描述模糊且复杂时,测试所有所需的技能无疑会需要多轮面试,这会让整个过程更加疲惫。根据这个清单充分评估多个候选人几乎是不可能的。经过漫长的筛选后,公司很可能只是随便录用一个人。之后,麻烦才刚刚开始。这个职位描述的最大问题是缺乏方向。雇主并不清楚候选人的职能和职责。这个问题比看起来更为深刻;职位描述实际上只是一个症状,而非根本问题。对于新员工而言,模糊性和不明确性不会在第一天工作时就消失。如果雇主没有完全弄清楚新员工应该做什么,工作流程本身就会变成一个未确定的混乱。大多数面试和招聘流程只是对一个次优、充满压力且有偏见的候选人筛选过程的合理化。幸运的是,这些问题是可以解决的。你所需要的只是诚实、明确的目标定义和一些准备工作。

将价值观和伦理引入面试

我们常常从单方面的角度看待面试。我们希望找到一个可靠的团队成员,能够胜任工作。很容易忘记,糟糕的面试可能会吓跑优秀的候选人。更重要的是,潜在的候选人会通过面试对你的公司做出判断。糟糕的面试会导致负面的宣传。有效且顺利的面试的关键是考虑候选人的体验。

如果你已经成功地为候选人定义了诚实的要求,下一步就是从整体上考虑面试体验。为了让新队员展现出最佳状态,面试应该像一个真正的工作过程,而不是像一场毕业考试。

考虑一下大多数技术面试是如何进行的:

  • 你会经过简历筛选。最优秀的人通常拥有博士学位,并且至少有 5 年(可疑的)在大型科技公司的经验。

  • 你完成了一些关于技术能力的在线测试。

  • 你提交了你的 GitHub 库和作品集项目进行审查。

  • 然后,你将参加一次在线筛选面试。你需要回答一系列与多种技术和科学领域相关的技术问题,这些领域可能对你未来的工作有用。

  • 接下来,你发现自己站在一个白板前,回答一系列关于软件开发、软件架构、机器学习、组合优化、范畴理论和其他重要话题的复杂且非常具体的问题,这些问题用来从最优秀的人才中选拔最优秀的。

  • 多位专家,分别擅长各自领域,会测试你不同的技能。面试官很可能会用他们自己经验中的棘手问题来考验你,而每个问题都曾让他们耗费数天时间来解决。

  • 最后,一位公司高管会评估你是否符合公司的文化,并且与你的价值观和目标是否一致。

剩下的就是加上一些 DNA 测试、IQ 评分筛选、测谎仪测试,还有艺术和国际象棋能力的两项检查。

你可能觉得好笑,但在某些俄罗斯公司,软件开发人员确实需要通过测谎仪测试才能入职。

如果你已经明确定义了职位要求,你会发现大部分步骤都是不必要的。更重要的是,它们可能会让你的面试过程偏向那些不适合你职位的人。

这个过程与你的实际工作经验完全不同,以下是其中的一些事实:

  • 面试会带来巨大的压力,这会显著影响你的表现。

  • 你将接受与该职位工作任务无关的考核。

  • 面试问题和家庭作业与工作任务没有关系。

如果你能设计一个尽可能接近实际工作经验的面试,所有无用的面试环节都可以去掉,包括以往的工作经验和教育背景筛选。

面试过程必须尊重候选人的情感状态,并将其视为一个人。它应该是人性化的。一旦你开始做到这一点,潜在的候选人名单会增加,面试会变得更简短、更高效。

保持开放的心态,摒弃偏见。我与一些最有才华和成功的软件工程师、软件架构师以及数据科学家共事过,他们的工作经验与职位无关,或者没有正式的教育背景。我并不是说这些事情不重要,它们确实重要,但并不是决定性因素。相关性不代表因果关系。通过排除不必要的预筛选过滤器,你错失了结识那些能和你共同工作多年的才俊的机会。当然,一些组织确实需要预筛选过滤器。例如,你不会聘请没有文凭的外科医生。在某些领域,比如医学,教育确实提供了自学无法获得的必要经验。但在软件工程和数据科学等领域,知识和经验可以通过几次点击就能获得,情况就完全不同了。

最后,记得要有人情味。对你面试的候选人要友善,创造愉快的体验,你会得到更好的结果。如果你一天面试很多人,这可能会很难,所以最好限制自己每天最多只面试一到两个人。

你可能认为这样的面试会占用不合理的时间,且查看每位候选人是不可能的。事实上,情况正好相反。设计人性化面试的关键是将焦点从你的组织转向候选人,我们将在下一部分探讨如何做到这一点。

设计好的面试

我们如何让面试更加相关并且高效呢?理想的面试应该是在真实工作环境中进行几个月的测试。虽然有些公司可以承受不进行面试,改用带薪试用期,这是一种非常昂贵的招聘策略,并不是每个企业都能负担得起。一个好的面试应该作为实际工作经验的替代。它不应该是测试一个人的技能,而是测试一个人是否能够胜任特定的工作。如果理想的候选人测试是试用期,那么最糟糕的测试方式就是白板面试(除非你是在面试计算机科学讲师)。设计一个出色的面试,应该尽可能贴近你的工作流程和你每天解决的问题。

设计测试任务

当然,可能有几次你或你的同事在同一职位上需要证明一个定理或从零实现一个复杂的算法,但仅仅是将这个问题纳入面试流程中是否足够?如果你的团队只遇到过几次这个问题,那它最多也只能作为一个补充问题。大多数面试问题应当来源于你们团队每天解决的最常见问题。绝对不要去网上搜索面试问题。你的面试应该尽可能具体,通用问题会让面试变得乏味且与寻找的答案无关。

问题的一个常见来源是面试官自己的知识储备。你可能读过许多复杂而有趣的书籍和博客文章。如果从这些材料中获得的知识,尽管它们在智力上非常有价值,但与候选人的工作无关,请将其排除在面试之外。想象一下,一个机器学习工程师的面试,候选人被问到关于变分自编码器中重新参数化技巧的数学细节,而他的工作是将预训练的分类器交付到生产环境中,作为可扩展的服务。

之前的案例可能对你来说看起来不太现实,但它确实发生在我认识的一位软件开发者身上。他当时正在面试一个分布式系统开发者的职位。在一些初步的技术问题之后,面试官开始问关于在 Java 应用中集成本地代码的细节:

开发者:你们在应用中集成本地代码吗?

面试官:不行。

开发者:这很好。因为我真的不太懂这个话题。

面试官:我还是想问一下。

开发者:但我对本地代码集成了解不多。而且,正如你所说,这并不相关。我们能继续吗?

面试官提问。

无论从哪个角度看,这个问题都是不合适的:

  • 这与该职位的技能要求无关。

  • 这与公司无关。

  • 面试官已经知道候选人无法提供答案。

  • 它增加了面试的压力因素,可能影响后续更相关问题的回答。

  • 它降低了候选人对公司价值的评价。

相反,一个好的面试问题应当是以下这些:

  • 与候选人在工作中需要解决的问题相关。

  • 和候选人的日常工作经验一样困难或简单。

任何面试问题的最大问题在于其时间跨度。我们通常希望一个典型的面试问题能在 10 分钟内解决。但真实的工作环境并没有这样的时间限制。为了缩小差距,你可以设计一个测试任务。理想情况下,这个任务应该能够在 2 到 4 小时内完成。

创建测试任务时,按照以下步骤进行:

  1. 选择一个与你公司中类似角色(或由具有相同职称的队友直接完成)的核心任务。

  2. 然后,用一段文字描述这个任务。你希望你的任务描述是SMART的(即具体的、可衡量的、可实现的、相关的、和时间限定的)。

  3. 尝试估算完成该任务所需的时间。由于你是根据实际工作经验来设定的,这个任务可能需要几天或几周才能完成。只有非常投入的候选人才能接受一个如此长时间跨度的任务。你可以通过将其拆分为多个小任务,并仅选择最重要的任务作为任务的一部分,从而缩短其完成时间。你可以将所有附加任务转化为你在检查测试任务结果时提出的问题。

  4. 如果你具备必要的技能,可以自己完成任务,或者请求队友的帮助。请注意,如果你无法独立完成任务,你将在面试中需要队友的帮助。

在进行任务时,检查与任务相关的所有事项:

  • 它是否相关?

  • 你能在预期的时间框架内完成它吗?

  • 它是否测试了你面试的职位所需的所有技能?

  • 你能围绕这个任务创建额外的问题来组织面试吗?

你可能需要几次迭代才能创建一个好的测试任务。当你完成后,你需要决定候选人在哪里实施任务。根据你的要求,候选人可以远程完成任务,或者你可以要求他们坐在你的办公室里。如果任务实施所需的时间较长且你无法进一步精简,考虑支付候选人的时间报酬。记住:雇佣不合适的候选人会花费你更多。

例如,我们可以为初级数据科学家创建一个测试任务。假设我们的公司为远程教育平台提供预测分析服务。这些公司需要评估每个学生成功完成课程的可能性。每个客户收集关于学生的不同数据。虽然模型构建过程相对标准化,但为了为每个客户创建具有令人满意质量的分类器,需要进行定制的数据预处理和特征工程。我们公司承诺每个客户将获得一个 F1 分数至少为 0.85 的模型。

初级数据科学家遵循标准流程来创建和部署分类模型。该流程有详细文档,并做了说明。流程包括几个阶段,例如:

  1. 获取由数据工程团队通过公司数据门户 Web 应用提供的训练数据集。

  2. 使用公司自助服务门户创建一个基于 Web 的数据分析和建模环境。

  3. 将数据上传到环境中,并创建一个包含至少 10%数据集的留出测试集。

  4. 执行探索性数据分析EDA),并使用梯度提升 算法创建一个基准分类器。使用 10 折交叉验证来衡量基准 F1 分数。

  5. 从客户数据中创建新特征,并调整模型参数以提高 F1 分数。

  6. 如果你能达到不低于 0.85 的 F1 验证分数,则测量测试分数。

  7. 通过生成一个指向你环境的链接,将结果报告给你的经理。

  8. 如果结果通过批准,按照公司的指南创建一个 REST API。

  9. 向你的经理报告结果。

我们希望测试的该职位最重要的技能如下:

  • 能够使用我们公司用于构建分类器的框架和工具

  • 能够构建二分类器

  • 能够对我们日常工作中遇到的类似数据集执行 EDA 和特征工程

  • 能够遵循流程并报告结果

  • 理解公司分类器构建过程背后的原理

为了为初级数据科学家创建一个测试任务,我们可以创建一个与客户数据集相似的数据集。如果候选人从原始数据中创建了几个有用的特征,他们的模型可以达到所需的 F1 分数。候选人理想的工作环境是我们公司的办公室,但远程工作选项也是可以接受的。我们已经为每位候选人提供了这两种选择。

我们的初级数据科学家通常用 2 到 3 小时完成类似的任务。他们大部分时间都花在了步骤 5上。我们决定故意简化任务,使其能够在 1.5 小时内完成。学习如何使用公司所有的内部工具,包括自助服务门户,通常需要 4 小时,因此我们决定在测试任务中使用广泛知名的开源工具。大多数候选人已经熟悉这个选项,而且我们所有的内部系统都与开源替代工具兼容,因此这将是一个可行的简化方案。

我们已经创建了以下的测试任务描述:

我们提供了一份包含客户数据的 CSV 文件。我们要求你构建一个二分类模型,用来预测学生是否完成一门课程。数据文件中每一列的描述如下:[……摘要描述缺失]。你可以使用以下步骤来构建你的模型:

  1. 执行 EDA 并使用梯度提升算法创建一个基准分类器。使用 10 折交叉验证来衡量基准 F1 分数。

  2. 从客户数据中创建新特征,并调整模型参数以提高 F1 分数。

  3. 如果你的 F1 验证得分不低于 0.85,请测量测试得分。

  4. 向我们报告结果。

预计完成此任务的时间为 1.5 小时,但你可以申请延长时间。请使用以下工具来创建解决方案:[……]。

我们还创建了一些额外的问题,用来检查候选人对我们工作流程的理解:

  • 交叉验证是如何工作的?

  • 交叉验证的替代方法有哪些?

  • 你为什么使用梯度提升机GBM)来解决这个问题?

  • 你能解释一下 GBM 的基本原理吗?你之前使用过哪些 GBM 的实现?能否介绍一下它们的特点?

  • 什么是 F1 分数?

  • F1 分数与准确率得分有什么不同?在哪些情况下你更倾向于使用准确率?什么时候 F1 更适用?

  • 为什么我们需要一个单独的测试集?

请记住,技术评估不是面试中唯一需要考察的内容。向候选人介绍你的工作流程以及团队的工作内容。试着弄清楚你们的工作内容是否能足够吸引他们。那些高度积极、能顺利融入你们工作流程的候选人,通常是最好的选择,即使他们的技术能力不如其他候选人。

最后,我会给出一个简单的面试问题创建规则:提出与该职位日常工作相关的活动问题。问题只有在候选人需要每天独立解决此类问题时,才应高度抽象、理论性或复杂(如果是这样,请提供解释)。让面试更具现实性和相关性。提出你真正想要的,而不是更多也不是更少。

面试不同数据科学职位的技巧

面试应该是每个公司高度个性化的过程,所以提供面试模板或问题集会违背本章节的目的。然而,关于数据科学项目中每个角色相关的能力和日常问题的一般清单,可以作为你创建个性化、有目的面试流程的良好起点。

一般指导

不管你面试的是哪个职位,你都应该检查候选人是否具备以下能力:

  • 信息搜索 或 Google 技能:这听起来可能有点好笑,但信息搜索能力对任何技术专家来说都是一种极其宝贵的技能。你永远不知道在项目中会遇到什么算法、框架或错误。能够快速找到现有的解决方案并重用全球数据科学社区的经验,可以为你节省大量时间。如果候选人很难回答一个技术问题,但能查找解决方案并理解它,考虑将这个答案标记为至少部分正确。

  • 沟通能力:在模拟真实工作流程时,要注意候选人的沟通能力。留意他如何理解任务定义、请求额外的澄清以及报告状态。在面试前,最好告诉候选人你也会测试这项技能,并提供一小部分指令。例如,你可以允许并鼓励在家庭作业中进行中间沟通。许多家庭作业是在一个与真实项目协作环境完全不同的孤立环境中完成的。鼓励沟通可以让你快速了解候选人的真实工作经验,使其成为测试任务的一部分。

  • 软件工程技能:除了项目经理外,每个数据科学项目角色都需要编程技能。候选人能够构建的更好的软件,集成到整个系统中所需的工作就越少。

  • 如果候选人不知道某些事情,也没关系。人们会紧张、忘记细节,或者缺乏相关经验。把面试看作一个双向的过程,你们是在一起解决问题。现实工作不像考试,对吧?而且,在大多数情况下,那些即使不知道解决方案,但能和团队快速一起解决问题的人,往往是非常有价值的。

  • 不要成为知识的诅咒的受害者。知识的诅咒是一种认知偏差,通常出现在某个拥有特定知识的人假设他人具备所有必要背景知识以便能理解他们,或者至少高估了这种背景知识。不要期望候选人能完全理解并轻松解决你们团队几天前解决的问题。你们团队日常解决的关于数据集的具体细节和问题的微妙之处,对候选人来说是无法掌握的。要有意识地避开知识的诅咒,并将问题简化,匹配候选人的背景。

面试数据科学家

在面试数据科学家时,注意以下品质可能有助于你做出更好的选择:

  • 你在寻找什么样的数据科学家?一位研究型数据科学家能够实现最先进的模型并推动该领域的边界,而一位机器学习工程师则更擅长快速应用现有的最佳实践,同时保持良好的软件设计。许多公司需要第二类数据科学家,但却在试图招聘第一类。不要犯这个错误,要诚实地了解作为公司你们的需求。

  • 询问模型构建的整体工作流程,特别是如何将模型交付到生产环境中。注意候选人选择的离线和在线测试策略,用来评估模型的效果。许多专家对算法的内部机制有很好的理解,但缺乏完整的端到端模型测试和交付方法。

  • 询问你正在处理的数据集中的常见问题。如果你的团队常常面临数据不平衡的问题,一定要确认候选人是否具备解决此类问题的直觉。

  • 如果你在特定的业务领域工作,别忘了询问候选人的领域专业知识。

面试数据工程师

在寻找数据工程师时,别忘了关注以下品质:

  • 从数据工程师将使用的具体技术开始。数据处理技术和数据库种类繁多,所以你应该清楚了解你在寻找什么样的技术栈,因为没有人能掌握所有的技术。一位大数据工程师将帮助你驾驭大数据技术的复杂生态并编写复杂的 Apache Spark 作业。具备丰富经验的后端开发工程师则能帮助你处理传统数据仓库中的数据集,并且轻松地将你的解决方案与其他系统集成。

  • 如果你公司中的数据工程工作与分布式数据处理系统相关(例如 Apache Spark),那么不要忘记在面试中涉及这一话题。分布式系统存在抽象泄漏问题:当代码中出现问题时,开发者应该对系统内部的工作原理有一个良好的直觉,以便解决问题。这并不意味着每个数据工程师都应该是分布式算法专家并了解所有关于法定人数的内容,但他们应该具备足够的知识,以便在设计分布式数据处理流程时做出合理的选择。

总结

在本章中,我们探讨了在开始面试过程之前设定目标的重要性。我们解释了为什么在没有明确目的的情况下提出复杂的理论性问题不仅对候选人有害,也会对面试官所在的公司造成伤害。我们分析了现代面试的缺陷,并获得了使面试具有目的性和意义的工具。我们还看到了一个好的职位描述和一个不好的职位描述之间的区别。此外,我们为从你和你的团队每天解决的实际任务中制定面试问题定义了一个框架。

在下一章中,我们将制定建立数据科学团队的指南。

第六章:构建你的数据科学团队

本章中,我们将了解构建成功团队的三个关键方面,并解释领导者在数据科学团队中的角色。我们将学习如何构建并维持一个能够提供端到端解决方案的平衡团队。接着,我们将制定一个计划,通过改善并增加一些有用的管理技能来扩展我们的技能库:以身作则的领导力、积极倾听、同理心与情商、信任与授权。我们还将考虑倡导成长型思维模式如何成为团队发展过程中的重要部分。

本章将涵盖以下主题:

  • 实现团队禅意

  • 领导力与人员管理

  • 促进成长型思维模式

实现团队禅意

一个平衡的团队能够高效、轻松地解决所有来临的任务。每个团队成员互相补充,利用各自的独特能力帮助他人找到解决方案。然而,平衡的团队并不会在一个技能高超的领导者组建精英小队时神奇地自然而然地形成。找到团队的“禅意”不是一时的成就;你需要付出努力才能找到它。看起来某些团队表现出色,而其他团队则令人失望。但关键是要意识到,团队表现并非恒定不变的。最优秀的团队也可能变得最糟,反之亦然。每个团队都应该努力改进。有些团队可能需要的工作较少,而另一些团队则更难改变,但没有团队是没有希望的。

那么,平衡的团队是什么样的呢?每个团队成员在软硬技能上都有独特之处。有些人是全能型的多面手,而其他人则在某一领域具有高度专业化的专长。此外,我们每个人在情感上也有很大的差异。在平衡的团队中,每个人都能够互补和增强对方的能力。每个团队成员都知道在何时参与能产生最佳的结果。平衡的团队是自组织的,它们能够高效地进行规划和行动,而无需团队领导的直接干预。领导者将团队凝聚在一起,使团队更加有序,但平衡团队的实际工作过程显得高度去中心化。领导者经常参与团队工作,并帮助大家达成共同目标。团队成员之间有着良好的关系,大家都希望不断提升自己,迈向新的高度。平衡团队的另一个特点是,它们没有单点故障。如果有人生病或决定离开,团队核心的运作也不会受到太大影响。

不平衡的团队初看可能难以区分。不平衡的团队可以正常运作,甚至是顶尖表现者,但它们虽然高效,却很脆弱。人们在不平衡的团队中难以长久待下去,因为那样很困难。不平衡的团队有多种形式,因此很难界定。以下是两个不平衡团队的例子:

  • 在第一种情况下,团队负责人是团队中最优秀的专家。他们做大部分重要工作,而其他团队成员则负责最简单的委派任务。团队负责人将任务分解成许多简单的子任务并分配给团队成员。除了他们自己,没有人能看到全貌。不愿意分享重要的工作部分,也不愿意让团队参与任务分解过程,这种做法造成了强烈的失衡。这个团队非常脆弱,没有团队负责人,团队将无法正常运作。团队中的员工很快就会感到倦怠,因为他们看不到自己工作的成果。大部分任务枯燥重复,因此他们会寻求其他团队、项目或公司的挑战。这是团队中专业失衡的一个例子。

  • 在第二种情况下,团队正在构建一个非常庞大的项目。开发工作已经持续了 3 年。团队负责人和几位从一开始就参与项目的数据科学家建立了深厚的关系和团队文化。然而,并非所有团队成员都在这 3 年里一直留在团队中,因此,团队负责人找了几位新专家,他们急切希望接手这个项目。然而,这些新成员发现自己很难融入团队。核心团队新团队的沟通是勉强的。由于文化差异,他们发现沟通非常困难。与熟悉的人互动比与新团队互动要容易得多。因此,文化失衡出现了。

一旦团队中出现了失衡现象,要想去解决非常困难。一旦失衡的根基扎下,每个具体情况都需要仔细审视,并制定计划将团队带回更平衡的状态。应对失衡的最佳方法是从一开始就避免它。

就像在招聘人员以建立平衡的团队时一样,你应该着眼于目标。没有目标,就没有行动的理由,没有平衡,也没有失衡。例如,你的目标可能是在短时间内利用数据科学交付问题解决方案。从这个目标出发,团队的主要特点将逐渐显现。为了成功地应用数据科学,你需要该领域的专家。为了实现短时间交付,你还需要良好的内部流程,确保每个人都能顺畅可靠地工作。团队需要随着时间的推移不断改进,并且需要成长和持续发展;这就是平衡的需求。

明确陈述你的目标,并确保所有团队成员理解这些目标,以便每个人都能对成功的定义达成一致。如果没有度量标准和损失函数,就无法训练机器学习算法。没有反馈,人类也会停止发展。当没有好坏之分时,我们会停滞不前,而目标帮助我们定义这些对比。

每个团队的另一个重要组成部分是其角色。角色定义了团队成员可以执行的一组活动。你可能认为你不需要角色,因为你的团队是敏捷和跨职能的,因此每个人都可以并且应该能够做所有的事情。这对小型团队在生存并擅长其工作时可能至关重要。但跨职能并不意味着没有明确的角色。事实上,跨职能和团队规模是团队的不同维度,后者通过每个团队成员执行的角色数量影响前者。

例如,我们的数据科学团队应该负责从业务需求定义到最终解决方案交付的所有工作。我们已经大致定义了项目交付过程,并将每个阶段分配给了一个角色:

  • 定义业务需求:业务分析师

  • 定义功能需求:系统分析师

  • 定义非功能需求:系统分析师

  • 发现并记录输入数据源,创建数据集市和报告:数据分析师

  • 探索性数据分析与建模:数据科学家

  • 围绕模型构建软件:软件工程师

  • 创建最终产品的文档:软件工程师和系统分析师

  • 交付与部署:DevOps 工程师和软件工程师

  • 管理和团队领导:团队领导

假设这个团队只有三名成员,包括团队领导。我们可以将多个角色合并为一个,以满足团队规模的限制,同时为每个团队成员制定目标。回想一下,为每个职位设定目标是一个良好招聘流程的基础,创建团队目标、定义角色并将其映射到职位上是这个过程的前提。

对于我们的例子,有很多选择,但最现实的情况是以下几种:

  • 定义业务、功能和非功能需求:分析师

  • 交付软件和模型:机器学习工程师

  • 项目管理、团队领导和最终及中期结果的接受:团队领导

创建与团队目标一致的个人目标可以通过以下一系列转化来完成:

团队目标 → 团队角色 → 职位 → 个人目标

团队的角色越多,团队规模越小,成员之间的边界就越模糊,找到合适的队友来填补这些角色就越难。定义角色可以帮助你更现实地看待所需的工作量和创建一个优秀团队所需的预算,因此千万不要省略这一步。如果你的团队较大,每个员工的职责被明确区分,或者如果你的团队较小,职责较少分离,将角色映射到职位上同样非常有帮助。

通过遵循这一过程,你可以创建一个反馈系统,不仅能够优化全球团队目标,还能优化个人目标,帮助每个人理解自己在大局中的角色。当设计深度神经网络时,你需要创建一个损失函数并确保梯度通过每一层。在建立团队时,你需要确保反馈通过团队的每个部分,从你自己开始。

了解角色、目标和规模的约束也将有助于你发展和壮大团队。随着时间的推移,团队会壮大,但如果你保持核心目标-角色-位置框架,随着团队的发展,添加新的责任和团队成员将变得非常简单,你将把位置分配给更少的角色。目标-位置-角色的维护和修订也是必要的,以保持团队的平衡。组织结构或团队主要目标的变化总是带来创造不平衡的风险,所以在引入变动时要小心,并提前规划。

团队平衡和反馈系统的概念是简单但强大的工具,能帮助你建立一个平衡的团队,并以正确的方式扩大团队规模。

领导力与人员管理

实现团队禅部分,我们得出结论:团队领导者不应处于团队的核心位置,因为这种情况会导致严重的组织不平衡。然而,团队领导者应该在任何地方又不在任何地方。团队领导者应促进团队的运作,帮助每个团队成员参与到过程中,并在问题成为真正的障碍之前,减轻任何可能威胁到团队运作的风险。一位优秀的团队领导者可以替代并提供对团队中所有或大部分角色的支持。他们应该对团队核心角色有深刻的了解,以便在尽可能多的团队活动中提供帮助。

团队领导者应确保信息能够在团队中毫不费力地传播,并确保所有的沟通都在必要时进行。如果我们用互联网作为类比,团队领导者应该为所有服务器提供一个快速且可靠的通信网络。

团队领导者的另一个重要任务是不断并平衡地扩展团队。所有团队成员应拥有足够的动力,面临挑战,并清楚了解自己如何根据个人目标成长。

最重要的是,团队领导者应该设定目标,并与团队一起实现这些目标。团队领导者应将每个人的努力统一到一个焦点上,并确保这个焦点是正确的。

那么,如何让每个人都专注于他们的努力呢?如果你问我领导力中最重要的一个方面是什么,我会说是以身作则。现代社会对于成功领导者的定义,在现实中往往难以实现。许多人认为所有的领导者都是高超的沟通者和谈判者,能够通过言语的力量说服任何人做任何事情。当然,沟通技巧很重要,但不是那种操控性技巧。熟练的操控者在某些情况下可能会占些优势,但每个行为都有后果——操控从长远来看总是具有破坏性的。

以身作则

最简单和最有效的领导建议很可能是在你童年时就有人给你讲过:如果你想和别人建立良好的关系,先迈出第一步。想让别人信任你吗?通过信任他人逐步建立信任。想让你的团队有动力吗?参与工作流程,给予每个人帮助;展示他们的进步。管理学文献称这一原则为以身作则。言出必行,每个人都会跟随你的榜样。

这种领导方式对于团队建设非常有效:

  • 它不需要你学习和应用复杂的理论方法

  • 它建立了团队中的关系和信任

  • 它确保团队领导者参与到团队中每个角色的工作流程中

  • 它帮助每个人,包括你自己,在职业上成长

以身作则的领导方式唯一的缺点是它可能很困难。这要求你在情感和智力上都深度参与到你的团队中——这可能会让人感到疲惫不堪。避免疲劳是非常重要的,因为你的团队会立刻察觉到这一点。如果你精疲力竭,那么你的团队也会如此。幸运的是,有一种简单的方法可以避免领导者的倦怠。在你的工作日中确保有时间让自己从团队领导的活动中得到休息。也许是一个可以帮助团队成员的小研究项目,或者是一个你可以独立处理的原型。

另一个警告是,以身作则的领导方式可能很难放手。许多有志成为团队领导的人往往承担了过多的工作。领导者通常是团队中最有经验的专业人士,分配工作可能在情感上很困难,尤其是当你知道自己可以完成这些工作时。没有任务分配,团队无法正常运作,因此这样的团队很容易瓦解。当团队领导者无法有效分配任务时,团队中的不平衡就会出现,且这种不平衡会不断加剧。

运用情境领导

幸运的是,在大多数情况下,关于任务委派的问题大多是情感上的。为了无所畏惧地委派任务,你应该建立信任。而要建立信任,你需要迈出第一步。如果你觉得自己很难委派任务,就强迫自己尝试一下。可能这看起来像是一次信任飞跃,但跳一跳,看看你的团队能做到什么。一开始,你可能会害怕,但我向你保证,他们会给你惊喜。委派的关键部分是任务描述步骤。如果你无法正确、简洁地描述需要完成的工作,委派将会失败。为了有效地委派任务,你可以运用情境领导。其核心概念非常简单:你必须衡量团队成员的能力和承诺水平。然后,你需要根据这些水平选择适合的领导风格。

以下图表展示了一个简单而实用的工具,用于选择任务委派的领导风格:

上述图表通过两个变量来衡量员工的准备情况:承诺和能力水平。承诺代表员工的动机水平。承诺高的人认为工作有趣,并愿意努力直到任务完成。而承诺低则意味着这个人对完成任务不感兴趣,觉得任务乏味或重复,或者快要感到精疲力尽。另一面是能力,表示员工独立完成任务的能力。低能力意味着该人在相关任务方面没有或缺乏经验。而高能力则意味着员工拥有完成任务所需的所有知识和经验。情境领导帮助你保持团队成员的动力水平稳定,同时确保他们获得所有必要的指导,从而使他们的能力在不影响任务质量的情况下得以提高。

以下示例展示了如何通过确定员工的能力和承诺水平,来应用情境领导技巧,从而委派任务:

  1. 想象一下,你有一个新团队成员,Jane。她经验不多,正在担任你团队中的初级职位。她的动力很高,渴望学习新事物。在这种情况下,承诺水平很高,能力水平很低,因此我们必须采取指导式领导风格。显然,她无法独立解决复杂的任务。最好是选择一些简单的任务,将任务拆分成尽可能多的子任务,详细描述每一个步骤,并检查每一步的正确性。来自这一类别的员工将占用你大量的时间,因此要注意自己的资源。一支由 10 个高承诺低能力的团队成员组成的团队,很容易消耗掉你所有的时间。

  2. 随着时间的推移,简已经掌握了一些技能,但最近她的动机开始下滑。现在是进行辅导的最佳时机。在这个阶段,你需要适当放宽控制,允许团队成员做出承诺。

  3. 简的能力水平进一步提升,相比团队中的其他成员,你可以明显看出她的技术能力已经处于中等到高水平之间。注意这个转变非常重要,因为简的动机可能再次受到影响。为了保持这一状态,你需要调整你的领导风格,变得更加支持,并减少对特定任务的关注。你还需要与她共享决策任务。此时简的表现可能会有所波动,因此要提供她所需要的支持,帮助她顺利过渡到最后阶段。

  4. 在这个阶段,简已经成为一名资深专家。她技能高超,能够做出良好的决策,并持续提供高质量的工作成果。这是可以委派任务的阶段。在这个阶段,你的主要目标是设定高层次的目标,监控进度,并参与高层决策。

以清晰的方式定义任务

情境领导模型很有用,但它并未告诉你如何描述任务,以便让团队成员与你的愿景保持一致。首先,你需要意识到你的任务描述不应对所有团队成员都相同。你的描述会根据成员的能力和动机水平有所不同。在指导阶段,任务描述可以类似于一个低层次、详细的待办事项 清单,而在委派阶段,任务描述可能仅由两句话组成。然而,无论处于哪个阶段,你的任务描述应该是清晰、有限时性且现实的。SMART 标准有助于创建这样的描述。

SMART 标准指出,任何任务都应该符合以下要求:

  • 具体:明确目标并针对具体领域

  • 可衡量:有一些进展指标

  • 可分配:指定一个或多个负责人来完成任务

  • 现实:设定在给定的约束条件和可用资源下能够实现的结果

  • 与时间相关:设定时间限制或截止日期

尝试记住这一点。SMART 标准是一个方便的清单,可以帮助你的团队更好地理解你。尽管如此,不管你的任务描述多么详细,都应该与负责人进行沟通。我们的语言往往很模糊,甚至我们自己的想法也常常不清晰。在编写任务描述后,去找同事确认:你是怎么理解这个的? 我们能否花 1-2 分钟讨论一下? 如果你使用敏捷方法,也可以在每次迭代规划会议上讨论每项任务。这些对话是任务分配的关键部分。即使是细微的理解差异,也可能导致意想不到且完全错误的结果。

花几分钟讨论手头的任务将帮助您确保以下事项:

  • 您对任务的理解及其目标是否正确和现实

  • 您的任务描述足够详细

  • 您和受让人在需要完成的事项上是同步的

  • 受让人了解结果应该是什么样子的

  • 截止日期是现实的

培养共鸣

像示范领导、情境领导和 SMART 标准这样的基本概念将帮助您作为团队领导者构建和衡量工作。然而,还有另一个关键组成部分,没有它,即使完美执行正式的领导职能,您的团队也可能会分崩离析。这个组成部分就是共情。拥有共情意味着理解自己的情绪,以及他人的情绪。我们的反应大多是不理性的,我们经常混淆自己的感受和情绪。例如,很容易把愤怒误认为恐惧;实际上我们只是害怕时可能会表现得愤怒。了解自己的情绪并学会识别他人的情绪将帮助您理解人们并看到他们行为背后的微妙和动机。共情帮助我们找到理解非理性行为背后逻辑的方法,以便我们可以适当地做出反应。面对侵略行为时,除非您能理解背后的动机,否则可能很容易用愤怒回应。如果能看到这些动机,最终愤怒行为可能看起来很愚蠢。共情是最终解决冲突的工具;它有助于建立团队的信任和一致性。它在谈判中也起着重要作用,我们稍后将谈论此事。

共情不是一种先天能力。当然,有些人天生比其他人更具共情力,但这并不意味着不能培养共情。这是一种技能,就像任何其他技能一样,如果您努力学习,它是可以掌握的。要增强您的共情力,从自己开始。一天中要注意自己的情绪。如果遇到复杂情况,思考自己的行动和情绪。尝试理解哪些响应是适当的,哪些不是,看看是什么引起了它们以及在那一刻您的感受。有时,您会发现自己的感受与行动之间存在不匹配。从中学习。随着时间的推移,您将越来越好地理解情绪。首先,学会了解自己,然后您将能够比以前更好地读懂他人的情绪。

帮助您建立共情并理解他人的另一个重要工具是积极倾听。我们每天都在倾听他人,但我们是否从他们的言语中提取了所有可用信息?实际上,我们留下了大部分信息。在倾听时,我们经常被自己的想法分散注意力。我们不注意说话者,急于开口。

你可能听过通过让他人说话可以获得更多的收获。想象一下自己处于一个冲突情境中。你心爱的队友连续三天未提前通知,下午三点才到办公室。当你问他们怎么了,他们会粗暴地要求你走开。你可能会立刻想要用同样激烈的方式回应。然而,在这种情况下,理解这种行为背后的原因要比直接反应更为有效。未知的因素可以澄清这些看似不合逻辑的行为,并以不同的角度展现你队友的处境。

单纯地盯着对方看并希望信息自然流入脑海是一种乐观的想法。如果对方不在谈话的状态下,这反而可能让情况变得更糟。为了避免这种情况,你应该主动倾听。主动倾听是一套技巧,能够帮助他人更开放地表达。

要主动倾听,请做以下几步:

  • 全神贯注地倾听讲话者:当别人长时间说话时,我们经常会沉浸在自己的思维中。讲话者会立刻注意到你在走神,这会对他们与您分享信息的愿望产生负面影响。

  • 展示你在专心倾听:通过嗯嗯的回应,表示是的,点头和微笑等方式给出反馈。对方不应感到自己在对着一堵水泥墙讲话。

  • 复述与镜像:这时你会重复对方最后两到三个词。当你复述时,你用不同的词语重复或总结对方的上一句话;例如,我听到你说你想要……这开始时可能有点尴尬,但相信我,镜像法有效。这是主动倾听中最重要的工具,能够促进讲话者和听者之间的信息流动。学会了复述和镜像之后,我注意到优秀的演讲者常常在不自觉的情况下使用这些技巧。你完全没有理由不使用这个工具。

  • 永远不要评判:公开地评判他人会激发他们的防御机制,打断信息的流动。

  • 表达情感以理解他人的感受:同理心是一项难以掌握的技能,但你通常可以走捷径:表达对方的感受。我觉得你很不高兴,是吗? 如果你猜对了,对方会确认,如果你错了,你也会得到线索。

主动倾听在纸面上很简单,但在现实世界中可能有点棘手。像任何技能一样,你可以通过练习使其达到完美。在日常对话中遵循这个简单的建议,你会注意到效果。

促进成长型心态

我们将要讨论的团队建设的最后一个关键要素是成长型心态。如果你不希望你的团队解散,团队的持续成长是必要的。没有成长,就没有动力,没有新目标,也没有进步。我们可以将团队成长提炼成两个方面:团队整体的全球性成长和每个个体团队成员的局部成长。

提升团队整体专业能力

全球增长发生在你的团队克服挑战、发展项目并获得新机会时。全球团队的增长伴随着公司扩展而发生。但相反的情况并不成立:如果你的公司业务增长,并不意味着你的团队会自动变得更好并看到新的机会。团队一起学习经验是公式中的关键部分。恰巧的是,当公司不陷入停滞时,你会有更多的学习机会。每当有好事发生时,你和你的团队应该从中学习。当不好的事情发生时,也要从中学习。当发生重大事件时,确保信息通过团队传播并回到你那里。

一个很好的学习工具是进行回顾和内部聚会。回顾是项目团队会议,在会议中团队中的每个人回答三个简单的问题:

  • 我们做对了什么?

  • 我们做错了什么?

  • 我们应该做些什么来改进?

回顾允许你和你的团队成员获得反馈并加以改进。它们也是一种有效的项目管理工具,可以提升团队的产出。在更大的范围内,团队中的每个人都应该有机会与他人分享经验,并不仅仅从他们的经理那里获取反馈,而是从团队中的其他人那里也能获得有用的反馈。

个人成长中的持续学习

虽然通过从日常经验中学习来实现全球团队增长是可以通过一个过程来完成的,但个人成长并不容易。我经常问自己一个重要问题:如何激励人们去学习? 仅仅依靠日常工作经验,在数据科学领域成长是极其困难的,这对于其他技术领域也是一样的。为了个人成长,以及作为团队的一部分,你的同事们必须学习。对于一些人来说,获取新知识是困难的,尤其是那些在毕业后就停止了主动学习的人。学习是一种习惯,每个人都可以培养获取新知识的渴望。成长心态的关键理念是,我们毕业后不应该停止扩展自己的知识。知识是无限的,如今,你想学习的任何东西都触手可及;你只需要付出一些努力。终身持续学习而不间断的能力是一种真正的财富,能够实现无限的自我发展。如果你仔细想想,几乎任何目标都能通过足够的知识和坚持不懈实现。

个人或本地增长的关键是持续学习。如果你想激励团队成员学习和成长,你必须为他们提供以下内容:

  • 持续学习的概念是一个工具,它将帮助你的队友把学习变成一种习惯。

  • 并不是每个人都有时间来学习,即使有,也不是每个人都愿意立刻用这些时间来学习。工作中的学习和研究活动可能是养成习惯的好方式。

  • 个人学习计划将帮助每个人结构化和跟踪他们的目标。

  • 项目、学习和绩效评审过程中的其他目标将帮助你在团队中进行反馈流动。

现在我们将逐一探讨每个要点,从持续学习开始。其背后的主要理念是,无论你是一天内读完一本书,还是浏览一条有价值的信息推文,所有学习都算数。你应该目标是每天学到一些新东西——即使只是少量。最终,你不仅会更接近学习某些东西的目标,还会培养出一系列的习惯,使你在不知不觉中不断获取更多的知识。过一段时间后,持续学习将成为你生活的一部分,培养你对新有用信息的自然渴望,就像一个优化你空闲时间的调度程序,能在后台为你挤出通勤和排长队时的空闲分钟,帮助你朝着真正对你有意义的目标前进。

持续学习的技巧是通过小批量学习来达成学习目标。如果你有心情,你可能会继续做更多的工作。如果没有,你依然学到了一些新东西并继续前进。

一开始,这可能是达成单一目标的一种方式。然后,在实现第一个成就后,你会意识到这种思维方式可以让你学到更多:将其应用到新的专业领域、技能或兴趣话题。几个月后,它将成为你生活的一部分,帮助你每天都在进步。

提供更多的学习机会

养成习惯并不是一个简单的过程。要真正坚持下去,一个习惯应该重复很多次。你应该尽可能多地为你的团队提供学习机会。如果你希望你的团队能自我成长并持续发展,请确保你具备以下条件:

  • 学习计划模板

  • 研究和教育的计划时间

  • 付费课程和书籍的报酬选项

确保学习计划模板易于访问;将其放在公司 Wiki 或其他在线资源中。学习计划模板应包含你和你的团队认为对获取新技能有用的所有技能、书籍和在线课程。此页面应经常更新,链接到团队找到的新材料。将所有材料按类别分类。

特别地,针对数据科学的学习计划模板,你可以考虑以下类别:

  • 数学:

    • 数学分析与优化

    • 线性代数

    • 数理统计

  • 数据科学:

    • 机器学习

    • 深度学习

  • 数据工程:

    • 关系数据库

    • 数据仓库

    • 大数据

    • 商业智能

  • 软件工程:

    • 软件架构与模式

    • 代码质量

所有这些主题都应该包含书籍、在线课程以及博客文章的链接,并附上评论,说明为什么这些资料好以及它们最有用的部分是什么。如果能将每个主题进一步分为不同的等级就更好,比如初学者、中级和高级。这样,你和你的团队成员就能大致跟踪他们处于哪个能力水平。这个学习计划模板可以用于绩效评估,帮助制定和调整个人学习计划。我们将在本章稍后详细讨论这个话题。

在创建学习计划模板后,你可以与团队中的每个人交流,了解他们的职业目标。询问他们希望在哪些领域成长,并了解他们个人感兴趣的内容。请他们查看你的学习计划模板,并在每个主题中写下他们的大致能力水平,如果他们无法独立完成此任务,你可以帮助他们。有了这些信息,你将了解每个团队成员目前的状况以及他们的目标。接着,你可以为他们制定个人学习计划。我发现简单的任务跟踪系统,如 Trello,是跟踪学习目标的好工具——为你的队员创建共享板块,并在会议中创建卡片。和任何任务一样,学习计划如果能根据 SMART 标准来定义会更好。特别是,要确保它是现实的(每年读 100 本书对某些人来说可能是现实的目标,但对其他人却不一定)并且具有时间限制。每个学习计划应该有一个截止日期。在这个截止日期,你和你的队友应该再次会面,并调整学习计划:决定下一个目标,创建新的卡片,并删除过时的目标。在第二次会议中,你可能会发现许多学习计划未完成。这意味着你需要调整下一阶段的学习材料数量。最重要的是,进步永远不能停止,而不是已经完成了多少学习卡片。

学习计划没有为研究和教育规划时间是没有价值的。规划的时间可以是个人的,但你不应该指望你的团队仅仅在空闲时间自我教育。也要给他们在工作时间学习的机会。项目之间或者等待他人完成你依赖的工作部分时,通常会有空闲时间。在少数情况下,你的队员可能会有几天的空闲时间,等待新的任务。请明智地利用这段时间。你应该和你的团队沟通,如果他们没有分配到任务,在向你汇报后,他们应该按照个人计划进行学习。在某些情况下,公司政策可能反对在工作场所学习。你应该尝试沟通,让团队理解学习是一项长期投资,能够让他们更好地发挥。

形成学习习惯的另一个重要组成部分是为付费课程和书籍提供补偿选项。学习材料和在线课程可能会很昂贵。你的队友可能有其他的收入计划,而不是花钱买那些能让他们在工作中变得更好的书籍。如果有人理解投资教育将带来更大的回报,那很好,但并不是每个人一开始都会明白这一点。人们需要亲身体验这个过程。他们需要看到学习能够帮助他们提升,不仅是在收入上,也是在技能上。为成功完成的课程或书籍提供公司补偿计划并不昂贵,这将为你的团队启动学习习惯。

通过绩效评审帮助员工成长

最后但同样重要的一个组成部分是绩效评审。绩效评审的唯一目的是共享双向反馈,并清晰地了解个人进展。你可以尝试跟踪绩效的方式有无数种。许多公司使用某种关键绩效指标KPI)系统。KPI 是一个单一的数字,应该能够充分衡量你的成功。销售部门常见的 KPI 是销售总额(以$为单位)。这看起来最初是一个好的 KPI。销售部门的目标就是卖东西,对吧?把部门的成功与这个数字挂钩就像是在告诉大家:你们只需要想着卖更多东西,其他的都不重要。但这是一个非常短期的目标。销售部门的现实要比单一数字复杂得多。如果我们转到软件开发或数据科学部门,KPI 变得更加繁琐和复杂。你如何衡量一个程序员或数据科学家的表现?也许我们可以用实验的数量,或者每天编写的代码行数?这些标准与真正的成功完全无关。

说实话,我还没有看到过成功实施个人 KPI 的例子。KPI 最适用于商业流程,而个人 KPI 非常单一且不现实。如果你把一个人的成功与一个数字挂钩,他们要么会与系统对抗,要么会利用系统。一个更好的但更耗时的绩效追踪和目标设定方法是通过绩效评审。绩效评审通常每年进行一次或两次。

这个过程包括几个步骤:

  1. 让你的队友写下自上次绩效评审以来所做的所有事情,比如完成的项目、工作中的主要成就、开源贡献、书籍等。假设队友的名字是 Matt。

  2. 将这个描述发送给与 Matt 一起工作的同事。你应该尽可能地包括更多的人:项目经理、产品负责人和团队成员。让他们回答以下问题:

    • 你喜欢和 Matt 一起工作的哪些方面?

    • 有什么可以改进的地方?有什么部分你不喜欢?

  3. 如果你曾与马特作为经理共同参与一些项目,请自己准备好回答那些问题。

  4. 匿名化所有的评审并准备一份单一的绩效评审报告。

报告完成后,你应该与马特分享并安排一次会议。最好在会议之前分享报告,这样马特可以有时间思考反馈并得出结论。在会议中,讨论每个要点,并确保你们对于反馈意见有相同的理解。确定需要改进的最重要部分。如果马特在之前的绩效评审中达到了你设定的新高度,你应该考虑给他升职或奖金。无论是正面反馈还是负面反馈,都需要给予同等关注。努力让绩效评审脱颖而出。它们应该是令人难忘的。我们应该尽力制作漂亮的评审模板,注重排版,并适当加入一些幽默的表情包。我们还应将所有评审打印在高质量的纸张上,这样任何人都可以随时取阅。绩效评审应当创造积极的记忆,尤其是当反馈偏向负面时。你应该为团队提供改进的动力,并且不要忘记为自己收集评审意见。作为经理,你可能会犯很多错误,甚至不知道。获取团队的反馈对你来说与对他们一样重要。

如果你希望促进团队中的成长心态,带头示范是非常重要的。如果你希望任何人能够继承持续学习的原则、学习计划和教育目标,就亲自去做。展示这一切是有效的。通过这样做,你将一举两得:不仅极大地提升自己,还能向团队展示你所说的理念是如何切实有效的。

现在,让我们通过一个案例研究来看看如何应用本章中提供的建议。

案例研究——创建一个数据科学部门

一家大型制造公司决定开设一个新的数据科学部门。他们聘请了有经验的团队领导者罗伯特,并要求他建立这个新部门。

罗伯特做的第一件事是研究他的部门应该处理的场景。他发现公司内部对数据科学的理解仍然模糊,虽然有些经理希望部门能够构建机器学习模型并寻找新的数据科学应用场景,其他人则希望他构建数据仪表板和报告。为了创建一个平衡的团队,罗伯特首先记录了两个团队目标,并确认他的观点正确地总结了公司管理层对新团队的期望:

  • 数据管理: 根据管理层的要求,从公司数据仓库创建数据集市、报告和仪表板

  • 数据科学: 寻找高级分析应用场景,实施原型,并为项目想法辩护

接下来,Robert 考虑了团队规模的限制,并询问了每个月各个目标的大致请求量。对于数据管理部分,管理层已经积压了大量任务,需要尽快完成。至于数据科学部分,管理层没有任何预先存在的请求,但他们希望团队在接下来的三个月内寻找并建议新的数据科学用例。管理层注意到,他们已经准备好通过创建一个最多四个专家的团队来投资数据科学目标。

根据这些信息,Robert 得出了以下团队角色:

  • 数据团队负责人:监督两个数据团队并在更高层次上协调项目。预计在团队成立的第一年,该角色的工作量不会很大。

  • 数据管理团队

    • 团队领导/项目经理:目标定义明确要求有人管理即将到来的请求并规划工作。

    • 系统分析师:记录来自利益相关者的可视化和报告需求。

    • 数据分析师:根据系统分析师定义的需求实现数据报告和仪表盘。

  • 数据科学团队

    • 团队领导/项目经理:应能够在商业环境中管理研发流程。

    • 业务分析师:面试公司管理层并寻找潜在的数据科学用例。

    • 系统分析师:搜索数据并为业务分析师提供的用例提供需求。

    • 数据科学家:根据业务分析师和系统分析师提供的任务定义实现原型。

    • 后端软件工程师:将原型与外部系统进行集成,并根据需求实现软件。

    • 用户界面软件工程师:实现交互式 UI 和原型演示的可视化。

接下来,Robert 考虑了团队规模的限制,并根据前述角色创建了以下职位:

  • 数据团队负责人

    • 需要员工人数:1。该职位将由 Robert 担任。
  • 数据管理团队

    • 团队领导:需要员工人数:1。Robert 之前没有领导数据分析团队的经验,因此他决定聘请一位有经验的经理,在他的监督下工作。

    • 系统分析师:需要员工人数:1。

    • 数据分析师:需要员工人数:2。

  • 数据科学团队

    • 团队领导:需要员工人数:1。第一年该职位将由 Robert 担任,因为项目量不会大到影响数据团队领导的角色。作为团队中最资深的专家,Robert 仔细思考了如何运用情境领导理论来分配任务,以便激励数据科学家,并为他们提供成长的空间,承担更多复杂的任务。

    • 业务分析师:需要员工人数:1。

    • 系统分析师:所需员工数:0。罗伯特决定不再将系统分析与业务分析分开,因为系统分析可以由整个团队在研发阶段跨职能地进行。

    • 数据科学家与后端软件工程师:所需员工数:2。罗伯特决定将数据科学家和后端软件工程师合并为一个职位,因为原型项目的软件工程要求足够简单,数据科学家就能处理。他决定招聘两位专家,这样他就能同时处理多个想法。

接下来,罗伯特为每个职位定义了工作流程,以便创建准确的职位描述和面试场景,如在第五章《进行数据科学面试》中所描述的那样。为了促进成长型思维,他根据自己的经验为每个团队角色定义了学习计划模板。他专注于角色而不是职位,因为一些合并的职位可能会随着团队的增长而拆分,而基于角色的成长轨迹将使这些拆分自然发生。罗伯特还创建了一份快速团队领导指南,其中阐述了基于情境领导和 SMART 标准的任务分配标准,并为每个团队设立了绩效评审日程。

总结

在本章中,我们探讨了构建与维持团队这一复杂话题。首先,我们深入探讨了团队平衡的概念,并分析了为什么它对团队长期生存至关重要。接着,我们了解了几种领导风格,包括情境领导模型和以身作则的领导方式。然后,我们看到了如何利用 SMART 标准创建良好的任务描述。我们还提到同理心和积极倾听是领导者最重要的软技能。我们还探讨了持续学习和成长型思维的概念。最后,我们看到了绩效评审流程如何帮助团队发展学习习惯。

本章结束了本书的构建与维持团队部分;恭喜你完成了这一部分!接下来的部分将讨论数据科学项目管理的话题。

第三部分:管理各种数据科学项目

一旦你和你的团队开始构建项目,你可能会意识到它需要有效的管理策略。你能否使用传统的软件开发方法来进行数据科学项目?需要注意哪些陷阱?应该采用什么样的流程来管理开发迭代?如何在研究与实现之间保持平衡?面对极度不确定的情况时,应该如何处理?

本节包含以下章节:

  • 第七章,管理创新

  • 第八章,管理数据科学项目

  • 第九章,数据科学项目的常见陷阱

  • 第十章,创建产品与提升可重用性

第七章:管理创新

在本书的团队建设与维持章节中,我们探讨了如何打造一个能够交付数据科学解决方案的平衡团队。现在,我们将讨论如何找到具有真正价值的项目和问题。在本章中,我们将更大范围地讨论数据科学管理。我们从团队领导转向数据科学项目管理的领域。我们将制定具体的策略和方法,以便能够找到、管理和交付对业务有价值的项目。

对于大多数公司来说,数据科学和机器学习属于创新领域。与软件开发不同,这些学科对客户和业务利益相关者来说是未知领域(terra incognita)。如果你像处理其他项目一样处理数据科学项目,你将面临许多意想不到的问题。数据科学的领域需要采取不同的处理方式。当我们进入创新领域时,最佳和良好的定义发生了变化。

在本章中,我们将探索创新管理,并回答以下问题:

  • 理解创新

  • 为什么大企业会如此频繁地失败?

  • 探索创新管理

  • 平衡销售、营销、团队领导和技术

  • 在大公司中管理创新

  • 在初创公司中管理创新

  • 寻找项目创意

理解创新

在我们讨论创新失败之前,我们需要了解什么是创新。字典中对创新的定义是:创新是某种新事物或以不同方式引入的事物;是新事物或新方法的引入。每个创新都是暂时的。爱迪生的灯泡曾是创新的,汽车也是如此。成功的创新如暴风骤雨般侵入我们的日常生活,永远改变它们,随后变得平凡。失败的创新则逐渐消失,被遗忘。

如果我们看历史,技术的创造并不保证成功。汽车首次出现在 1886 年,但汽车真正改变我们生活是在 27 年后的 1913 年,当时福特汽车公司建立了第一个流水线。如果你将创新定义为发明家的成功,那么第一辆汽车的发明可能是一次巨大的突破。但从商业的角度来看,我们可能只有在创新创造了一个新市场,并带来了稳定的收入流时,才认为它是成功的。技术创新推动了领域的发展,而商业创新创造了某些新的、以前无法获得的价值。这些价值帮助了新市场的出现和新企业的崛起。

为什么大企业会如此频繁地失败?

大公司往往将创新视为金矿。许多企业家会想,你听说过这家新的人工智能初创公司吗?试想一下,我们在这个领域能取得什么成就。与其他公司相比,我们的资源是巨大的。然而,历史却告诉我们并非如此,因为新兴的创新技术通常是在小型初创公司内部诞生的,而不是在大型稳定的企业中。这与直觉相反。大公司有更多的资源、人力、时间和风险免疫力,而初创公司几乎没有。那为什么大公司会在创新上失败呢?克莱顿·克里斯滕森的《创新者的窘境》(www.amazon.com/Innovators-Dilemma-Revolutionary-Change-Business/dp/0062060244)和杰弗里·摩尔的《跨越鸿沟》(www.amazon.com/Crossing-Chasm-3rd-Disruptive-Mainstream/dp/0062292986)讲述了一个有说服力且有数据支持的故事。创新在发展的初期几乎不会带来任何收入。在大公司中,创新产品往往会与公司现有的最佳产品进行竞争。从这个角度来看,创新似乎是初创公司的合法选择,而与大公司现有的收入渠道并不兼容。小公司为了生存而努力获取收入,而与大型企业在成熟市场中竞争几乎是不可能的。小型初创公司没有足够的资源来提供市场所需的竞争性产品。因此,初创公司生存的自然之道便是创新。

新技术通常是未经加工的原始技术,因此它们对于新市场来说似乎不具吸引力。克莱顿·克里斯滕森教授以硬盘驱动器HDDs)为例来说明这一点。在大型硬盘驱动器盛行的时代,所有人都将其作为行业标准。虽然小型硬盘在理论上很有趣,但在实践中却无法使用,因为当时硬件仅支持较大的硬盘驱动器型号。较大的硬盘驱动器还拥有更大的存储容量、速度和可靠性。随着个人计算机市场的兴起,小型硬盘瞬间变得更加吸引人。电力消耗和体积是 PC 用户关心的参数。新的收入渠道促进了小型硬盘的发展。经过一段时间,小型号硬盘在存储容量、速度和可靠性上超越了其大型型号。对老一代硬盘来说,已经为时过晚。看似稳定的大公司在五年前失去了市场,市场被新兴的、更先进的技术所取代。

在大公司启动创新项目很容易,但完成它们却很麻烦。创新根据公司的短期到中期目标来看,往往显得毫无意义,因为它们既不带来收入,又需要大量投资。然而,创新进入大公司并非不可能。我们将在本章稍后探讨如何将创意发展成小型和大型企业的商业模式。

市场的游戏

数据科学仍然是一个充满巨大潜力的年轻领域。许多专家认为,即使我们停止新的研究,如果将过去 10 年中出现的新技术整合进来,我们依然领先于当前的竞争对手二到三十年。然而,研究项目与广泛应用的技术之间存在很大差距。就像硬盘驱动器(HDD)一样,一个研究项目需要不断扩展其功能,以超越当前的竞争者。

数据科学利用机器学习、深度学习和统计学的研究成果,提供解决现实问题的软件产品。为了使软件具有广泛的适用性并能被使用,软件需要大量的时间投入。软件工程师、数据科学家以及其他技术专家的时间是有成本的。要从你的软件中赚取收入,你需要解决人们的问题。你的产品需要为人们带来一些有价值的东西。当这种价值足够大,能够维持持续的需求时,你就创造了一个新市场。这个市场由供求法则主宰:人们和公司将用钱交换你的产品和服务。

在初期,大型组织会创建自己的市场或参与现有市场。市场就像我们一样会衰老和消亡,给新市场提供了生存空间。如果处于衰退市场的公司未能转向新兴市场,它们将停止存在。

创造新市场

创造新市场是复杂且具有风险的。如果你测试一个想法花费太长时间并消耗太多资源,你将会失败。风险很大,所以测试想法应该是快速且简单的。这种测试让你能将错误转化为知识,并在一次又一次的迭代中改进你的产品。快速失败并通过测试想法不断学习是精益创业方法的关键。公式很简单:尽可能多地探讨想法,迭代地调整你的产品以适应市场,并增加对你服务的需求。这个过程的关键特点是速度。

大公司很少能快速运作。长周期的运营和繁重的组织流程随着公司规模的增大而自然出现。没有这些关键工具,公司可能无法正常运作。然而,创新不容忍长周期。实验的失败成本随着时间的延长而增加,这使得创新对大公司来说变得非常昂贵。

对于组织来说,数据科学仍然是一种创新,大多数市场细分尚未开发或发现。虽然创新很困难,但并非不可能。在本章的后续部分,我们将探讨如何通过在大公司和小公司中运用创新管理来掌控新技术。

探索创新管理

创新本质上非常混乱。创新者提倡实验,但他们无法预测最终结果,并且很难定义时间限制。这些创新的特性使其在商业环境中难以实施,因为在商业环境中,明确的目标、严格的截止日期和有限的预算是常态。创新管理提供了一套技术,旨在为混乱的创新领域带来秩序。管理 这个词通常与直接控制相关,但对于创新来说并非如此。自由对于每一个创新都至关重要。你无法通过微观管理取得任何积极的结果。创新管理是为创新提供支持,并将其整合到现有的业务中,以便它们能带来有益的结果。

要理解创新管理背后的主要思想,我们应该了解不同类型的创新,即持续创新和颠覆性创新:

  • 颠覆性创新 是大多数人所理解的创新。这种创新带来了市场的剧变。它引入了某种新的、技术上足够成熟的东西,能够创造一个新市场。iPod、iPhone、IBM PC 和电灯泡都属于颠覆性创新。

  • 持续创新 感觉更为 有机渐进。你最喜欢的操作系统的新版本、社交网络的界面变化和 iPhone 的升级都属于持续创新。持续创新的目标是通过引入新功能来跟上竞争对手的步伐,防止你的客户转向竞争公司提供的更具吸引力的产品。

每一次持续创新都会稍微拉大竞争对手之间的差距,而颠覆性创新则改变了我们的生活和工作方式,从而创造了新市场并使旧市场变得过时。从外行观察者的角度来看,颠覆性创新可能会突然出现,但实际上,它们并非一时的灵感。《创新者的困境》中包含了许多颠覆性创新的例子,这些创新是在小市场中成长起来的,其中创新产品的特点对特定的使用场景具有更大的吸引力。稳定的收入来源使创新技术能够成长到其潜力,而提供老一代产品的公司并未意识到市场上已有的直接竞争。当新产品颠覆市场时,已为时过晚。

数据科学本身并不是颠覆性的创新,也不能单独支撑创新。它是一套工具,我们可以用它来创造这两种创新。特别是,自动驾驶汽车是颠覆性技术的良好候选者,而更精准的推荐引擎属于创新管理中的持续创新一方。

从风险的角度来看,创造颠覆性创新是一项危险且长期的投资,而创造持续性创新应该是任何成功企业中一个稳定且经过充分研究的过程。

我们可以通过以下生命周期来查看这两种类型:

  1. 搜索:在这一阶段,公司会寻找一个可以进行实验的创意。

  2. 构建:在这里,公司构建原型,进行实验,并衡量结果。

  3. 规模化:在这个阶段,构建阶段为我们提供了一个有前景的方向,因此公司开始扩大规模。原型被转化为市场准备好的产品,并开始创造收入。

  4. 扩展:每种创新都会饱和其市场。在这个阶段,公司将产品扩展到新市场,以保持增长率不变。

  5. 持续:在这一阶段,创新变成了一个稳定的业务。一些公司可以在持续阶段存在几十年。然而,这也伴随着风险。你在市场中的当前位置并不是一个固定的不变的收入来源。没有长期投资,它可以迅速饱和。每一分钟的停滞都会为你的竞争对手创造新的机会,使他们能够进行颠覆性创新,从而将你挤出市场。持续阶段是一个信号,表明公司需要恢复搜索阶段。

每一个颠覆性创新的另一个重要方面是鸿沟。在《跨越鸿沟》中,杰弗里·摩尔展示了著名的市场采纳曲线:

新技术可以迅速在早期市场找到一个看似稳定的收入来源,早期市场由愿意为风险性、未经验证、实验性的但有前景的解决方案支付费用的公司组成。许多组织认为,从早期市场到主流市场的过渡会是顺利的;早期市场会产生足够的收入,以便能够创造出对主流市场有价值的新功能。然而,实际上情况并非如此。早期市场和主流市场之间的差距远大于看上去的。随着早期市场的饱和,公司进入了鸿沟。其产品尚未足够成熟和完善,无法满足主流市场的需求,主流市场的客户习惯了功能丰富且稳定的产品。因此,公司被迫忍受收入来源的下降,而其产品需要大量投资,才能创造出主流市场所要求的功能。

为了找到突破困境的路径,公司必须将精力集中在一个非常具体的应用领域,在这个领域中,产品的最佳特性比其当前的缺陷更为重要。目标是找到一个微小但可靠的细分市场,并专注于完善它。这将创造一个小市场,通过成功案例、功能、客户推荐和新的收入来源,帮助你获得成长的动力。在一个小市场中的持续成功将为你提供必要的资源和时间,从而能够扩展到更成熟的市场。

在接下来的章节中,我们将看看一个虚构公司 MedVision 的案例研究。

案例研究 – 跟踪 MedVision 的创新周期

作为一个例子,我们来看一下 MedVision——一个虚构的人工智能初创公司,旨在将计算机视觉技术应用于医疗设备和医院。在他们的探索阶段,进行了一项关于深度学习在医学中应用的研究。

MedVision 的专家们还进行了市场调研,并确定了四个潜在的工作方向,如下所示:

  • 使用 X 光图像检测肺癌。

  • 通过分析可穿戴设备的数据,检测心脏病发作和其他危险的健康状况。

  • 利用患者的病史创建诊断助手,帮助治疗师在考虑患者数据的情况下识别和分类疾病。

  • 分析瞳孔运动、脑电图(EEG)扫描和脑部扫描,识别和分类心理疾病。

从商业角度来看,所有这些想法看起来都很有前景,并且有一个明确的市场基础,也就是希望提供/获得更准确且价格更低的医疗诊断的医生和患者。

在构建阶段,MedVision 团队创建了多个原型并展示给潜在买家。他们还加深了对每个想法领域的了解并进行了研究。构建阶段揭示了一些在探索阶段未能发现的意外问题,如下所示:

  • 癌症检测面临数据质量差的问题。许多数据集包含带有偏见的图像,需要手动清理。在原型阶段,MedVision 的模型在保留测试集上获得了 0.97 的 F1 分类分数,但在新获取的数据上却未通过测试。MedVision 用于模型训练的数据集存在偏见:用于制作 X 光图像的扫描仪在扫描图像上留下了标记。模型学会了通过最简单的策略来分类癌症:识别这些标记。这导致了模型的偏差。另一个偏差来源隐藏在时间戳中,所有的 X 光图像都有时间戳。结果发现,癌症患者因为医院的排班政策,更有可能在星期二和星期五进行扫描。MedVision 团队现在已经准备好在为实际客户解决癌症分类问题时处理这些问题。团队决定,偏见问题是可以解决的,并且不会成为这个想法的障碍。

  • 可穿戴设备的数据已被证明是心脏病发作和跌倒伤害的良好预测指标。然而,数据可获取性存在巨大问题。在 MedVision 的网络中,只有 1/10 的医院报告称他们拥有可穿戴设备的数据,而且仅有两家医院计划在未来 5 年内向患者提供可穿戴设备。由于可穿戴设备在医学中的普及程度较低,MedVision 决定将这一想法从计划中剔除。

  • 使用患者的病史来诊断疾病被证明是一个非常具有挑战性的任务,因为数据收集存在困难。对三家医院数据的研究显示,30%的患者病史仍然是纸质格式。表格标准化,但大多数是手工填写的。为了验证他们的想法,MedVision 团队需要开发可靠的手写识别技术,然后对大量文本信息进行结构化和错误校正。这个过程需要大量的时间投入,并且需要两名手写识别和自然语言处理NLP)领域的专家。在数据研究过程中,关于一家大型公司在这一方向上失败的消息传出。MedVision 决定不再在这一方向上进行进一步投资。他们一致认为,继续进行原型开发阶段的风险太高。

  • 精神疾病分类吸引了多位 MedVision 深度学习专家的关注。这个想法新颖、未被探索且充满潜力。进一步的研究表明,目前精神病学的诊断方法主要依赖患者的描述和外部条件,而非医疗设备的测量数据。尽管研究人员在这一领域已经取得了显著成就,但精神病学诊断手册并未采纳这些研究成果。事实证明,解决这一任务,MedVision 还需要在精神病学和数据科学这两个学科领域取得先进的进展。这个想法更像是一个研究项目,而非产品实施。他们将需要吸引长期投资、精神病学和心理治疗领域的专业人士和专家。这个想法具有变革性:MedVision 需要从一家商业公司转型为研究机构,才能实现这一目标。所有团队成员一致认为,在不改变公司目标和投资者的情况下,他们无法完成这个项目。他们记录下了自己的选择,并决定在公司规模足够提供长期研究项目资源时,再次考虑这个想法。

MedVision 的团队决定继续推进他们的癌症检测原型。他们已确定两家对他们的解决方案感兴趣的医院:奥克兰医院和癌症预防中心。他们还找到了一家可能提供额外资金的医学研究机构,前提是他们与真实患者的首次测试成功。

一年后,MedVision 的系统成功在奥克兰医院投入使用。第二个项目在中途被取消,因为癌症预防中心希望对已开发的产品拥有独占所有权,这大大限制了 MedVision 的扩展和销售能力。

癌症检测系统的首次工作部署使 MedVision 和奥克兰医院得以向主要新闻媒体发布他们的成功故事。这使得 MedVision 团队开始了扩张。他们扩展了销售部门,并开始吸引新的客户进行系统试用。大量新的功能请求开始涌向 MedVision 团队,因此他们聘请了一位产品经理来研究市场,并对新功能进行分类、优先排序和管理交付。几家竞争对手进入了市场,跟随 MedVision 的成功,因此团队转向提供持续性创新,以保持市场领先地位。

随着资金的增长,在成功运营几年后,MedVision 的团队为他们的客户群开发了新产品。他们开始通过寻找新想法来进行变革性的公司调整,希望能找到适合的基础,以便开始第二轮破坏性创新周期。

接下来,我们将探讨将创新整合到现有业务中的可能方式。

整合创新

创新需要实验。新的方法经常会失败,但失败并不意味着终点。失败只意味着你必须提炼经验,从错误中学习,并尽快再试。如果你在一家成熟公司中尝试这样做,他们的流程和最佳实践可能会让你看起来像个疯子,而且你的行为可能会显得具有破坏性,并与公司的价值观和目标相悖。这种情况发生的原因是大多数企业倾向于持续性创新。现有的价值观、目标和关键绩效指标(KPI)对破坏性创新的反应就像免疫系统对病毒的反应——采取防御行动。这就是为什么大多数研发R&D)部门在企业中生活得如此艰难的原因。它们追求的目标与所工作的公司的价值观不兼容。为了缓解破坏性创新在大公司中的整合,你可以尝试在公司内部引入一个独立的业务实体。

有多种方式可以实现这一点:

  • 收购:收购已经成功跨越鸿沟的公司。这种方式的主要挑战在于整合被收购的公司。技术和组织整合需要小心进行,以免对新收购的产品和团队产生不利影响。

  • 独立实体:创建一个分支公司,接受总部的融资。这种方法的主要挑战是高昂的成本、风险管理以及抵制完全控制的冲动。诚实地评估你公司的潜力,以便创建和组织一个以长期发展颠覆性技术为目标的新业务。

  • 独立部门:这是创建创新团队的最难方式。这里的主要挑战是为现有公司创造一套新的目标和价值观。

从创新的角度思考数据科学项目,在许多方面都是有帮助的。机器学习和深度学习可以创造持续性和颠覆性创新。创新管理将为你提供更广阔的视野,并让你的主要战略在市场中获得成功。那些没有将创新整合进来的组织将被竞争对手超越。归咎于技术不够成熟,或者专家不如竞争对手的明星专家,都是容易的事。在做这些的同时,很多公司忽略了考虑围绕新技术形成市场战略的有效性。数据科学解决方案需要一个稳定的组织基础和收入生成的行动计划。创新管理帮助我们兼顾这两个方面。

正如你所看到的,管理创新涉及处理大量的失败。失败是多维的,为了避免失败,你需要在不同领域的专长之间找到平衡。本章的下一部分将探讨三种主要的思维方式,这些思维方式将帮助你管理数据科学项目中的风险。

平衡销售、营销、团队领导和技术

在数据科学管理中要取得成功,你需要在不同的专业领域之间找到平衡。数据科学经理每天都在销售、营销和优化的任务之间切换。但他们不应该最关心数据科学吗?由于我们是集体完成工作的,因此沟通量较大。问问任何在商业环境中工作的技术专家,他们实际工作所花的时间有多少。平均来说,软件工程师会告诉你,他们每天有 2 到 3 小时是在编码。其余的 6 小时,他们参加会议、写或读文档、创建任务单、讨论技术设计。数据科学家花大量时间讨论数据定义、指标选择以及他们所构建模型的商业影响。

数据科学家可以投入的领域数量令人眼花缭乱:

  • 开发解决方案中的复杂部分

  • 代码评审

  • 工作规划、任务管理和任务定义

  • 技术栈与工具

  • 员工

  • 应用研发

  • 绩效评估

  • 指导

  • 支持成长型思维,并为员工制定自我发展计划

  • 为了更好的市场契合调整技术

  • 制作演示文稿

  • 练习演讲

  • 编写书面材料

  • 扩展你的网络并检查你的联系,寻找可能的 B2B 应用场景

  • 探索竞争对手的当前产品

  • 寻找技术的潜在转型方向

  • 寻找新的应用场景并优化当前的应用场景

我们可以通过将每个活动归类到四个常见领域中来简化这个列表:

  • 技术领导力:所有与数据科学、编程和开发过程组织相关的事项都属于这个话题:

    • 开发解决方案的复杂部分

    • 代码审查

    • 工作规划、任务管理和任务定义

    • 技术栈和工具的员工管理

    • 应用研发

  • 团队建设:这个话题包括与你团队相关的活动:

    • 绩效评估

    • 教练辅导

    • 支持成长型思维并为你的员工制定自我发展计划

  • 销售:任何有助于你销售更多产品或服务的事项都属于这个话题:

    • 制作演示文稿

    • 练习演讲

    • 创建书面材料

    • 扩展你的网络并检查你的联系,寻找可能的 B2B 应用场景

  • 市场营销:所有与市场和转型相关的事项都属于这个话题:

    • 探索竞争对手的当前产品

    • 寻找技术的潜在转型方向

    • 寻找新的应用场景并优化当前的应用场景

在成熟的团队中,每个管理领域将由专门的专家来处理。在数据科学已经产生影响的组织中,你会发现跨职能的产品团队,其中专家们会被分配一到两个角色。对于刚开始涉足数据科学的组织,或那些正在利用先进的数据分析和预测建模建立业务的组织情况则有所不同。在这些团队中,数据科学经理更可能负责大部分,甚至是所有关键管理领域。

在工作日中管理不同的情境,不仅对新兴的数据科学团队有用。改变环境可以打开新的视角,给你关于如何推进技术、团队和业务发展的思路。我们将简要涵盖四个管理领域,并将它们与数据科学的具体情况联系起来。

技术领导力,与团队建设一起,是任何数据科学经理的关键活动。你需要确保你的项目使用了合适的工具,并且已经设计好以实现客户的目标。另一方面,你还需要关注团队的动机和长期的改进。倡导成长型思维并建立一个平衡的团队,将成为构建更好技术的坚实基础。

你的团队需要不断有任务可以进行。即使公司有专门的销售部门,你也需要先将你的想法推销给他们。如果数据科学在公司中相对较新,销售人员会熟悉公司现有的产品,但他们并不懂得如何向客户销售数据科学解决方案。你要么需要学会自己做这件事,要么需要讲销售的语言来指导销售部门如何推销数据科学解决方案。另一种需要这些技能的情况是内部销售。例如,当数据科学部门正在优化内部业务流程时,这套技能就显得至关重要。这在银行和互联网公司中是常见的情形。在这种情况下,数据科学经理需要寻找创意,使其具有吸引力并且清晰易懂,明确利益相关者,并完成一次内部销售,以便为你的项目争取到预算。没有销售,即使是最优秀的团队和最具颠覆性的技术也会发现自己没有任何工作可做。从销售员的角度看待你的职责,会为你打开一个意想不到的机会大门,因此千万不要错过。

如果你工作的销售部分如预期那样运作,你将开始看到许多机会,每个机会都需要你团队投入大量的时间。有些机会是现实可行的,与你团队的技术和专业匹配,而另一些机会则不那么吸引人。现在是时候戴上你的市场营销“帽子”了,这样你可以在这片机会的海洋中找到方向。从市场、需求和产品的角度思考你的工作,将帮助你选择出最佳的工作方向。随着每一个项目的完成,你团队的技能和技术将越来越接近某一类机会,而远离其他机会。市场营销的核心在于最有前景的方式去寻找,并朝着你的技术与市场需求相匹配的方向发展,从而创造出新的价值。

从不同的角度看待你的工作既能启发思考,也能对你的职业生涯和公司带来益处。我们生活在一个多维的世界,因此,超越我们主要职责的范围进行思考是非常重要的。从现在开始,试着把团队管理、技术领导、销售和市场营销这四顶“帽子”放在你的桌面上。记住,要不时地更换这些“帽子”,这样你和你的团队就会拥有寻找、培养和交付创新所需的所有要素。

在大公司中管理创新

大多数公司已经意识到数据科学的变革力量。没有人愿意在竞争中落后,因此公司创建了内部的数据科学和研发部门。在这种环境下工作具有挑战性,因为你既被一些人视为创新的推动者,也被其他人视为打扰的麻烦。创新通常会导致公司现有业务流程的重大变革,许多人不愿意看到这些变革的实施。

将颠覆性创新引入现有业务是一个棘手的过程;为了增加成功的机会,确保你具备以下条件:

  • 组织权力:你需要直接或间接的组织权力来实施变更。

  • 迁移计划:你需要对现有的业务流程(集成前)和未来的业务流程(集成后)有一个完整的规划。你还需要一个迁移计划,指导你从现有流程到未来流程的过渡。

  • 成功标准和集成策略:对整个业务流程进行突然变更并快速整合创新是一种高风险的策略。你应该为你的项目设定可衡量的成功标准,并有一个风险管理策略,以便在最坏的情况下控制损失。

  • 开放的过程和清晰的解释:每个受迁移影响的人都需要清晰明了地了解正在发生什么,以及这将如何影响他们的工作流程。

  • 参与集成:你需要在描述现有流程和制定迁移计划时得到帮助。没有人比那些已经执行现有业务流程的人更适合这项工作。找出那些参与日常执行现有流程的人,并确保他们参与到第 3 和第 4 点中提到的流程中。

接下来,我们将探讨一个关于零售业务创新管理流程的案例研究。

案例研究 – 将数据科学引入零售业务

在这个案例研究中,我们将关注一位数据科学经理 Carl,他在一家虚构的零售公司工作。他和他的团队已经原型化了一种能够提高货架上商品可用性的解决方案。该解决方案将监控所有门店的商品,并通知店员,当货架上缺货时,店员可以及时补充商品。公司管理层已要求 Carl 将该原型发展成完整的解决方案,并将其整合到现有的货架可用性流程中。

在当前流程中,每家门店有两到五名商品可用性经理,他们使用智能手机上的应用程序手动监控店内每个货架。该应用显示每个货架上的最新商品位置,但经理需要手动检查商品是否在货架上。检查后,经理可以记录下所有缺货的商品,并前往门店仓库取货,将其放置在货架上。

首先,Carl 要求公司管理层将他介绍给负责所有门店当前商品上架可用性的负责人。结果发现,一位负责物流、配送和商品上架可用性的执行董事掌管了这一流程。Carl 准备了一份详细的演示文稿,描述了试点项目的结果。他告诉公司,他需要这位董事的帮助来制定系统的需求,以便将其集成到现有的业务流程中,因为这位董事具备相关的组织能力。当前的业务流程有详细的文档记录,每一步都分配给了具体的业务角色。为了制定迁移计划,他们采访了执行目标流程的专家。Carl 向专家展示了当前的原型,并记录下他们关于如何改进技术的意见,以便顺利地将其集成到工作流中。每个新功能都形成了即将实施项目的待办事项。随着新功能和想法的提出,业务流程方面也自然地出现了一些变化。有些变化存在冲突且定义不清,因此 Carl 将一名业务分析师分配到项目中,负责将迁移计划整理成一份连贯的文档。

之后,Carl 将结果呈报给了董事。新系统的集成显著改变了现有的流程。之前,监控商品上架可用性的门店经理们是通过人工走遍门店来监控商品的可用性,但现在,这项任务可以通过在每个货架附近安装便携式摄像头完全自动化。一名经理将通过移动应用接收任务通知,每个任务将包含关于商品存放位置、数量和货架位置的详细信息。该应用会将任务进行批量处理,并创建最优的路线穿过门店的储物区域。由于所有门店的可用性管理员都已经有智能手机,因此集成将变得简单:用户只需要更新手机上的应用,并熟悉新功能。

Carl 提出的集成策略的核心思想是首先在一个门店内测试该系统。如果该门店能够仅用一半的可用性管理人员应对当前的工作量,则测试视为成功。通过这种方式,项目会有可衡量的成功标准。如果第一次测试成功,系统将继续在更多门店进行测试。这个过程将重复进行,最终迁移到所有门店,使其成为目标版本的流程。

很明显,系统集成过程后,每个门店将需要更少的可用性经理。为了保持开放的流程和清晰的说明,主管设计了一个特别的培训项目,针对那些在系统上线后不再需要从事此项工作的人员。其他部门正在努力寻找新员工,因此重新分配劳动力是一个非常吸引人的选择。Carl 的团队还创建了一个深入的现场培训课程和应用内教程,描述了用户如何与新应用程序进行操作。

创新的生命周期比大型组织中的一般项目生命周期要快得多。由于快速的实验率和增加的失败风险,它在短期内的成本也更高。这使得在大型公司中处理创新变得更加棘手。现有的短期至中期的价值和目标会排斥创新,就像免疫系统排斥病毒一样。在成熟企业中,为研发和创新部门提供组织和财务支持是至关重要的。创新团队在以公司内部公司形式部署时表现最佳。尽管主业务可能在拥有众多层级部门和管理链条的组织结构中高效运作,但创新在组织结构层级很高且员工与高层经理之间只有一两步之遥时效果最佳。

在接下来的章节中,我们将探讨如何在初创公司中管理创新。

管理初创公司中的创新

如果你在初创公司工作,创新会比在大型、缓慢发展的公司中显得更加自然和易于实施。然而,初创公司与成熟公司之间存在显著差异。初创公司不能承担犯太多错误的风险。稳定的收入流使大型公司能够同时测试多个想法,而初创公司往往只能在一个方向上同时发展。

"鸿沟"的概念对初创公司非常重要。初创公司的主要目标是找到一个新的市场,在这个市场上它可以独立成长并提供不存在的价值。将你的创意和技术与市场需求对接需要大量可量化的实验。采用可衡量的方法是《精益创业》《跨越鸿沟》方法中提倡的重要内容。

精益创业方法建议你尽早在市场上测试每个创意和每个功能。进行实验并获取反馈对初创公司至关重要,因为你做出的每一个选择都在限制你未来的发展。你的产品越早收到市场反馈,你就越能在为时已晚之前改变其方向。一家拥有良好研发实践和大预算的公司可以在计算机视觉、自然语言处理(NLP)和强化学习领域进行长期的创意测试。他们甚至可以创建完整的分支机构,以便测试创意。另一方面,一家计算机视觉的初创公司将更难转型到 NLP,因为盈利预期较短。

初创公司需要保持精简、快速和敏捷才能生存。从市场营销的角度看待你的创意是小型创业公司至关重要的技能。即使是最好的创意,如果没有适当的经济发展,也无法长久存活。由于早期采用者和早期多数人之间存在巨大差距,初创公司需要有一个明确的聚焦,力求满足特定客户群的需求。在本章的示例中,MedVision(参见案例研究跟随 MedVision 的创新周期部分)实施了一种肺癌分类器。他们衡量了多个替代方案的市场需求,并确定癌症分类是最有前景和现实的应用案例。在短期内,他们计划通过几个成功的部署来吸引收入和新客户。从长远来看,他们计划收集市场反馈,扩展系统功能以支持更多类型的医疗设备,并扩展他们的疾病识别列表。关键的思路是通过进行实验和收集可衡量的反馈,将你的产品导向市场需求的满足。

在接下来的章节中,我们将探讨寻找可以推动数据科学项目的创意的不同方法。

寻找项目创意

在实施第一个原型之前,你需要找到有前景的创意进行开发。要创造创意,你可以从两个出发点之一着手:商业或数据。

在商业流程中寻找创意

如果你正在与已经建立的企业合作,找到创意的第一种也是最直接的方法是向管理层询问他们的需求。将数据科学专长与深入的领域知识相结合,可以帮助你在他们的需求和你团队的能力之间找到匹配。然而,你的客户很少会知道自己遇到了什么问题。在使用这种策略时,你最有可能得到的回应是,我们知道这个问题,且已经在着手解决

在极少数情况下,一个问题可能会被端上银盘。如果不是这种情况,你将需要深入了解公司的业务。首先从他们的关键创收流程开始。了解这些流程是如何运作的。然后,将所有步骤标记为手动、部分自动化或完全自动化。现有业务流程改进的两个关键领域是手动步骤的自动化和自动化步骤的优化。

对于手动步骤,研究为什么它们仍然以这种方式执行。人工劳动可以产生大量的数字化数据,你可以利用这些数据来训练模型。表单验证、表单填写和客户支持是一些常见的案例,你可以通过数据科学解决方案来替代这些重复的人工劳动。

对于自动化和部分自动化的步骤,研究实施这些步骤的 IT 系统。查看数据源:数据库、数据仓库和文件存储。然后,看看哪里可以部署机器学习模型来优化这些步骤。评分、风险管理和算法营销算法就是其中的例子。

在分析现有业务流程时,最佳的做法是找出如下步骤:

  • 生成数据:这一过程中的这一或任何前一个步骤都应持续生成可以被模型使用的数字数据。

  • 对业务至关重要:改进应该为客户提供直接的商业价值。增加价值总是一个强有力的卖点。

  • 具有数据科学应用潜力:你可以利用数据构建一个算法,提供洞察或自动化决策过程。

在 B2B 环境中,利用现有的业务流程寻找有前景的数据科学项目想法是一个稳妥的方法。这可以让你深化领域专长,找到最有价值的改进。

现在,让我们看看如何从数据中获取创意。

从数据中寻找想法

创造项目想法的另一种方式是直接从数据中寻找:

  1. 首先,你应该创建与你合作的公司的数据源地图。有时,这些信息会直接提供给你使用。如果没有,你的团队应该做一些研究,恢复组织的数据架构。利用这个数据地图,你可以识别出最大和最完整的数据源。

  2. 然后,根据数据量和数据质量对所有数据源进行排序,查看不同数据库之间可能的数据合并。目标是为进一步研究创造几个起点。

  3. 最后,深入了解你所选择的数据源。寻找可以用来构建监督学习或无监督学习模型的数据集。在这个阶段,你不应构建任何模型;只需写下所有想法——越多越好。在记录下这些想法后,看看是否有任何想法能够创造新的商业价值。

这种寻找创意的方式具有风险、耗时且非常具有创意。成功的几率比之前的方法低,但如果你能够从数据出发,找到一个行之有效的想法,你更有可能偶然发现一个独特的数据科学应用案例,这会为你带来竞争优势并提供新的商业价值。第一种方法更适合寻找可持续的创新,而第二种方法则可以用来挖掘颠覆性的创意,也就是变革性想法。

偶尔,一些人会提出真正独特的创意。这些创意可能没有任何数据,也没有商业背景——只有一个引人入胜的想法。那些能颠覆行业的创新性想法通常融合了几个表面上看似无关的学科:

  • 医学 + 计算机视觉和机器学习 = 患者的自动化疾病风险分析

  • 汽车 + 计算机视觉 = 自动驾驶汽车

  • 呼叫中心 + 深度神经网络 = 完全自动化的对话系统,具备语音识别和生成

如果有一种可靠的公式可以用来创造这样的想法,那么它们就不再是罕见和令人惊讶的了。增加发现新想法的机会的唯一方法是积累在不同领域的知识和经验。

如果你认为你已经想出了一个有前景的概念,不要急于行动。写下你的想法并开始研究它:

  • 查找市场上已经存在的类似产品。很可能,你会找到几个至少有些相似的产品。

  • 收集并分类竞争对手的产品功能。

  • 写下每个产品背后的核心商业模型。

  • 将所有收集到的功能按几类进行排序:

    • 最佳功能:没有人能做得比这更好;这是产品的独特特性。这个特征通常是决定购买的关键因素。

    • 核心功能:大多数竞争者已经相当好地实现了此功能。

    • 基础功能:这是以基础的方式实现的。许多其他竞争者在此功能的实现上更为完善。

    • 缺失功能:产品缺少某个功能。

  • 通过描述产品功能开始构思你的创意。为你的产品创建一个概况,并思考那个使它与众不同的特征。

  • 思考一下你的产品商业模式。它如何与市场上的其他产品相关联?

如果你在市场上找不到任何竞争对手,或者你看到你的产品能够轻易将竞争者排挤出市场,那么你有机会创造出颠覆性的技术。记住,将颠覆性创新推向市场需要仔细的规划、专注和跨越鸿沟的策略。

接下来,我们将看一个案例研究,内容是关于在保险公司寻找创意和管理数据科学项目的。

案例研究 —— 在保险公司寻找数据科学项目创意

在这个案例研究中,我们将考察虚构的 Insur Inc.公司,Rick 最近晋升,现在担任数据科学部门负责人。数据科学是公司的一门新领域。尽管他们尝试过多个原型,但没有一个成功进入生产阶段。Rick 的第一个重要任务是找到一个既有益又能为公司带来利润的数据科学应用场景。

Rick 已经知道公司的主要收入来源是销售保险单,而主要损失则来自保险理赔。Insur Inc.提供健康、房地产和汽车保险项目。公司最大的产品是其汽车保险,占整体收入的 75%。Rick 仔细研究了汽车保险部门的流程。

首先,他查看了新保险单的流程,如下图所示:

这个过程由四个 IT 系统支持:

  • 前台系统:这是一个保险顾问 UI,在所有 Insur Inc.的办公地点使用。该系统不存储大量数据,作为一个轻量级的 UI,它的功能相比后台系统有限。

  • 后台系统:这是一个管理所有与保险合同相关数据的系统。后台工作人员使用该系统来验证和处理新合同。

  • 评分与费率系统:这是后台系统的辅助模块,利用保险合同数据并应用一套规则,为客户找到最匹配的费率。

  • 保险单注册:这是一个中央数据仓库,存储所有与保险合同相关的数据。

Rick 想要研究利润损失周期,但这个过程只包括了周期中的利润部分。损失由另一个过程管理,即保险理赔管理:

参与这个过程的 IT 系统几乎一样,和保险合同一样,除了理赔处理系统。专门的经理使用这个软件来验证理赔并安排现场调查损坏的车辆。该系统还会识别欺诈性理赔。欺诈检测过程大部分是手动进行的,但系统中也实现了一些简单的基于规则的检测器。

Rick 决定改进评分与费率系统。根据客户数据预测潜在理赔将有助于提高风险识别和合同定价。风险较高的客户将会收到更高的费用。Rick 组建了一个团队,并开始使用来自保险单登记处后台系统评分与费率系统的数据进行新评分算法的原型开发。公司计划实施一个二分类器,用于估算每个新客户有效理赔的概率。汽车保险部门的业务人员已经熟悉假阳性和假阴性错误的概念,因此他们使用混淆矩阵来比较当前和新评分算法的表现。业务部门拒绝使用像 F1 分数这样更复杂的指标,建议直接从混淆矩阵中计算利润增加。

经过三周的原型开发,Rick 的团队创建了一个分类器,优于当前基于规则的评分与费率系统算法。他们将预测结果发送给业务部门进行评估。30 分钟后,业务部门要求解释每个得分。结果发现,当前的评分系统生成了详细的季度报告,并将其发送给一个监管机构,后者检查公司使用的评分模型的有效性。该模型应当完全可解释且易于人类理解。Rick 的团队使用了一个具有大量参数的黑箱模型,以实现高准确率,因此他们的模型未能满足这一要求。像逻辑回归这样的可解释模型更适合这里,但它们的性能对于当前的系统来说不尽如人意,因此不适合部署。

Rick 意识到他和他的团队浪费了三周的项目时间。这对他的老板来说是个坏消息,他被要求不要再犯同样的错误。

这一次,Rick 研究并记录了所有相互冲突的需求。他通过向汽车保险部门的同事询问业务流程的每一个细节,深入理解了领域知识,并为明确起见将其记录下来。在研究过程中,他验证了欺诈检测流程更适合迁移到机器学习模型:

  • 没有相关的政府规定和特殊报告要求。

  • 理赔处理部门在欺诈检测方面遇到了困难,因为这是他们主要的损失来源之一。决策过程耗时且每一项理赔都需要检查,因此欺诈检测的整体质量逐渐下降。

  • 理赔处理数据库中收集了大量数据。

主要问题是,客户需要更详细的拒绝理由,而不仅仅是“我们的模型认为您的保险索赔是欺诈性的,因此我们拒绝了它”。因此,Rick 建议公司只使用一个用于欺诈检测的算法。这个想法是创建一个基于机器学习的过滤器,用来评估索赔欺诈的可能性。如果这个可能性足够高,就会触发当前的欺诈调查流程。所有索赔中只有 0.5%是欺诈的,因此如果模型准确,它应该能显著减少检查的数量。

Rick 准备了一个解决方案架构,展示了新欺诈检测系统将如何实施以及如何与现有流程集成。他与所有业务利益相关者会面,验证了他的想法。每个人都同意这种方法。他们达成的一致评估策略与评分模型相同。之后,进入了下一个原型设计阶段。该模型被证明是成功的,Rick 被要求实施完整的欺诈检测模块,并将其集成到现有的业务流程中。

总结

在这一章中,我们探讨了创新,并学习了如何管理它们。良好的创新管理要求我们仔细规划自己的活动,并利用销售、市场营销和技术领导等不同的视角,将我们的创意与市场需求对接。

首先,我们描述了每个视角如何有助于有效的创新管理。接下来,我们探讨了将创新融入大型组织和初创公司的复杂性。数据科学对于大多数组织来说是一项创新活动,我们定义了几种策略,可以用来找到项目创意并使其成功实施。

我们还考察了三个案例研究,每个案例都与创新管理的不同主题相关。第一个案例是在 MedVision 跟随创新周期,展示了创新周期如何在现实场景中应用。第二个案例是关于将数据科学引入零售业务,我们探索了大组织中的创新管理。最后一个案例是在保险公司寻找数据科学项目创意,展示了使用结构化方法寻找数据科学项目创意的重要性。

在下一章中,我们将探索数据科学项目生命周期,它允许您为您的团队结构化和规划任务。

第八章:管理数据科学项目

在上一章中,我们探讨了创新管理。我们制定了可以帮助寻找数据科学项目创意的方案,并将这些创意与市场需求相匹配。在本章中,我们将通过分析数据科学项目如何与一般的软件开发项目不同,来探讨数据科学项目管理的非技术方面。我们将讨论导致数据科学项目失败的常见原因,并制定一种方法,降低数据科学项目的风险。最后,我们将深入探讨项目估算的艺术与科学。

在本章中,我们将探讨如何从头到尾管理项目,涵盖以下主题:

  • 理解数据科学项目失败

  • 探索数据科学项目生命周期

  • 选择项目管理方法

  • 选择适合你项目的方法

  • 估算数据科学项目

  • 发现估算过程的目标

理解数据科学项目失败

每个数据科学项目最终都会变成一个生成定期报告或在线运行的软件系统。软件工程的世界已经为我们提供了多种软件项目管理方法,那么为什么我们还需要为数据科学项目重新发明一种特殊的方法呢?答案是,数据科学项目需要更多的实验,并且比软件工程项目需要容忍更多的失败。

为了看清传统软件系统与具有预测算法系统的区别,让我们来看一下数据科学项目失败的常见原因:

  • 对数据的依赖:一个健全的客户关系管理CRM)系统能够组织销售流程,在许多组织中都能良好运行,且与其业务无关。一个预测销售流程结果的系统可能在一个组织中运行良好,但在另一个组织中可能需要部分重写,甚至在其他组织中完全不起作用。原因在于,机器学习算法依赖于数据,而每个组织都有其独特的客户数据模型和销售流程。

  • 需求变化:虽然软件开发项目常常会面临需求变化,但这些变化大多是从客户流向实施团队。在数据科学项目中,来自实施团队的新洞察和研究成果可能会形成反馈循环。项目利益相关者可能会根据数据科学家发现的新信息生成新的需求,并改变项目的方向。

  • 变化的数据:在软件开发项目中,数据模型大多是固定的,或者可以在受控的方式下进行更改。数据科学项目通常需要集成新的数据源以供研究使用。数据始终在变化和转化,在系统内部创建多个中间表示。人们和软件组件使用这些表示进行报告、数据处理和建模。软件工程项目使用固定或缓慢变化的数据模型,而数据科学项目使用不断演变的数据管道。

  • 实验和研究:数据科学项目涉及完成大量实验。通常,实验数量从几百到几千不等。软件工程项目通过设计系统架构并以可控的方式演化来限制研究。在数据科学项目中,下一个实验可能会使项目朝着新的方向发展,而且你永远不知道何时会发生这种变化。

理解数据科学管理方法

传统的软件工程项目管理方法并没有考虑这些问题。大多数现代软件项目管理方法需要解决的关键问题是需求变化的问题。敏捷方法论专注于规划和执行快速迭代。每次迭代都旨在尽可能快地向客户交付功能。外部反馈是项目变化的主要来源。

在数据科学项目中,变化来自各个方向。它们在项目团队内部传播,也来自企业的客户。度量标准应始终确认进展。实现目标的过程中,可能需要经历几十次甚至上百次失败的实验,这使得快速迭代成为必须。

敏捷项目的典型迭代周期可以从 2 周到 1 个月不等。项目团队为此期间确定迭代范围,并在严格的时间表下交付。在数据科学项目中,迭代中期的实验结果可能会影响迭代目标,并且由于新的发现,其他计划任务的工作重要性可能会降低。

管理层必须为常见问题和问题提供保障。来自软件工程领域的方法论可以为你提供坚实的基础,但它们并未提供可以用来管理研究和治理数据的工具。

如果你开发的是使用机器学习的系统,必须关注以下几点:

  • 验证和对齐的要求:你需要检测并管理来自外部(客户)和内部(研究团队)来源的需求变化。

  • 数据治理:你的项目将需要数据治理标准,这些标准应严格应用于与数据相关的每一行代码。理想情况下,通过你的数据管道流动的每一行数据都应该能追溯到其数据源。所有进出数据集,包括中间报告,都应被跟踪和记录。

  • 研究过程:每个数据科学项目都需要进行广泛的研究。如果没有控制,研究很容易迅速消耗掉预算,而项目的完成似乎遥不可及。管理研究项目的核心组成部分包括以下内容:

    • 研究规划:项目团队应当规划并优先处理他们的所有研究。

    • 实验方法论:每个实验都应遵循一套标准,如跟踪、文档记录和可重复性。

    • 快速失败并早期恢复:实验经常会失败。你的管理方法应该使实验尽可能快速,以便你的团队能够尽快地进行迭代和学习。

  • 软件工程过程:你的工作大部分将涉及软件的创建。软件项目管理已经提供了很好的工具,但它们需要与管理方法论的其他组件紧密集成。

接下来,我们将探讨数据科学项目中常见的阶段。我们将这些阶段与项目生命周期的过程结合起来,以便全面了解数据科学项目的全貌。

探索数据科学项目生命周期

每个数据科学项目有几个不同的状态。我们可以将不同领域和技术的项目结构化为包含数据科学项目生命周期的各个阶段,如下图所示:

让我们更详细地探讨生命周期中的每个阶段。

商业理解

在这一阶段,你将运用你的领域专业知识,研究项目的商业方面。你需要定义商业需求,并确认这些需求的实施能够改善客户的生活。你还应该定义并记录所有相关的商业指标,以便用业务方能够理解的方式衡量和报告结果。这个阶段的输出应为一份业务需求规格书,已由项目相关方审阅、修订并达成一致。

数据理解

在这一阶段,你需要研究与之合作的组织的数据架构。你需要记录数据来源、它们的拥有者及其使用的技术。除非你打算从数据中挖掘项目创意(参见第七章,管理创新),否则不必记录所有可用的数据源。重点是与项目相关的有用数据。

找到这些数据后,进行探索性数据分析EDA)并彻底研究数据。查看数据中是否有任何异常或不寻常的现象,研究它们发生的原因并记录如何处理它们的方法。例如,如果数据集包含大量空值,你应该有一个处理这些空值的方案,而且你的处理方式不应以不合适的方式扭曲数据。

你还应当在 EDA 阶段考虑特征工程的想法。对数据进行统计分析,并尝试找到有助于解决当前任务的因果关系。

数据理解阶段应当有以下输出:

  • 数据源字典:本文档简要描述了与你的项目相关的所有数据源。

  • 一份展示你数据分析结论的 EDA 报告:该文档应描述你将用于解决当前任务的方法和应对数据中错误的策略。你应该包括一些可能引起客户兴趣的事实。

数据准备

这一阶段是我们开始处理数据的地方。数据准备阶段涉及将原始数据转换为有用的格式。你从数据源中读取数据并对其进行准备,以便使用这些数据实现项目目标。如果你在解决一个基于结构化数据的任务并计划使用机器学习,你将需要进行特征工程。前一个阶段应该会为你提供数据中独特之处的洞察,这些问题你可以在数据准备阶段进行修复。本阶段的输出是一个或多个可重复的数据准备任务以及一个可以用来构建和测试模型的数据集。

优化数据准备

数据准备和数据理解是非常耗时的。这些阶段可能占用项目时间的 80%,所以不要忘记提前规划。由于这些阶段耗时,优化团队的表现非常重要。开源的自动化 EDA 和特征工程工具可以在项目初期为你节省大量时间,因此不要犹豫使用它们。在本书的创建开发基础设施章节中,我们将介绍一些可以帮助你加快数据准备和数据理解阶段的库。

为了减少出错的可能性并便于监控,你应该关注数据的来源和版本管理。每个数据集都应该能够追溯到其源头。无论是中间数据还是原始数据,都应该妥善保存所有数据文件。在你的代码中记录每个数据转换任务的输入和输出。数据处理的 bug 很难发现,除非你对数据流有完全的掌控。

另一个重要的点是可复用性。要合理编写数据处理代码。虽然很诱人将大量杂乱无章的代码写在一个文件中并让它们执行任务,但这样会增加技术债务。代码可能运行一段时间,但最终会在没有任何预警的情况下失败。随着时间推移,你可能还会想为代码添加额外功能。如果代码写得不好,你将花费大量时间来修复和调试。

为确保你的数据处理代码稳健,请在代码审查时使用以下检查清单:

  • 所有重复的代码被封装成函数。

  • 逻辑相关的函数被封装在类和模块中。

  • 你的代码有广泛的日志记录。

  • 所有配置参数可以通过配置文件或命令行参数进行更改。

  • 你的数据处理任务的输入和输出需要存储在某个地方。

  • 代码可复现并附带文档。

建模

本主题已在本书的什么是数据科学?章节中讨论。在此阶段,我们运用数据科学、机器学习和深度学习的知识来解决当前任务。这些工作分为以下几个阶段:

  1. 首先,我们确定任务类型,即监督学习(分类与回归)、无监督学习(聚类与文档主题建模)或强化学习。

  2. 然后,准备一个适合解决任务的算法列表。

  3. 接下来,设计一个模型验证和测试方法。

  4. 最后,优化模型的参数并选择最佳模型。

评估

尽管建模和部署步骤并不分开,但这一阶段值得单独强调。在这一阶段,你必须测试技术和业务指标,并检查模型的单个预测结果。查看模型在测试集上出现的最大错误,并思考你可以对数据、特征或模型做出哪些改动来修正这些错误。这也是发现数据处理漏洞的好方法。

你的项目应该有两种评估策略:在线评估和离线评估。在线评估负责跟踪已部署模型的所有指标,而离线评估则用于决定哪个模型可以进入部署阶段。

典型的数据科学项目包含数百个实验,这些实验涉及不同的模型、数据和参数。每个实验会生成新的数据,如指标、代码参数和备注。使用专门的实验跟踪工具来判断某个实验的成功与否。这些工具可以自动收集实验的所有日志、指标和成果,以确保实验的可复现性,并简化实验结果的搜索。如果你不想使用或无法使用专门的工具,电子表格可以作为一个不错的替代方案,尽管你需要花费更多时间来处理它。保留完整的实验日志和你在建模和数据预处理过程中做出的所有决策,将帮助你比较不同实验并得出结论。

如果你需要了解模型测试的技术细节,请参阅 第二章,测试你的模型

建模和评估阶段紧密相连,通常在多个迭代过程中反复进行,直到达到最终阶段。

部署

在部署阶段,你将最好的模型发布给最终用户并检查结果。在这个阶段,复杂性常常被忽视。生产代码有一套严格的要求和服务水平协议SLAs),你的模型需要满足这些要求。我们可以将这些要求分为两类:功能性要求和非功能性要求。功能性要求定义了你的服务特性,而非功能性要求定义了你的 SLA。

以下是模型服务的一些功能需求示例:

  • 请求/响应格式

  • 模型版本控制的能力

  • 跟踪部署和请求统计信息的用户界面

非功能性需求定义了服务质量和可用性,以下是一些例子:

  • 期望的请求吞吐量(每秒 1000 个请求)

  • 可用性计划(24/7 和 5/8)

  • 安全通信

  • 弹性可扩展性,确保在用户负载峰值时系统仍然可用

模型部署的要求对于不同的项目是相似的,因此这一过程可以实现复用。你可以开发自己的模型服务框架,或者使用现有的框架,而不是为每个项目重复相同的工作。

在部署阶段还需要记住的另一个重要点是评估。评估不会在之前的阶段结束,你应当在线评估模型的所有指标。如果在线指标低于某个阈值,系统可能会触发警报或采取补救措施,如重新训练模型。A/B 测试和多臂赌博机也是部署过程的一部分,可以作为模型服务器的功能进行支持。

现在,你应该熟悉每个数据科学项目的常见阶段。让我们看看如何通过合适的管理方法执行每个阶段。

选择项目管理方法论

项目管理方法论提供了一套规则和流程,用以区分混乱的项目与有条理的项目。它们为每个人提供了一个可以朝着更大目标前进的框架。法律在我们的社会中也起着相同的作用。然而,法律并不完美,且往往会失败。在软件管理领域也没有灵丹妙药。有些管理实践更适用于某种类型的项目,但在另一种项目中可能会让你失望。在接下来的章节中,我们将探讨管理软件项目的最流行方法,并学习如何将它们适应数据科学环境,从而得出结论并选择最适合我们项目的方法。

瀑布

管理项目最直观的方式是将其视作建造房屋。其步骤如下:

  1. 准备建筑工地

  2. 奠定基础

  3. 创建框架

  4. 建设屋顶

  5. 建立墙体

  6. 连接电力和水源

  7. 完成外部和内部建设

构建一个软件系统,你需要做以下步骤:

  1. 准备开发环境

  2. 分析并记录需求

  3. 分析并记录架构和软件规范

  4. 建设系统

  5. 测试一切是否按照需求正常工作

  6. 完成项目

这种管理方法论被称为瀑布模型。它在纸面上看起来很合理,但实际应用中很少能够取得成功。其背后的原因在于所有步骤是顺序排列的,并且只会重复一次。如果你犯了一个错误,项目计划就会崩溃。一个未记录的需求,例如在第 2 步中,可能会在第 6 步时导致灾难。客户对最终结果没有完整的视图,也可能犯错误。在客户看到实际实现后,需求可能会发生变化。

软件项目经理知道单一的瀑布模型无法解决他们的问题,因此他们将多个小的瀑布模型组合成顺序迭代。这一发展阶段被称为迭代和增量软件开发。迭代项目由多个阶段组成,每个阶段都以瀑布式的方法进行管理。每次迭代的长度通常以月为单位。在每个阶段结束时,开发团队会向最终用户展示阶段性成果,以收集反馈。这些反馈将推动下一次迭代的启动。随着每次循环,对期望结果的理解逐步发展,直到满足客户需求。

敏捷

迭代方法对于大多数软件项目来说仍然过于繁重。它们往往因为不断积累的技术需求而受到困扰。2001 年,软件开发领域的一些最杰出的头脑创建了《敏捷宣言》(agilemanifesto.org),它描述了一种新的管理方法,简明扼要地提出了四个要点:

  • 个体和互动优先于过程和工具

  • 可工作软件优先于全面的文档记录

  • 顾客合作优先于合同谈判

  • 响应变化优先于遵循计划

也就是说,尽管后者每个点都有价值,我们更重视前者每个点的价值。

今天,我们将敏捷与看板和 Scrum 联系在一起。这些方法需要介绍 50 到 500 页才能解释清楚。然而,敏捷的核心很简单。任何项目都可能因为敏捷宣言而偏离正轨,事实上确实有很多。如果忽略宣言的最后一句,您可能最终会创建一个没有计划或规范的项目,这将不可避免地导致无法控制的混乱。人们在管理软件项目时需要更直接的指导。这就是看板和 Scrum 被发明的原因。

看板

首先,让我们来看看看板。解释看板的最佳比喻是传送带。想象一下,所有任务在完成之前经过固定数量的阶段。这些阶段的具体定义由您决定。

在软件项目中,您可能希望使用以下过程:

  1. 积压(所有待处理任务收集的缓冲区)

  2. 需求规范

  3. 开发

  4. 代码审查

  5. 测试

  6. 部署

Kanban 将每个任务可视化到一个面板上,如下图所示:

每个阶段应具有关于可以并行完成的任务数量的限制。看板有意限制同时进行任务的数量,以增加吞吐量。如果团队因为有太多任务停留在部署阶段而受阻,那么所有能够将最终产品运送到生产环境的团队成员都应停止当前任务,转而解决瓶颈问题。问题解决后,团队可以根据优先级决定是否继续处理其他任务。因此,看板支持跨职能团队,每个人都可以帮助推动每个阶段的任务。看板不会取消角色的概念,但它指出,无论角色如何,每个团队成员都应能够帮助处理瓶颈。

看板专注于尽快完成单个任务。我们可以用以下主要指标来衡量看板项目的有效性:

  • 领导时间:任务从积压队列到完成的平均所需时间。

  • 周期时间:任务从开始阶段到平均完成所需的时间。在我们的例子中,周期时间将介于需求规范和部署之间。

  • 吞吐量:您在时间间隔内完成的平均任务数,即一天、一周或一个月。

一般来说,使用看板时,你不需要创建固定的项目计划和固定的截止日期。同时,你也不必单独估算每一个任务,因为度量指标会处理这个问题。你可以测量团队的工作流几周,以便了解近期能够交付的工作量。

看板的优点也是其局限性,其中一些局限性如下:

  • 看板在每个任务的工作量相同的情况下效果最佳。如果某些任务花费的时间明显长于其他任务,你的度量指标将变得没有意义。

  • 如果你不想作为一个跨职能团队工作,你的工作流将遭遇瓶颈,这样使用看板就变得毫无意义。

  • 看板不会提供管理截止日期、项目范围和预算所需的工具。它唯一需要关注的就是优化工作流。

看板是一种非常适用于具有重复任务的项目的软件管理方法。它也可以部分应用于项目的某些部分,只要在这些部分使用看板是有意义的。以下是一些适合使用看板的项目示例:

  • 在软件支持项目中,你需要处理部署和修复频繁出现的问题。

  • 如果你的数据科学项目有一个专门的团队进行机器学习模型的实验,使用看板将有助于提高他们的工作流。

  • 需要创建大量相似物品的项目,如数百个网页表单、数据映射或相同的机器学习模型。

关于 (看板)的一件令人惊讶的事情是,它最初是为了提高汽车制造过程的效率而开发的。丰田于 1959 年发明了看板,并于 1962 年将其整合进他们的生产环境中。你可以看到,看板的所有优缺点在制造环境中都有意义,在那里汽车零件通过传送带进入不同的生产阶段。

Scrum

另一个来自敏捷家族的流行管理方法是 Scrum。Scrum 背后的主要思想是 Sprint。Sprint 是一组有固定截止日期和持续时间的任务。典型的 Sprint 持续时间为一周、两周和一个月。讲解整个 Scrum 过程需要一本书,因此我们在这里只介绍基本内容。

Scrum 流程包括以下步骤:

  1. 待办事项列表整理

  2. Sprint 规划

  3. Sprint 执行

  4. 回顾

类似于其他敏捷方法,所有任务都会进入项目待办事项列表。项目待办事项列表需要定期整理:所有过时的任务应该删除;其余任务需要按优先级排序。

Scrum 的主要组成部分是冲刺(sprint)。冲刺是一个具有固定截止日期和明确目标的迭代周期。典型的冲刺周期为 2 周。冲刺通常以冲刺规划会议开始,团队成员在会议中查看项目待办事项,并将任务纳入冲刺。每个任务都会以抽象的故事点进行估算。使用故事点而不是小时来进行估算的目的是使估算相对而非绝对。例如,我们可以认为一个故事点的任务是微不足道的,而两个故事点的任务则稍微难一些,但仍然容易完成。四到六个故事点表示一个正常的任务。另一种故事点估算系统建议使用 2 的幂(最高到 128)作为任务估算。在第一次冲刺时,估算比较粗略。在第二次冲刺时,你将新任务与之前的任务进行比较,并查看任务的故事点值。经过四次冲刺后,你可以看到团队的平均完成故事点数。你也可以计算出单个故事点的近似小时等价值,尽管这应该仅作为参考,而不是冲刺规划过程中的故事点替代物。

在规划阶段,每个团队成员单独估算任务,然后比较各自的估算结果。这有助于确保每个人对任务定义的理解一致。估算差异意味着任务需要更清晰的解释,并根据 SMART 标准进行评估。

冲刺在规划阶段后开始。当你开始进行冲刺时,冲刺范围将被锁定。你不能在规划阶段定义的范围内做任何更改。团队的主要目标是尽可能在冲刺结束前完成所有任务。这一策略使你在应对变化的同时,仍能实现计划目标。Scrum 的主要优点也是其主要缺点。如果你的客户在周中带着一个需要立即完成的极其重要任务来找你,你应该尽最大努力说服他们,告诉他们团队会在下一个冲刺中交付该任务。范围锁定是使冲刺顺利进行的关键机制。如果你经常偏离这一规则,Scrum 将变成一个障碍,而非一种有益且高效的管理方法。

在实际操作中,范围锁定可能会引发问题,尤其是在 B2B 环境中。对于那些你没有选择余地,且被迫改变冲刺范围的情况,你有两个选择:

  • 交易任务:你可以从冲刺中移除一个任务,并添加一个新任务。

  • 开始一个新的冲刺:你可以停止当前的冲刺并规划一个新的冲刺。

经常使用这些选项会使 Scrum 变得低效。尝试与客户谈判固定的冲刺范围,并向他们展示这种方式带来的好处,比如按计划交付,同时也为需求变化留出空间。

一个有效的策略可以帮助你避免预期之外的范围变化,那就是要求客户参与待办事项梳理和迭代规划。Scrum 专家建议,为此任务指派一个特别的产品负责人角色。产品负责人应当决定任务的优先级、迭代目标,并与项目利益相关者协商所有冲突的需求。

Scrum 直接来源于软件开发领域,因此它比 Kanban 具有更少的限制。代价在于其复杂性:Scrum 并不是一种简单的方法论,它会带来管理负担。如果你希望它能有效运作,每个团队成员都应当理解 Scrum。在复杂的项目中,你可能需要给某个人分配专门的 Scrum master 角色,负责将方法论应用到一个或多个项目中。

在下一部分,我们将根据项目的需求来探讨如何选择方法论。

选择适合你项目的方法论

选择项目管理方法可能成为一项引人入胜且复杂的任务。你可能会花费大量时间思考哪种方法能比其他方法更好地支持你的流程,以及它将带来哪些限制。尽量不要在方法论的考虑上浪费太多时间。选择一个方法并坚持下去,除非它显然对你的项目有害,这要比纠结于方法的细节更为重要。为了简化这一过程,我们将探讨一些关于选择管理方法的简单指南。

创造颠覆性创新

如果你创建的解决方案应该颠覆市场,唯一重要的因素就是你方法论的效率。项目初期你可能没有太多客户,因此你应该能够收集反馈并专注于工作,以便对下一个版本进行迭代。在这种情况下,Scrum 是最合适的。你可以在每个迭代周期内实现新功能,并在每次迭代结束时收集反馈,以开始新的迭代。Kanban 也可以使用,但在颠覆性创新方面,它提供的好处较少。

提供经过测试的解决方案

如果你实施的系统类似于你过去的项目,那么相较于以往的迭代,它可能需要的研究要少得多。系统集成项目也是如此,你提供的服务可以将产品集成到客户的 IT 环境中。在这些项目中,你可以定义许多以客户为中心的任务,并根据总工作量将其分成三到五个小组。在这种情况下,Kanban 将提供最大益处。使用 Kanban 可以帮助你在更短的时间内向客户交付更多成果。

为客户开发定制项目

当你为客户工作时,使用敏捷方法论可能非常棘手。客户希望同时拥有两全其美的方案:固定的截止日期和不断变化的需求。你的任务是决定该项目的最佳方法,并解释它的优缺点。许多团队选择在 Scrum 和瀑布之间找到折中的做法:你制定项目的初步范围,进行估算,并展示给客户。接下来,你将通过冲刺逐步实施项目范围。需求在实施阶段不可避免地会发生变化,因此,管理这些变化并确保客户参与冲刺规划至关重要。

选择项目方法论与估算数据科学项目密切相关。在接下来的章节中,我们将定义估算过程的目标,并学习如何进行估算。

估算数据科学项目

如果你需要向某人解释预测的基本原理,可以问他们是否曾经参与过软件项目。如果是的话,他们已经了解了预测的基本知识:每个做过项目的人都曾经进行过任务估算。每个人都需要估算。你的客户需要估算来计划并控制他们何时开始使用你项目的成果。项目经理需要估算来了解任务或整个项目的范围、工作量和大致成本。

估算在多个领域都很有益,以下是几个例子:

  • 理解工作结构:将一个任务分解成多个子任务,以查看需要完成的主要步骤。

  • 理解复杂性:虽然单独估算一个复杂任务很困难,但估算工作结构中的每个单独部分会更简单。这可以帮助你了解任务的复杂性以及完成它所需的时间。

  • 理解成本:在大多数企业中,如果不先解释和辩护项目的成本和所需资源,你无法开始工作。

估算的最大问题在于它们往往失败。我们的计划不准确、不完整,而且通常与实际工作完成的方式无关。即使是经验丰富的软件开发人员,也难以估算完成一个任务所需的总小时数,除非他们已经做过多次。

研究表明,人类在进行绝对估算时表现不佳。我们的脑袋并不适合建立复杂多层次项目的准确心理模型。例如,如果我们问一群陌生人最近的建筑物有多高,大多数人无法给出正确答案。然而,如果你告诉他们几座建筑的高度,他们的估算会更准确。这不仅适用于建筑物的高度估算,任何类型的估算都是如此。

要在数据科学项目中使用相对估算,你需要两个条件:相关样本和良好的估算过程。我们可以把相关估算看作是简单的统计估算器,通过平均所有之前相关任务的长度来得出。为了创建这样的估算器,我们首先需要收集数据集。如果你遵循瀑布流程,那么为了获得估算数据集中的一个新数据点,你需要从头到尾完成一个整个项目。在你熟练估算某一特定类型项目之前,可能需要在许多项目中失败进行估算。

诀窍是深入到单个任务级别。Scrum 建议你使用相对的故事点,而不是绝对的小时数,正因为如此。首先,你的估算会在任务级别变得相对,然后在冲刺级别,最后在项目级别。如果你没有任何有助于进行相对估算的经验,你应该进行的唯一绝对估算是针对项目的第一个冲刺。从这里开始,你应该以之前的任务为基础进行新的估算。

你不必使用 Scrum 来从相对估算中受益。Scrum 提供了一种使其生效的方式,但可能并不适合你的情况。如果是这样,你可以调整任何管理方法来进行相对估算。

区分商业估算和实施估算:

我们可以从两个角度来看待估算。第一个角度对于主要关注项目交付的项目经理和团队领导来说非常熟悉:实施角度。在这个例子中,估算的主要目标是提供关于构建解决方案所需时间和资金的正确预期。

另一个角度与项目的商业目标密切相关,通常是实施团队未曾看到的。每个项目通常都有一个支持它的商业模型,设定了关于收入增长、客户满意度、成本减少等方面的预期。

在创建实施估算时,应该始终考虑这个商业模型。在数据科学项目中,可以通过从商业模型中得出预算限制并创建一套评估项目绩效的商业指标,将商业估算纳入项目中。

学习如何进行时间和成本估算

使用相对估算是一种有效的策略,但如果有人问你,你到底什么时候能完成这个? 那它就变得毫无意义了。Scrum 和 Kanban 并没有为你提供项目估算工具。事实上,这两种方法论认为做出这样的估算是没必要的。如果你的目标是高效完成一个有已知截止日期和预算限制的项目,这种想法是成立的。然而,也有一些情况,你可能需要自己设定预算和时间的限制。

让我们以咨询环境为例。我们需要为客户构建一个定制的分析系统。主要任务是根据用户的资料估算购买某个产品的概率。该客户需要一个全新的解决方案,以满足来自多个部门的不同利益相关者的需求。他们还要求您将该解决方案与各种 IT 系统进行集成。他们邀请了几家公司竞争这个项目。第一件他们问每个候选公司的问题是,这将花费多少,您能多快完成? 如果我们知道绝对估算的局限性,我们该如何应对?

我们从大纲开始。大纲是一个分层的任务列表,您需要完成这些任务。瀑布式项目的最简单大纲可能如下所示:

  1. 收集需求

  2. 实现需求

  3. 测试系统

  4. 部署系统

使用瀑布式项目方法具有一定风险,因此我们将把系统分为多个阶段,每个阶段都会经历若干连续的步骤。根据阶段的复杂性,您可能需要对同一阶段进行一次或多次迭代才能完成它。从理论上讲,您可以尝试为每个两周的冲刺创建一个大纲,但由于数据科学项目的不断变化,这种做法是不现实的。

例如,来看一下收集需求的大纲:

  1. 收集需求:

    • 软件架构:

      • 非功能性需求规格

      • 非功能性需求实现策略

      • 组件图

      • 集成图

    • 功能性需求规格:

      • UI:

        • UI 需求

        • UI 原型图

      • 后端服务

      • 数据分析与建模:

        • EDA

        • 创建实验待办事项列表

您应该从定义粗略的步骤开始,然后逐步细化它们。如果您之前创建过类似的项目,您可以参考它们的大纲,这样您就能知道从哪里开始。收集并使用其他项目的数据可以作为相对估算的主要来源,因此不要低估您的先前经验。

您可能会发现一些任务难以分解。对任务的处理方式不确定是一个信号,表明您需要与客户沟通并找出解决方案。如果您不知道需要与多少个系统进行集成,那么分解所有与集成相关的阶段和任务将非常困难。在这种情况下,我们需要与客户沟通,迅速获取必要的信息。然而,在估算过程中,您可能会有数百个类似的问题,追踪新信息将迅速变得低效。最好提前准备一个编号问题列表。问题的答案在估算过程中可能会发生变化,因此每个问题应分配一个日期。理想情况下,这些问题应以便于协作的格式共享。

当你的大纲足够详细时,就该设计软件架构提案了。这是一个关键步骤,因为将大纲与客户需求匹配并不总是经济可行的,甚至从技术角度来看也未必可行。你应该至少对将使用哪些技术、如何将它们与客户系统的其他部分集成、以及如何部署你的解决方案有一个大致的了解。如果有任何关键的非功能性需求,比如 24/7 的可用性,软件架构师还应考虑如何从技术和系统设计的角度实现这些需求。制定一个高层次的架构愿景将有助于解释这个大纲。如果你认为有必要,千万不要犹豫去修改大纲。软件设计是一个复杂的任务,应该由有经验的工程师来做,因此,如果你在软件解决方案设计方面没有深入的专业知识,请寻求团队成员的帮助,或者更好地,将软件设计作为一个协作的过程。

完成大纲并有了软件架构愿景后,你可以开始估算项目。我推荐使用简单的统计估算方法,例如程序评估与审查技术PERT)。

在 PERT 中,你为每个任务给出三点估算:

  • 乐观估算:如果一切顺利,你计划花费在任务上的时间;可能会有一些小的技术问题和需求问题。

  • 最可能的估算:你能为任务提供的最现实的估算。

  • 悲观估算:在出现问题时,完成任务所需的时间。这包括处理失败实验、复杂的调试过程以及与客户进行长时间讨论的额外风险。

然后,你可以计算一个简单的加权平均值来得到最终的估算:

计算标准差对于制作置信区间也很有用:

将为你提供 99.7%的置信区间,这意味着任务将以 99.7%的概率落在这些数字之间。如果这个范围对你来说太宽,你可以使用,它会给你一个 95.5%的置信区间。

使用任何已完成项目的数据作为相对估算的基础。你使用的外部资源越多,估算就越准确,风险也会相对较低。

由于我们在估算方面不可避免地存在误差,所有的估算仅仅是对当前项目实施计划的粗略看法。项目大纲和估算应不断变化,并根据当前情况进行调整。你应该定期检查是否需要修改和更新原始计划。如果需要,及时向客户传达,并讨论这些变更的必要性。客户可能会将若干新功能添加到你的待办事项中,认为这些功能属于原始范围。如果事实并非如此,则需要协商范围扩展,并相应延长预算和期限。如果这些功能不够关键,可以建议客户将其从待办事项中移除。随着每个特定类型项目任务的完成,你的经验将不断增长。结果,你将能够预测更多客户的需求,并将其纳入基础计划,从而使估算更为准确。存储所有版本的项目估算,以便轻松追踪所有范围变更。

项目架构愿景在面对变化时也应具备足够的韧性。你的解决方案越是定制化,就越不可能创造出一个能够应对所有范围变化的理想架构愿景。提前规划,并在最可能变化的解决方案部分加入多个变动点。变动点是指从一开始就注定会发生变化的软件组件(或一组软件组件)。插件架构和具有固定契约的微服务就是允许轻松扩展或替代的变动点的例子。

发现估算过程中的目标

在进行估算时,重要的是始终牢记最终目标。你可以在没有宏大计划的情况下构建数据科学系统。创建估算并保持其更新需要大量的努力和时间。数据科学项目复杂且不可预测,因此,越是你和你的客户相信你的估算,它们失败的可能性就越大。如果你的团队在为新业务领域构建解决方案方面没有先前经验,或者你正在尝试应用新类型的算法或新技术,估算将变得更加不确定。

对如何实现最终目标有一个细粒度的视角是有帮助的。相反,依赖于精确计算所需的时间,或使用极为详细的大纲,则没有太大意义。明智地使用估算,它们将帮助你使实施计划与客户需求保持一致。

总结

在本章中,我们探讨了如何管理数据科学项目。我们研究了分析项目与软件工程项目的区别,并学习了数据科学项目的生命周期。我们分析了如何选择适合我们需求的项目管理方法,并揭示了估算数据科学项目的实用指南,还讨论了长期计划的局限性。无论你的计划和估算有多好,数据科学项目都有许多固有风险,这些风险可能成为项目失败的关键因素。

在下一章中,我们将讨论数据科学项目的常见陷阱。

第九章:数据科学项目的常见陷阱

在本章中,我们将探讨数据科学项目的常见陷阱,以及那些容易犯的错误,这些错误会增加你项目可能遇到的风险。了解如何应对这些问题对于项目的成功至关重要。不同类型的数据科学解决方案有许多诱人的执行方式,但这些方式可能会在项目后期引发不必要的困难。我们将逐一选择并解决这些问题,同时跟随数据科学项目的生命周期。

在本章中,我们将涵盖以下主题:

  • 避免数据科学项目的常见风险

  • 处理研究项目

  • 处理原型和最小可行产品MVP)项目

  • 减少面向生产的数据科学系统中的风险

避免数据科学项目的常见风险

任何数据科学项目的首要风险就是目标定义。正确的目标定义在成功的公式中起着重要作用。常常在任务定义之后,尤其是当任务定义模糊不清时,人们容易急于进入项目的实施阶段。这样做,你可能会以完全不同于业务实际需求的方式来解决问题。因此,定义一个具体且可衡量的目标至关重要,这将为你的团队提供一个工具,帮助他们区分正确与错误的解决方案。

为确保项目目标的正确定义,你可以使用以下检查表:

  • 你有一个可量化的业务指标,可以通过输入数据和算法的输出进行计算。

  • 业务方理解你使用的最重要技术指标。

  • 任务在数据科学术语中被定义。你知道自己是在解决分类、回归或其他类型的任务,并且有技术上的方法来处理它。

  • 你了解问题的(业务)流程和领域的细节。

  • 项目开始所需的所有数据源都存在,并且能够被实施团队访问。

另一个重要问题是文档记录。在数据科学项目中,实验结果常常会改变项目的方向。因此,记录所有实验、所做的决策和结论是非常重要的。对于数据和需求的任何变动也需要及时修正。当你拥有这些信息时,你将能够看到使你的解决方案按预期工作的思路全过程。

了解数据科学项目的常见风险将帮助你从重大错误中恢复过来,但细节才是关键。在下一节中,我们将讨论不同的管理方法,涉及研究项目、原型以及端到端生产系统,并详细讲解它们的特点。

处理研究项目

研究项目是指任何能够为你解决新问题的项目,特别是那些不太为人知的问题。研究项目不总是为了推动科学进步。如果你的团队处理的是一个全新的业务领域,或者一种新的机器学习库,这些也被认为是研究项目。发现如何将数据科学应用于新的业务领域也是研究。几乎每个数据科学项目都包含一个处理建模过程的研究子项目。

研究项目的第一个陷阱是缺乏明确的范围。每个研究项目必须有明确的范围,否则无法完成。同时,确定研究项目的外部约束也非常重要。随着范围的扩大,研究预算也会增加,因此有限的预算可能会影响你能够进行的研究深度和持续时间。

当你了解了自己的研究能力后,可以开始与团队一起填写实验待办事项。每个待办事项应包含一个可能提升模型质量或帮助实现期望功能的想法。每个实验都应根据 SMART 标准进行定义。

例如,针对二分类问题的初步实验待办事项可能如下所示:

  1. 执行探索性数据分析EDA)并熟悉数据。

  2. 使用梯度提升和基本预处理创建一个基准模型。

  3. 测试分类变量的编码:哈希编码。

  4. 测试分类变量的编码:目标编码。

  5. 特征工程:衡量日期特征的影响。

  6. 特征工程:聚合特征日期窗口。

为了符合 SMART 标准,每个条目还应包含截止日期、数据集链接、计算资源和度量建议。为了简洁,我们省略了这些细节。

你应该始终根据预期回报优先安排实验。一些实验可能需要大量时间才能完成,但初步测试所需时间较少。如果你和你的团队对优先级不确定,最好广泛开展实验,而不是深度开展。对当前研究周期中的所有实验进行快速初步质量检查,以确定每个实验的大致时间投入。

同时,跟踪实验中的每个细节也非常重要,例如以下内容:

  • 输入数据

  • 实验的日期和时间

  • 生成实验结果的精确代码版本

  • 输出文件

  • 模型参数和模型类型

  • 度量标准

你可以使用简单的共享文档来实现这一目标,或者将专门的实验跟踪框架与用户界面UI)集成到你的项目中。实验跟踪框架在需要大量实验的项目中能收回投资。

最后,要确保每个实验都可以重现,并记录你从结果中得出的结论。为了检查实验的可重现性,使用以下标准进行每个独立实验:

  • 输入数据易于访问,团队中的任何人都可以发现。

  • 实验代码可以在输入数据上运行而不出错。

  • 你无需输入未记录的配置参数即可运行实验。所有配置变量都在实验配置中固定。

  • 实验代码包含文档,并且易于阅读。

  • 实验输出是一致的。

  • 实验输出包含可以与其他实验进行比较的指标。

  • 实验结果的结论出现在文档、注释或输出文件中。

为了避免研究项目中的陷阱,请确保你做了以下事项:

  • 定义明确的目标

  • 定义成功标准

  • 定义约束条件,包括时间和预算限制

  • 填写实验待办事项

  • 根据预期进行优先级排序

  • 跟踪所有实验及其数据

  • 使代码具有可重复性

  • 记录你的发现

成功的研究项目可以帮助你找到复杂问题的答案,或推动科学领域和实践学科的边界。研究项目常常与原型混淆,尽管原型通常追求不同的目标。在接下来的部分,我们将探讨原型项目的特性,以及这些类型项目的具体管理策略。

处理原型和 MVP 项目

如果你从事数据科学工作,我敢打赌你会发现自己做了很多原型设计。原型通常有非常严格的时间和金钱限制。原型设计的第一课是将每个原型都视为 MVP。MVP 的核心理念是只包含足够的核心功能来展示一个可行的解决方案。其他附加功能可以稍后实现,只要你能够展示原型背后的核心思路。

聚焦核心功能并不意味着你的原型不能有漂亮的用户界面或令人惊叹的数据可视化。如果这些是你未来产品的主要优势,一定要包含它们。为了确定产品的核心功能,你应该从市场和流程的角度思考。

向自己提问以下问题,以检查某个特性是否应包含在 MVP 中:

  • 你的用户是谁?

  • 你的解决方案针对的是哪些(业务)流程?

  • 你想解决什么问题?

然后,看看哪些功能对于达到预期目标至关重要,哪些是附加的,哪些与目标无关。之后,观察你的竞争对手,思考是什么将使你的 MVP 与他们区别开来。如果你没有区别特征,或者你没有解决一个不同的问题,那么你将很难与一个已经开发且可能广泛采用的竞争性产品竞争。

将竞争对手的产品分解为功能列表并对其进行相同的分析,看看你应该实现哪些附加功能,以使你的产品与市场接轨。这种对竞争对手产品的详细功能分析更多的是关于产品开发,而不是创建 MVP,因此我们不会进一步深入探讨这个话题。

通过功能分析获得的信息,你应该能够对所有功能进行排序,并选择一些核心功能作为 MVP 的一部分。请记住,如果你知道某些功能对于成功至关重要,你可以调整它们的优先级。

交付 MVP 的另一个重要方面是削减成本。如果你有很多原型,使用项目模板、内部快速原型工具和文档模板将节省大量的时间和金钱。如果你发现你的团队在使用特定类型的算法或技术创建 MVP 时花费更多时间,可以考虑创建工具来自动化大部分工作。至关重要的是要记住,MVP 应该足够好,让你的客户和用户能够看到其好处。正如伏尔泰所说,完美是优秀的敌人

要更全面地了解如何创建可以转化为实际项目的原型,请参见第七章,创新管理

在下一部分,我们将简要概述如何在咨询公司环境中管理 MVP。

案例研究 – 在咨询公司中创建 MVP

我们的朋友 Mark 在一家咨询公司工作。他的团队为一家大型制造公司创建了一个缺陷检测系统原型。该系统应该分析传送带上产品的视频流,并检测出有缺陷的产品。Mark 已回答了初步的 MVP 问题清单:

  • 你的用户是谁?

    制造厂的产品质量部门。

  • 你的解决方案面向哪些(业务)流程?

    我们的目标是核心的产品质量控制过程。

  • 你想解决什么问题?

    我们希望减少当前质量控制过程中未检测到的有缺陷产品的总量。

基于这些答案,Mark 为 MVP 创建了核心功能清单:

  • 缺陷检测模型

  • 通过监控传送带上的摄像头进行集成

Mark 知道,制造计划主管 Anthony 是关键决策者,他欣赏那些界面简洁直观的系统。此外,Mark 还确信,准备一个模型质量报告对于比较现有和未来质量控制过程的效率至关重要。

这两条见解为 MVP 增加了一些交付物:

  • 用于实时监控缺陷的用户界面

  • 提供旧流程和改进流程之间效率对比的模型质量报告,以及自动化的质量控制步骤

在客户批准了项目范围后,Mark 决定使用 Scrum 作为管理方法,并专注于尽快交付第一个可工作的版本。为了尽快上手,Mark 的团队已经在应用计算机视觉算法方面积累了经验,因此他们使用了可以为快速原型开发而开发的内部软件库。报告模板使得他们不需要花费大量时间编写文档,从而能够专注于 MVP 开发。

本例总结了我们对原型的概述。现在,我们准备深入探讨数据科学项目中评估和减轻风险的话题。

减轻面向生产的数据科学系统中的风险

端到端数据科学项目涵盖了一个或多个完整的数据科学项目生命周期迭代。端到端的数据科学项目包括了研究项目和 MVP 的所有风险,以及与变更管理和生产部署相关的一系列新风险。

第一个主要风险是无法维持持续的变更流。数据科学项目涉及范围变更,您应该能够应对这些变更,而不让项目崩溃。Scrum 为您提供了变更管理所需的基本工具,通过在一周内冻结开发范围来应对变化。然而,任何工具的有效性都依赖于客户与您的团队共同理解并遵循必要的流程。

另一个问题是,给定变更的实施可能会导致许多意外的错误。数据科学项目通常缺乏自动化测试流程。缺乏对现有功能的持续测试,可能会在一个简单的变更引发多个错误时产生连锁反应。如果没有测试,许多错误也会被忽视,并且被直接推向生产环境。同样,实施在线测试模块也非常重要,因为质量保证不仅仅在开发阶段就结束。随着时间的推移,模型的性能可能会下降,您的系统应该监控业务和技术指标的突变。

如果您的团队没有提前为生产做好规划,您将面临许多与非功能性需求相关的复杂工程问题,例如系统的可用性、可扩展性和可靠性。为了避免这种情况,从项目一开始就应该关注系统设计和软件架构。

即使在技术上万事俱备,最终的结果也可能让客户感到困惑。如果关键利益相关者没有看到您的系统的价值,您必须检查目标定义中是否存在任何错误。通常情况下,项目目标会在中途发生变化,同时客户对于什么对他们的业务最好也可能会改变。为了避免这一重大风险,您应该不断检查自己正在做的任务是否重要,解决方法是否正确。

在下表中,我们列出了常见的风险及其解决方案,以总结本章内容:

风险组 风险 解决方案
常见问题 目标定义模糊。 确保目标的定义完整,并包含本章中清单上的所有项目。
常见问题 项目目标不可量化。 定义可以被客户理解的量化业务指标。定义一个或多个与业务指标相关联的技术指标。
常见问题 决策时没有记录跟踪。 记录下项目中做出的每一个重大决策和结论。固定数据和代码版本,以便能够重现导致这些决策的结果。
研究 团队无法重现实验结果。 跟踪实验结果和数据,以及代码。
研究 研究没有明确的范围和行动计划。 提前规划,使用研究待办事项列表。优先处理待办事项列表中的条目,并定期检查是否有过时条目需要移除。通过快速测试(如果可能的话)评估每个实验的期望值。
MVP 原型未能展示如何解决用户的问题。 将每个原型视为一个 MVP,旨在解决客户的问题。通过考虑解决客户问题所需的最少功能,来定义你的范围。
MVP MVP 包含过多不必要的功能,导致开发时间过长。 使用功能分析来定义 MVP 的范围。
MVP MVP 开发时间过长。 如果团队需要制作多个 MVP,考虑创建快速原型框架和项目模板,以加速开发过程。
项目开发 客户不断推动团队进行紧急的范围变更。 提倡为项目使用敏捷开发方法。跟踪项目范围变更,展示这些变更如何影响项目的截止日期。
项目开发 客户看不出系统如何解决他们的问题。 持续回顾项目目标,并确保你解决问题的方式已获得客户确认。
项目开发 新的变更引入了大量的 bug。 编写自动化测试。
生产部署 模型在生产环境中质量下降,且系统没有工具来解决这个问题。 开发在线测试模块以跟踪生产环境中的指标。验证输入数据。定期使用新数据重新训练模型。
生产部署 系统不适合用于生产环境。 修复系统的功能性和非功能性需求。准备一个架构愿景,以提供一个生产就绪的系统设计。

接下来我们将进入下一个案例研究,展示如何检测并控制这些常见风险。

案例研究——将销售预测系统投入生产

简在一家初创公司担任高级经理,该公司为全球各地的物流公司提供销售预测解决方案。在一次大型科技会议上,一家物流公司代表马克斯询问简的公司是否可以从使用 AI 中受益。简提到,仅仅依靠工具本身并不能让公司变得更好,AI 也是一种工具,就像他们的 ERP 软件一样,只是更加灵活。她首先通过创建更具体的任务定义,旨在消除风险表中常见风险组的风险:

简:那要不要设定一个更明确的目标呢?我知道没有了解 AI 和机器学习的技术细节可能很困难,所以让我来帮您。我们的公司为像您这样的物流公司提供销售预测解决方案。典型的应用场景是将我们的系统集成到您的 ERP 中,这样您的员工就不会浪费时间手动做预测了。这样听起来有兴趣吗?

马克斯:当然,能告诉我更多吗?

简:好的。我们的系统会为您仓库中的每个物品进行需求预测。我们可以估算出您需要在未来某个日期之前发货的物品数量。为此,我们需要访问您的 ERP 数据库。我敢打赌您的员工已经在做这项工作,但通常这个过程会花费很多时间,而且结果可能没有达到最准确,尤其是当您的产品目录包含数百或数千个物品时。

马克斯:是的,确实,这个过程需要很多时间。我们甚至在添加新项目到目录时遇到困难,因为这意味着未来我们需要雇佣两倍的人手。

简:如果我提供的内容对您感兴趣,我很乐意帮助您制作一个小型的 MVP 项目,展示我们的系统如何对您的业务带来好处。不过,我们需要您的协助。为了向您展示使用系统的积极效果,我们需要确保目标以公司管理层能理解的数字形式呈现。让我们安排一个会议,我可以向您展示我们如何量化项目结果,以及我们从您的 IT 专家那里需要什么支持。

马克斯:当然,谢谢!

在这次讨论后,简与马克斯举行了一次会议,向他展示了从业务角度评估项目表现的常见方法。她将所有决策记录在一份小型的业务需求文档中,并通过向马克斯展示,确认讨论的结果是正确的。简还讨论了 MVP 的成功标准。马克斯同意,在项目的这一阶段,生产部署不是必需的,他们可以通过查看简团队将在会议上展示的离线测试结果来决定是否进行生产集成。这样,她就涵盖了常见风险组中的所有三大风险。

由于这是一个 MVP 项目,她还考虑了 MVP 小组中的风险。简问了马克斯他们如何向最终用户和公司管理层展示这个系统,以便让他们理解这个系统的好处。他们决定将系统直接集成到公司的 ERP 解决方案中,因为这对双方来说是最具成本效益的方式。马克斯对 MVP 中可以包括哪些有用功能有很多想法,并且提到了可视化仪表板和系统管理工具。简注意到这些功能并没有增加系统的核心价值,更适合在实施阶段进行实现。

在明确了目标定义并塑造了 MVP 约束条件后,简的团队进入了实施阶段。为了关闭项目开发小组中的风险,简与客户协调了项目管理方法论。基于她的经验,简决定在这个 MVP 项目中使用 Scrum。她向客户解释了固定范围迭代的重要性,并确保每个人都同意如何在规划阶段将变更纳入冲刺中。她还使用软件项目管理系统与马克斯共享了项目的待办事项,以便他可以添加新的任务并与团队一起优先排序,充当产品负责人。简确保马克斯能有时间参与春季规划会议,以确保项目不会偏离方向。简所在初创公司的一般软件开发实践已经解决了与代码质量、交付管道自动化和自动化测试相关的风险,因此她不需要担心这些问题。

总结

在本章中,我们探讨了数据科学项目中的常见陷阱,以及如何使用实验待办事项和实验跟踪等工具来管理研究项目。我们还看到了原型与研究项目的区别,并从 MVP 的角度审视了如何管理原型开发。接着,这些技术通过一个关于咨询公司 MVP 开发的案例研究进行了总结。最后,我们列举并系统化了研究、原型和生产系统的主要风险及其解决方案。

在下一章中,我们将探讨如何通过使用可重用技术来发展数据科学产品并提高内部团队绩效。

第十章:创建产品和提高可复用性

本章将通过探讨如何帮助产品成长并提高可复用性来结束管理数据科学项目部分。本章关注那些为客户提供定制解决方案的团队。如果你的团队帮助公司内部的业务利益相关者或希望购买专业知识、服务和软件解决方案的外部客户,你会觉得本章的内容非常有用。产品思维和可复用性的好处在咨询阶段通常被低估,而如果你的团队正在开发一个专注于市场细分的产品,这些好处则变得更加明显。

在本章中,我们将讨论以下主题:

  • 将项目视为产品

  • 确定项目的阶段

  • 提高可复用性

  • 寻找和构建产品

将项目视为产品

要从本章的思想中获益,你必须将你的工作视为产品开发。尽管许多公司将软件产品交付市场,但你提供的是服务。我们可以将服务视为一种产品;它们同样遵循供求法则,并且不同类型的服务有各自的市场。

就像软件产品一样,你可以将你的活动拆解成服务特征。你团队擅长的服务方面将把你们的部门或公司与竞争对手区分开来,但你也可能会发现这些方面在其他专注于某一特定类型服务的组织中滞后。例如,一个数据科学咨询公司可能在创建定制模型方面表现突出,但他们的用户界面UIs)可能比专门从事 UI 开发的公司差。这些权衡是市场需求的合理反映:那些希望购买定制模型开发服务的公司,通常不需要同一团队来提供高端的 UI。

将服务视为产品开启了改进的新可能性。你可以分析你最佳的服务特性,并思考可以引入的改进,使你的服务变得更好、更有利可图,从而开启持续服务质量改进的新机遇。

在大多数情况下,最好的团队能在更短的时间内、更低的成本下交付更多功能,且其产品在可定制性和质量上优于那些面向更广泛市场优化的产品。作为服务提供者,你可以做一件产品无法做到的事:为客户的特定问题提供高度专业化的解决方案。问题是,我们如何在不失去提供定制解决方案的关键优势的同时,让定制解决方案更容易实现?

将项目视为产品的第一步是考虑项目的阶段。在接下来的部分,我们将从不同的项目类型和阶段来考虑可复用性的概念。

确定项目的阶段

要制定服务改进的行动计划,你需要确定你正在进行的项目的类型和阶段。我们可以将项目分为两个主要类别:

  • 产品

  • 定制解决方案

虽然产品天生是可重用的,但定制解决方案往往不是。然而,定制解决方案可以通过可重用的组件来构建,同时不失定制软件的特点。为了在每个项目阶段发展这些内部组件并提高重用性,你需要关注它们:

  • 最小可行产品MVP):思考你在之前的项目中可以重用的结果,同时尽可能少地投入时间。即使从零开始构建此功能看起来更容易,创建一个可重用组件也能在较长的时间跨度内为你节省更多的时间。

  • 开发:思考你在构建的系统中可以包含哪些可重用组件。决定你正在构建的新功能是否可以转化为可重用组件。

  • 生产:稳定并整合任何现有技术。

提高重用性的下一个重要步骤是管理研究。此时,问题出现了:我们如何决定一个项目何时需要一个研究阶段?首先,我们来看看在数据科学项目中可以做哪些类型的研究:

  • 数据:通过执行探索性数据分析EDA)来提升对客户数据的理解,并从数据中寻找洞察。

  • 模型和算法:改进你的模型并寻找解决问题的新方法。

  • 技术:研究新技术以改善你的解决方案。技术可以直接应用于你的项目,也可以通过改善操作、需求管理、代码或数据版本控制等来补充开发过程。

研究很难规划和估算,但它对成功完成数据科学项目至关重要。它为你打开新机遇,提供洞察并改变流程。找到研究与实施之间的正确平衡对项目成功至关重要。为了高效管理研究,你可以将项目分为两个逻辑子项目:研究和解决方案开发。

你可以通过多种方式将研究阶段整合到解决方案开发项目中,如下所示:

  • 与解决方案开发并行:这种方法需要一个全职的独立研究团队。它很有用,因为研究过程会在主项目的背景下提供结果。来自研究积压的那些取得良好成果的项目会被转化为主项目积压中的研究整合任务。此种研究管理方式对于数据和模型研究非常有用,因为这些活动通常需要较长时间才能完成,而且大多数情况下能够直接集成到主代码库中。

  • 每次开发迭代前或后:这种方法要求您的团队将注意力从解决方案开发转移到研究上,当研究的结果能够影响长期的系统构建方法时,这种方法最为有效。技术研究是这一整合方式的最佳候选。您可以将技术研究与软件设计阶段结合,使您的团队能够在受控的方式下将新技术集成到项目中。

总结一下,让我们看看如何将研究与实施结合起来。

案例研究 – 构建服务台路由系统

Lucas 在一家大型零售公司担任数据科学团队负责人。他的任务是构建一个系统,帮助减轻支持部门的负担,从而每天解决 1 万个零售店的问题。部门支持门户中的问题创建流程如下:

  1. 选择问题类别。

  2. 填写模板表单。

  3. 等待解决方案或信息查询。

  4. 如果您不知道问题类别,请在表单中选择"无分类",并在自由文本框中描述问题。

团队发现,"无分类"问题是支持团队最难且最耗时的解决问题类型。这是因为自由描述通常缺少模板要求的信息,因此支持工程师需要询问大量额外信息,以确定问题类别,并自己填写模板表单。解决思路是利用历史数据对即将到来的"无分类"问题进行分类,并在将问题发送给支持部门之前,要求用户填写模板所需的信息。

该项目面临两个主要挑战:

  • 构建一个能够处理大量问题分类(超过 1,000 个)的文本分类器

  • 创建一个能够可靠地在 24/7 时间内运行的分类系统,并将该系统与公司的支持门户进行集成

Lucas 认为,项目实际上包含两个子项目:研究和系统实施。研究项目没有固定的时间范围,需要团队中的数据科学家构建各种文本分类器并评估其质量。系统实施项目的主要目标是构建一个高可用性的模型服务器,并更改公司支持门户的代码,以便将该模型集成到问题创建工作流中。

Lucas 为每个项目创建了两个项目组,并为它们创建了独立的任务积压:

  • 研究团队:文本分类任务并不标准,也没有直接的解决方案,因为大多数预构建的文本分类模型只能处理非常有限的类别数量,而这个项目要求模型能稳定地处理 1000 个类别。研究团队有一个团队负责人,负责管理和优先排序研究任务,以便团队只关注最具成本效益和前景的想法。每个人都明白这项研究没有明确的截止日期,因此团队决定采用总体项目截止日期这一人为约束。目标是在时间限制和公司数据的前提下,训练出尽可能好的文本分类器。

  • 实施团队:他们专注于构建软件解决方案。团队由机器学习工程师、后端软件开发人员、UI 软件开发人员、系统分析员和团队负责人组成。Lucas 决定在这一部分项目中最好使用 Scrum 方法。团队讨论了截止日期,设定了固定数量的冲刺,并确保能够在时间框架内完成所有工作。从技术角度来看,这项任务很明确,不需要广泛的研究或原型设计。团队之前已经构建过模型服务器,因此他们决定重用现有的技术并添加一些缺失的功能。

最后一个悬而未决的问题是,如何将新的研究成果集成到系统中而不破坏现有系统。这个集成过程很容易成为项目的瓶颈,因为研究团队不断切换数据预处理方法和机器学习框架,以寻找最佳的项目结果。Lucas 决定,研究团队需要将他们的模型提供为一个具有固定接口的软件库,并且该接口需要与实施团队共同设计和文档化。这一接口将建立研究团队与实施团队之间的通信契约,以便通过简单地更新研究团队的库版本,便可更换新的模型版本。

在你决定了最佳的研究集成方式,并且理清了解决方案开发过程后,再考虑你可以从哪些可重用组件中受益,就可以继续前进,看看你的团队如何逐步提高交付技术的可重用性。

提高可重用性

提高可重用性是一个定制的项目开发设置,在该设置中,你可以开发并重用内部组件,从而更快速地构建更好的解决方案。看看你在所有项目中重复的部分。对许多公司来说,这通常是模型部署和服务;对于其他公司来说,则是构建基于模型的仪表盘。

将开源项目作为起点。在许多领域,最佳的工具通常由商业公司提供。幸运的是,数据科学社区是一个非常开放的群体,你能找到的最佳工具往往是开源的。当然,也有很棒的商业产品,但你可以通过开源解决方案构建出生产级系统,且这些系统使用的是最先进的模型。它们将为你提供一个非常坚实的基础。

看看你是否能利用这些工具来减少团队在不同项目中花费在类似重复活动上的总时间。如果你发现没有开源解决方案能够解决你的问题,那么你有两个选择:从零开始构建一个可重用的软件组件,或者购买一个产品。但如何选择购买一个现成的解决方案还是自己构建一个呢?预构建的产品最适合解决数据科学团队的常见问题。相反,定制内部的可重用解决方案应该留给那些对你的团队和公司来说是独特的过程部分。为了找到解决问题的方案,你应该首先考虑开源解决方案,其次是市场上的产品,最后考虑在内部构建新技术。

请记住,可重用的组件需要特别关注。随着工具链的增长,你的团队将需要投入更多时间来支持它。可重用工具需要设计能够经得起时间考验的 API 和工作流程。维护在多个项目中使用的可重用工具并不是一项容易的任务,但它将使你的团队能够在此基础上不断发展,从而使每一个后续项目都比前一个更加高效。

是构建还是购买? 你的团队常常会面临这个两难选择。你可以自己构建某些东西,使用开源解决方案,或者购买商业产品。这个决定从来不容易,并且会有长远的影响。从零开始自己构建需要大量的投资。你可以通过使用开源解决方案来节省成本,但你可能会遇到一些限制或漏洞,这些问题将迫使你的团队深入开发这个开源组件。尝试修复漏洞或为大量由全球各地的人编写的现有代码添加新功能,将需要大量的工程努力,并且会让切换到其他技术变得更加困难。商业产品是三者中最不具备定制性的,因此你的团队必须投入时间来决定哪个产品最符合你的需求。

如果你以分析的方式来处理这个决定,事情会变得更容易。定义成功标准,思考你打算构建、使用或购买的组件或技术的战略重要性。定义、记录并权衡所有的利弊,形成一个完整的视图。最后,与尽可能多的利益相关者讨论这个问题,包括你的团队成员和管理层。

可复用的组件可以让你的团队更加高效,而不会使解决方案过于通用,这样每个客户都能得到定制化服务。有时,你会发现一个机会,通过将高需求的定制解决方案转化为产品,可以让你的团队进入一个完全不同的商业模式。在接下来的章节中,我们将看到如何寻找和构建产品。

寻找和构建产品

随着时间的推移,团队会自然专注于开发你们可复用工具链中最复杂和最受欢迎的部分。如果你有一个经过多次项目考验且由经验丰富团队支持的可复用组件,值得考虑将其转化为产品。

另一个你应该将项目转化为产品的迹象是,有很高的需求要求你构建某种类型的定制解决方案。如果每个客户都要求你构建一个客户支持聊天机器人,而你已经做了几十个,为什么不做一个产品,方便大家的生活呢?

如果你的公司没有向市场交付新产品的经验,认真对待这个任务,并准备好进入一个全新的领域。如果你想避免犯错,花时间阅读与产品管理相关的文献,考虑聘请或咨询有相关经验的产品经理。产品开发与制作定制解决方案不同。实际上,这是一个完全不同的业务,拥有与咨询项目经理可能觉得奇怪的流程和价值观。

最后,请记住,构建产品是有风险且成本高昂的。产品团队需要付出大量努力,将任何内部代码库转化为市场-ready 产品。如果这个创意没有真正的市场需求,那么这项工作将是徒劳的。

从商业角度来看,好的产品创意非常有吸引力。然而,如果你为不同的客户提供服务,在将项目转化为面向广泛市场的产品之前,你应该始终考虑隐私问题。

隐私问题

对每个数据科学团队来说,隐私至关重要,特别是对于那些受到其他企业信任的团队。当你考虑基于自己的内部代码库或数据构建新产品时,务必检查你计划使用的所有内容是否可以出售给其他客户。如果不能,你可能最终需要从头开始构建产品,这将大大增加开发成本。请咨询公司法律团队,确保所有相关的保密协议(NDA)和合同允许计划中的使用场景。

你还需要考虑许可你的内部可复用组件,以便在不同项目中合法复用它们。本书不是法律顾问,如果你计划复用软件组件并构建产品,别犹豫,咨询专业的法律顾问。

总结

在本章中,我们探讨了在定制项目开发环境中产品思维的好处。我们研究了为什么可重用性如此重要,以及如何在数据科学项目的每个阶段构建和集成可重用的软件组件。我们还讨论了如何找到研究与实现之间的正确平衡。最后,我们探讨了提升项目可重用性的策略,并探索了基于经验构建独立产品的条件。

在本书的下一部分,我们将讨论如何构建开发基础设施,并选择一个能够简化数据科学项目开发和交付的技术栈。我们将从 ModelOps 入手,它是一套自动化模型交付流水线的实践方法。

第四部分:创建开发基础设施

在最后一部分,我们的目标是创建一个能够帮助实际用户的产品。通常,这意味着创建一款能够在高负载下稳定运行的生产环境中的软件。任何数据科学产品也是一种软件产品。团队可以使用现有的软件开发最佳实践来避免许多潜在问题。本部分将概述构建和部署数据科学解决方案所需的必备实践和工具。

本节包含以下章节:

  • 第十一章,实现 ModelOps

  • 第十二章,构建你的技术堆栈

  • 第十三章,结论

第十一章:实现 ModelOps

在本章中,我们将探讨 ModelOps 及其最亲近的“表亲”——DevOps。我们将研究如何为数据科学构建开发管道,使项目更加可靠,实验可以复现,部署更加快速。为此,我们将熟悉一般的模型训练管道,看看数据科学项目与软件项目在开发基础设施方面的不同。我们还将看看哪些工具可以帮助版本控制数据、跟踪实验、自动化测试并管理 Python 环境。通过使用这些工具,你将能够创建一个完整的 ModelOps 管道,自动化新模型版本的交付,同时保证可复现性和代码质量。

本章将涵盖以下主题:

  • 理解 ModelOps

  • 探索 DevOps

  • 管理代码版本和质量

  • 将数据与代码一起存储

  • 管理环境

  • 跟踪实验

  • 自动化测试的重要性

  • 持续模型训练

  • 为你的项目提供动力包

理解 ModelOps

ModelOps 是一组用于自动化数据科学项目中常见操作的实践,包括以下内容:

  • 模型训练管道

  • 数据管理

  • 版本控制

  • 实验跟踪

  • 测试

  • 部署

没有 ModelOps,团队将不得不在这些重复任务上浪费时间。每个任务本身相对容易处理,但项目可能会因为这些步骤中的错误而遭受影响。ModelOps 帮助我们创建像精密传送带一样运作的项目交付管道,并通过自动化测试程序来捕捉代码错误。

让我们从讨论 ModelOps 的最亲近“表亲”——DevOps 开始。

探索 DevOps

DevOps 代表 开发运维。软件开发过程包含许多重复且容易出错的任务,每次软件从源代码到达工作产品时,都需要执行这些任务。

让我们来看一下组成软件开发管道的一系列活动:

  1. 执行检查,查找错误、拼写错误、不良的编码习惯和格式化问题。

  2. 为一个或多个目标平台构建代码。许多应用程序应该在不同的操作系统上运行。

  3. 运行一系列测试,检查代码是否按要求正常工作。

  4. 打包代码。

  5. 部署打包好的软件。

持续集成与持续部署 (CI/CD) 表明所有这些步骤可以并且应该被自动化,并尽可能频繁地运行。经过充分测试的小更新更加可靠。如果一切出现问题,回退这样的更新要容易得多。在 CI/CD 之前,手动执行软件交付管道的软件工程师的吞吐量限制了部署周期的速度。

现在,高度可定制的 CI/CD 服务器使我们摆脱了手动操作,完全自动化了所有必要的活动。它们运行在源代码版本控制系统之上,并监控新的代码更改。一旦检测到新的代码更改,CI/CD 服务器就可以启动交付流水线。要实现 DevOps,您需要花时间编写自动化测试并定义软件流水线,但之后,流水线会每次都按需运行。

DevOps 在软件开发领域掀起了革命,推出了许多提高软件工程师生产力的技术。像任何技术生态系统一样,专家需要投入时间来学习并将所有工具整合在一起。随着时间的推移,CI/CD 服务器变得越来越复杂,功能越来越强大,许多公司意识到需要一位全职专家来管理他们项目的交付流水线。因此,出现了 DevOps 工程师这一角色。

来自 DevOps 世界的许多工具变得更加易于使用,只需要在用户界面中点击几下。一些 CI/CD 解决方案,如 GitLab,帮助您自动创建简单的 CI/CD 流水线。

CI/CD 基础设施的许多优势适用于数据科学项目;然而,许多领域仍然没有覆盖。在本章接下来的部分,我们将探讨数据科学项目如何使用 CI/CD 基础设施,以及您可以使用哪些工具来使数据科学项目交付的自动化更加完善。

探索数据科学项目基础设施的特殊需求

一个现代的软件项目可能会使用以下基础设施来实现 CI/CD:

  • 版本控制——Git

  • 代码协作平台——GitHub、GitLab

  • 自动化测试框架——取决于实现语言

  • CI/CD 服务器——Jenkins、Travis CI、Circle CI 或 GitLab CI

所有这些技术都缺少一些对数据科学项目至关重要的核心功能:

  • 数据管理——解决存储和版本控制大量数据文件问题的工具

  • 实验追踪——用于跟踪实验结果的工具

  • 自动化测试——测试数据密集型应用程序的工具和方法

在介绍解决前述问题的方案之前,我们将先了解数据科学交付流水线。

数据科学交付流水线

数据科学项目由多个相互依赖的数据处理流水线组成。以下图显示了数据科学项目的一般流水线:

我们快速总结一下前述图中的所有阶段:

  1. 每个模型流水线都以原始数据开始,这些数据存储在某种数据源中。

  2. 接着,数据科学家执行探索性数据分析EDA),并创建EDA 报告,以加深对数据集的理解并发现数据中的潜在问题。

  3. 数据处理管道将原始数据转换为一种中间格式,这种格式更适合创建用于训练、验证和测试模型的数据集。

  4. 模型数据集管道创建了用于训练和测试模型的现成数据集。

  5. 模型训练管道使用准备好的数据集来训练模型,通过离线测试评估其质量,并生成包含详细模型测试结果的模型质量报告

  6. 在管道的最后,您将获得最终的成果——一个训练好的模型,它被保存在硬盘或数据库中。

现在,我们可以开始讨论 ModelOps 的实施策略和示例工具。

管理代码版本和质量

数据科学项目涉及大量代码,因此数据科学家需要使用源代码版本控制SVC)系统,例如 Git,作为必不可少的组件。使用 Git 最直接的方式是采用像 GitLab 或 GitHub 这样的代码协作平台。这些平台提供了现成的 Git 服务器,并配有用于代码审查和问题管理的有用协作工具,使得在共享项目上工作更加便捷。这些平台还与 CI/CD 解决方案集成,创建了一个完整且易于配置的软件交付管道。GitHub 和 GitLab 是免费使用的,而且 GitLab 支持本地安装,因此您的团队没有理由错过使用这些平台的好处。

许多团队将 Git 与流行的平台产品同义,但有时了解它并不是唯一的选择也很有用。有时,您无法访问互联网或在服务器上安装额外软件,但仍希望在共享仓库中存储代码。即便在这些受限环境中,您仍然可以使用 Git。Git 有一个非常有用的功能叫做文件远程,它允许您将代码推送到几乎任何地方。

例如,您可以使用 USB 闪存驱动器或共享文件夹作为远程仓库:

git clone --bare /project/location/my-code /remote-location/my-code #copy your code history from a local git repo
git remote add usb file:///remote/location/my-code 
# add your remote as a file location
git remote add usb file:///remote/location/my-code 
# add your remote as a file location
git push usb master 
# push the code

# Done! Other developers can set up your remote and pull updates:
git remote add usb file:///remote/location/my-code # add your remote as a file location
git pull usb mater # pull the code

通过将file:///路径更改为ssh:///路径,您还可以将代码推送到本地网络上的远程 SSH 机器。

大多数数据科学项目都是用 Python 编写的,而静态代码分析和代码构建系统在其他编程语言中更为普及。这些工具可以在每次尝试构建项目时自动修整代码,并检查关键错误和潜在的漏洞。Python 也有这样的工具——例如 pre-commit(pre-commit.com)。

以下截图演示了在 Python 代码仓库上运行 pre-commit 的情况:

在介绍了处理代码的主要建议之后,接下来我们来看一下如何为数据实现相同的效果,数据是任何数据科学项目的核心部分。

将数据与代码一起存储

正如您先前所见,我们可以将数据科学项目中的代码结构化为一组生成各种工件(报告、模型和数据)的管道。不同版本的代码会产生不同的输出,数据科学家经常需要复现结果或使用过去版本管道的工件。

这将数据科学项目与软件项目区分开来,并创建了管理数据版本的需求,以及与代码一起使用的数据版本控制DVC)。一般来说,可以仅通过源代码重构不同的软件版本,但对于数据科学项目来说,这是不够的。让我们看看当您尝试使用 Git 跟踪数据集时会遇到什么问题。

跟踪和版本控制数据

为了训练和切换您的数据科学管道的每个版本,您应该跟踪数据变化以及代码。有时,一个完整的项目管道可能需要几天的计算时间。您应该存储和记录项目的不仅是输入,还有中间数据集,以节省时间。从单个数据集创建多个模型训练管道而无需每次都等待数据集管道完成非常方便。

结构化管道和中间结果是一个值得特别关注的有趣话题。您项目的管道结构决定了可以用于使用的中间结果。每个中间结果都创建了一个分支点,从中可以启动几个其他管道。这创造了重复使用中间结果的灵活性,但以存储和时间为代价。具有许多中间步骤的项目可能会消耗大量磁盘空间,并且计算时间更长,因为磁盘输入/输出需要大量时间。

请注意,模型训练管道和生产管道应该是不同的。模型训练管道可能有很多中间步骤,以提供研究灵活性,但生产管道应高度优化以提高性能和可靠性。只有执行最终生产管道所需的严格必要的中间步骤才需要执行。

存储数据文件对于复现结果是必要的,但不足以理解结果。通过记录数据描述以及所有包含团队从数据中得出的总结和结论的报告,您可以节省大量时间。如果可能的话,将这些文档存储为简单的文本格式,以便它们可以与相应的代码一起轻松跟踪在您的版本控制系统中。

您可以使用以下文件夹结构存储项目中的数据:

  • 项目根目录:

    • 数据:

      • 原始——来自您的客户的原始数据

      • 中间——处理管道生成的中间数据

      • 预处理——模型数据集或输出文件

    • 报告——项目的探索性数据分析报告,模型质量等

    • 引用——数据字典和数据源文档

存储实践中的数据

我们已经探讨了为什么将数据工件与代码一起存储和管理很重要,但并没有讨论如何在实践中实现这一点。像 Git 这样的代码版本控制系统并不适合这个用例。Git 是专门为存储源代码变更而开发的。在 Git 内部,每个变更都作为一个 diff 文件存储,表示源代码文件中发生变化的行。

你可以在以下截图中看到一个简单的 diff 文件示例:

高亮的以 + 标记的行表示添加的行,而以 – 标记的行表示删除的行。在 Git 中添加大型二进制或文本文件被认为是不好的做法,因为它会导致大量冗余的 diff 计算,从而使得仓库变得缓慢且体积庞大。

diff 文件解决了一个非常特定的问题:它们允许开发者浏览、讨论并在一组变更之间切换。diff 是一种基于行的格式,针对的是文本文件。相反,二进制数据文件中的小改动会导致完全不同的数据文件。在这种情况下,Git 会为每个小的数据修改生成庞大的 diff 文件。

通常,你不需要浏览或讨论数据文件中的行级变更,因此为每个新版本的数据计算并存储 diff 文件是没有必要的:每次数据文件发生变化时,存储整个数据文件要简单得多。

对数据版本控制系统的需求不断增长,产生了几种技术解决方案,其中最流行的是 GitLFS 和 DVC。GitLFS 允许你在 Git 中存储大文件而不会生成庞大的 diff 文件,而 DVC 则进一步扩展,允许你将数据存储在多个远程位置,例如 Amazon S3 存储或远程 SSH 服务器。DVC 不仅实现了数据版本控制,还允许你通过捕获代码及其输入数据、输出文件和指标来创建自动化的可复现流水线。DVC 还处理流水线的依赖图,从而可以自动查找并执行流水线的任何先前步骤,以生成你需要的输入文件来支持代码的执行。

现在我们已经配备了处理数据存储和版本控制的工具,接下来让我们看看如何管理 Python 环境,以便你的团队不会在服务器上浪费时间处理包冲突。

管理环境

数据科学项目依赖于许多开源库和工具来进行数据分析。这些工具中的许多都在不断更新新功能,而这些更新有时会破坏 API。固定所有依赖项并以共享格式存储非常重要,这样每个团队成员就能使用相同的版本并构建库。

Python 生态系统中有多个环境管理工具,用于解决不同的问题。这些工具的使用场景有重叠,因此在选择时常常让人困惑,我们将简要介绍每个工具:

  • pyenv (github.com/pyenv/pyenv) 是一个用于在单台机器上管理 Python 发行版的工具。不同的项目可能使用不同的 Python 版本,pyenv 允许你在项目之间切换不同的 Python 版本。

  • virtualenv (virtualenv.pypa.io) 是一个用于创建包含不同 Python 包集合的虚拟环境的工具。虚拟环境在不同项目之间切换时非常有用,因为这些项目可能需要使用不同版本的 Python 包,这些包可能存在冲突。

  • pipenv (pipenv-searchable.readthedocs.io) 是虚拟环境的一个高级工具。Pipenv 的主要功能是自动为项目创建一个可共享的虚拟环境,其他开发人员可以轻松使用。

  • Conda (www.anaconda.com/distribution/) 是另一个像 pipenv 一样的环境管理工具。Conda 在数据科学社区中很受欢迎,原因有几个:

    • 它允许通过environment.yml文件与其他开发人员共享环境。

    • 它提供了 Anaconda Python 发行版,其中包含大量预安装的流行数据科学包。

    • 它提供了对流行的数据分析和机器学习库的高度优化版本。科学 Python 包通常需要从源代码构建依赖项。

    • Conda 可以与您喜爱的深度学习框架一起安装 CUDA 框架。CUDA 是一个专用的计算库,优化深度神经网络在 GPU 上的性能时是必需的。

如果你还没有使用 conda 来管理数据科学项目环境,建议考虑使用它。它不仅可以解决环境管理问题,还能通过加速计算节省时间。以下图表显示了使用pipconda安装 TensorFlow 库的性能差异(你可以通过以下链接找到原始文章:www.anaconda.com/tensorflow-in-anaconda/):

接下来,我们将讨论实验跟踪的话题。实验是每个数据科学项目中的自然组成部分。单个项目可能包含数百甚至数千个实验结果。记录实验结果非常重要,这样你才能得出正确的结论。

实验跟踪

实验是数据科学的核心。数据科学家进行许多实验,以找到解决手头任务的最佳方法。通常,实验是与数据处理管道步骤相关的一组操作。

例如,你的项目可能包括以下实验集:

  • 特征工程实验

  • 不同机器学习算法的实验

  • 超参数优化实验

每个实验可能会影响其他实验的结果,因此能够在隔离环境中复现每个实验至关重要。跟踪所有结果也非常重要,这样你的团队可以比较管道的不同版本,并根据指标值选择最适合你项目的版本。

一个简单的电子表格文件,包含数据文件和代码版本的链接,可以用来跟踪所有实验,但复现实验将需要大量的手动工作,且不能保证按预期工作。尽管使用文件跟踪实验需要手动操作,但这种方法也有其优点:它非常容易上手,而且版本控制也很方便。例如,你可以将实验结果存储在一个简单的 CSV 文件中,并将其与代码一起在 Git 中进行版本控制。

一份推荐的指标跟踪文件的最小列集如下:

  • 实验日期

  • 代码版本(Git 提交哈希)

  • 模型名称

  • 模型参数

  • 训练数据集大小

  • 训练数据集链接

  • 验证数据集大小(交叉验证的折数)

  • 验证数据集链接(交叉验证没有)

  • 测试数据集大小

  • 测试数据集链接

  • 指标结果(每个指标一列;每个数据集一列)

  • 输出文件链接

  • 实验描述

如果实验数量适中,文件处理起来相对简单,但如果你的项目使用了多个模型,并且每个模型都需要大量的实验,使用文件就变得非常繁琐。如果一组数据科学家同时进行实验,跟踪每个团队成员的文件就需要手动合并,而数据科学家更应该把时间花在进行更多实验上,而不是合并其他团队成员的结果。对于更复杂的研究项目,存在专门的实验结果跟踪框架。这些工具可以集成到模型训练管道中,允许你自动将实验结果跟踪到共享数据库中,这样每个团队成员都可以专注于实验工作,而所有的记录工作会自动完成。这些工具提供了丰富的用户界面,可以用来搜索实验结果、浏览指标图表,甚至存储和下载实验工件。使用实验跟踪工具的另一个好处是,它们能够跟踪许多可能会用得上的技术信息,但这些信息手动收集起来非常繁琐:服务器资源、服务器主机名、脚本路径,甚至实验运行时的环境变量。

数据科学社区使用三种主要的开源解决方案来跟踪实验结果。这些工具提供的功能远超实验跟踪,我们将简要介绍每一种:

  • Sacred:这是一个具有模块化架构的高级实验追踪服务器。它提供一个 Python 框架用于管理和追踪实验,可以轻松集成到现有的代码库中。Sacred 还提供多个用户界面,供您的团队浏览实验结果。在所有其他解决方案中,只有 Sacred 专注于实验追踪。它捕捉到最广泛的信息集,包括服务器信息、指标、工件、日志,甚至是实验源代码。Sacred 提供了最完整的实验追踪体验,但它的管理较为困难,因为它需要您设置一个单独的追踪服务器,并且该服务器必须始终在线。如果没有访问追踪服务器的权限,您的团队将无法追踪实验结果。

  • MLflow:这是一个实验框架,允许追踪实验、提供模型服务以及管理数据科学项目。MLflow 易于集成,可以在客户端-服务器架构或本地环境中使用。它的追踪功能稍微落后于 Sacred 的强大功能,但对于大多数数据科学项目来说已经足够。MLflow 还提供从模板启动项目的工具,并将训练好的模型作为 API 提供,这为发布实验结果作为生产就绪服务提供了一个快速的途径。

  • DVC:这是一个用于数据版本控制和管道管理的工具包。它还提供基本的基于文件的实验追踪功能,但在可用性方面,DVC 与 MLflow 和 Sacred 相比有所不足。DVC 的强大之处在于实验管理:它允许您创建完全版本化和可重现的模型训练管道。使用 DVC,每个团队成员都能从服务器拉取代码、数据和管道,并通过一个命令重现结果。DVC 有相当陡峭的学习曲线,但值得学习,因为它解决了数据科学项目协作中出现的许多技术问题。如果您的指标追踪需求较简单,可以依赖 DVC 的内建解决方案,但如果您需要更丰富和可视化的功能,可以将 DVC 与 MLflow 或 Sacred 追踪结合使用——这些工具并不互相排斥。

现在,您应该对可以在项目中将代码、数据和实验作为一个整体来追踪的工具有了完整的了解。接下来,我们将讨论数据科学项目中的自动化测试主题。

自动化测试的重要性

在软件工程项目中,自动化测试被认为是强制性的。软件代码的轻微变化可能会在其他部分引入无意的 bug,因此尽可能频繁地检查一切是否按预期工作非常重要。用编程语言编写的自动化测试允许你多次测试系统。CI(持续集成)原则建议在每次代码变更推送到版本控制系统时运行测试。所有主要编程语言都有多种测试框架。开发者可以利用它们为产品的后端和前端部分创建自动化测试。大型软件项目可能包含成千上万的自动化测试,每次有人修改代码时都会运行这些测试。测试可能会消耗大量资源,并且需要很长时间才能完成。为了解决这个问题,CI 服务器可以在多台机器上并行运行测试。

在软件工程中,我们可以将所有的测试分为一个层次结构:

  1. 端到端测试对系统的一个主要功能进行全面检查。在数据科学项目中,端到端测试可以使用完整的数据集来训练模型,并检查度量值是否满足最低的模型质量要求。

  2. 集成测试检查系统的每个组件是否按预期一起工作。在数据科学系统中,集成测试可能会检查模型测试管道的所有步骤是否都成功完成,并提供期望的结果。

  3. 单元测试检查单个类和函数。在数据科学项目中,单元测试可以检查数据处理管道步骤中单个方法的正确性。

如果软件测试的世界如此技术先进,数据科学项目能从自动化测试中获益吗?数据科学代码与软件测试代码的主要区别在于数据的可靠性。对于大多数软件项目,测试运行前生成的固定测试数据集已足够。数据科学项目则不同。为了对模型训练管道进行完整测试,可能需要数 GB 的数据。一些管道可能需要运行几个小时甚至几天,并且需要分布式计算集群,因此对它们进行测试变得不切实际。因此,许多数据科学项目避免使用自动化测试。这样,它们就会遭遇意外的 bug、涟漪效应和缓慢的变更集成周期。

涟漪效应是软件工程中的常见问题,当系统的某一部分发生轻微变化时,可能会以意想不到的方式影响其他组件,从而引发 bug。自动化测试是一种高效的解决方案,可以在涟漪效应造成实际损害之前发现它们。

尽管存在困难,自动化测试的好处是不可忽视的。忽视测试的代价远比构建它们要高。这对于数据科学项目和软件项目都适用。自动化测试的好处随着项目规模、复杂性和团队人数的增加而增长。如果你领导一个复杂的数据科学项目,考虑将自动化测试作为项目的强制性要求。

让我们来看一下如何处理数据科学项目的测试。模型训练管道的端到端测试可能不切实际,但测试单个管道步骤如何?除了模型训练代码外,每个数据科学项目都会有一些业务逻辑代码和数据处理代码。这些代码大多数可以从分布式计算框架中抽象出来,放入易于测试的独立类和函数中。

如果你从一开始就将项目的代码架构与测试考虑在内,那么自动化测试将变得更加容易。团队中的软件架构师和首席工程师应将代码的可测试性作为代码审查的主要验收标准之一。如果代码得到了恰当的封装和抽象,测试就会变得更加简单。

尤其是,让我们看一下模型训练管道。如果我们将其分为一系列具有明确定义接口的步骤,那么我们就可以将数据预处理代码与模型训练代码分开进行测试。如果数据预处理需要大量时间并且需要昂贵的计算资源,至少可以测试管道的各个部分。即使是基本的函数级测试(单元测试)也能为你节省大量时间,而且从单元测试基础上过渡到完整的端到端测试会变得更加容易。

为了在项目中受益于自动化测试,请从以下准则开始:

  • 为更好的可测试性构建你的代码架构。

  • 从小做起;编写单元测试。

  • 考虑构建集成测试和端到端测试。

  • 坚持下去。记住,测试能节省时间——尤其是当你的团队需要修复新部署的代码中的意外漏洞时。

我们已经了解了如何管理、测试和维护数据科学项目中的代码质量。接下来,让我们看看如何打包代码以进行部署。

打包代码

在为数据科学项目部署 Python 代码时,你有几个选择:

  • 常规 Python 脚本:你只是将一堆 Python 脚本部署到服务器并运行。这是最简单的部署方式,但需要大量的手动准备:你需要安装所有必需的包,填写配置文件,等等。虽然可以通过使用像 Ansible (www.ansible.com/)) 这样的工具来自动化这些操作,但除非是最简单且没有长期维护需求的项目,否则不建议使用这种部署方式。

  • Python 包:使用setup.py文件创建 Python 包是一种更加便捷的打包 Python 代码的方式。像 PyScaffold 这样的工具提供了现成的 Python 包模板,因此你无需花费太多时间在项目结构的搭建上。在 Python 包的情况下,Ansible 仍然是自动化手动部署操作的可行选择。

  • Docker 镜像:Docker(www.docker.com/)基于一种名为 Linux 容器的技术。Docker 允许将你的代码打包成一个隔离的可移植环境,可以轻松地在任何 Linux 机器上进行部署和扩展。它就像是将你的应用程序连同所有依赖项(包括 Python 解释器、数据文件和操作系统分发版)一起打包、运输并运行,而无需进入重量级虚拟机的世界。Docker 通过从一组在Dockerfile中指定的命令构建Docker 镜像来工作。Docker 镜像的运行实例称为Docker 容器

现在,我们准备好将所有用于处理代码、数据、实验、环境、测试、打包和部署的工具,集成到一个单一、连贯的流程中,以交付机器学习模型。

持续模型训练

将 CI/CD 应用于数据科学项目的最终目标是拥有一个持续学习的流程,能够自动创建新的模型版本。这种自动化的程度将使团队能够在推送代码变更后,立即检查新的实验结果。如果一切如预期工作,自动化测试完成,并且模型质量报告显示良好的结果,则该模型可以部署到在线测试环境中。

让我们描述持续模型学习的步骤:

  1. CI:

    1. 执行静态代码分析。

    2. 启动自动化测试。

  2. 持续模型学习:

    1. 获取新数据。

    2. 生成 EDA 报告。

    3. 启动数据质量测试。

    4. 执行数据处理并创建训练数据集。

    5. 训练新模型。

    6. 测试模型质量。

    7. 修复实验日志中的实验结果。

  3. CD:

    1. 打包新的模型版本。

    2. 打包源代码。

    3. 将模型和代码发布到目标服务器。

    4. 启动新版本的系统。

CI/CD 服务器可以自动化处理前述流程中的所有部分。CI/CD 步骤应当容易操作,因为它们正是 CI/CD 服务器创建的目的。持续模型学习也不应当困难,只要你结构化你的流程,以便可以从命令行自动启动。像 DVC 这样的工具可以帮助你创建可重现的流程,使其成为持续模型学习流程的一个有吸引力的解决方案。

现在,让我们看看如何在数据科学项目中构建一个 ModelOps 流程。

案例研究 – 为预测性维护系统构建 ModelOps

Oliver 是一家大型制造公司 MannCo 的数据科学项目团队负责人,MannCo 的工厂遍布全国多个城市。Oliver 的团队开发了一种预测性维护模型,帮助 MannCo 预测并防止昂贵的设备故障,这些故障会导致高额的维修费用和生产线长时间停工。该模型以多个传感器的测量值为输入,输出一个包概率,可以用来规划诊断和修复会话。

这个示例包含了一些技术细节。如果你不熟悉案例中提到的技术,可以点击链接以便更好地理解细节。

这些设备每一台都有其独特性,因为它们在 MannCo 各个工厂的不同环境下运行。这意味着 Oliver 的团队需要不断调整和重新训练针对不同工厂的独立模型。让我们来看一下他们是如何通过构建一个 ModelOps 流水线来解决这一任务的。

团队中有多位数据科学家,因此他们需要一个工具来共享代码。客户要求出于安全考虑,所有代码必须存储在公司本地服务器中,而不是云端。Oliver 决定使用 GitLab(about.gitlab.com/),因为这是公司的一般做法。在整体代码管理流程方面,Oliver 建议使用 GitFlow(danielkummer.github.io/git-flow-cheatsheet/)。它为每个团队成员提供了一套统一的规则,用于创建新功能、发布版本和修复热修复。

Oliver 知道,一个可靠的项目结构将帮助他的团队妥善组织代码、笔记本、数据和文档,因此他建议团队使用 PyScaffold(pyscaffold.readthedocs.io/)以及数据科学项目插件(github.com/pyscaffold/pyscaffoldext-dsproject)。PyScaffold 让他们能够引导一个项目模板,确保以统一的方式存储和版本化数据科学项目。PyScaffold 已经提供了environment.yml文件,用于定义一个模板 Anaconda(www.anaconda.com/distribution/)环境,因此团队从项目开始就没有忘记锁定包的依赖关系。Oliver 还决定使用 DVC(dvc.org/)通过公司的内部 SFTP 服务器来版本化数据集。他们还使用了--gitlab标志来运行pyscaffold命令,这样当他们需要时就可以得到一个现成的 GitLab CI/CD 模板。

项目结构如下所示(摘自pyscaffold-dsproject文档):

├── AUTHORS.rst <- List of developers and maintainers.
├── CHANGELOG.rst <- Changelog to keep track of new features and fixes.
├── LICENSE.txt <- License as chosen on the command-line.
├── README.md <- The top-level README for developers.
├── configs <- Directory for configurations of model & application.
├── data
│ ├── external <- Data from third party sources.
│ ├── interim <- Intermediate data that has been transformed.
│ ├── processed <- The final, canonical data sets for modeling.
│ └── raw <- The original, immutable data dump.
├── docs <- Directory for Sphinx documentation in rst or md.
├── environment.yaml <- The conda environment file for reproducibility.
├── models <- Trained and serialized models, model predictions,
│ or model summaries.
├── notebooks <- Jupyter notebooks. Naming convention is a number (for
│ ordering), the creator's initials and a description,
│ e.g. `1.0-fw-initial-data-exploration`.
├── references <- Data dictionaries, manuals, and all other materials.
├── reports <- Generated analysis as HTML, PDF, LaTeX, etc.
│ └── figures <- Generated plots and figures for reports.
├── scripts <- Analysis and production scripts which import the
│ actual PYTHON_PKG, e.g. train_model.
├── setup.cfg <- Declarative configuration of your project.
├── setup.py <- Use `python setup.py develop` to install for development or
| or create a distribution with `python setup.py bdist_wheel`.
├── src
│ └── PYTHON_PKG <- Actual Python package where the main functionality goes.
├── tests <- Unit tests which can be run with `py.test`.
├── .coveragerc <- Configuration for coverage reports of unit tests.
├── .isort.cfg <- Configuration for git hook that sorts imports.
└── .pre-commit-config.yaml <- Configuration of pre-commit git hooks.

项目团队很快发现,他们需要执行并比较许多实验,以便为不同的制造工厂构建模型。他们评估了 DVC 的度量跟踪功能。该功能允许使用 Git 中的简单版本化文本文件跟踪所有度量。虽然这个功能对于简单的项目来说很方便,但在多个数据集和模型的项目中使用会变得很困难。最终,他们决定使用一个更先进的度量跟踪器——MLflow(mlflow.org)。它提供了一个方便的 UI,用于浏览实验结果,并允许使用共享数据库,以便每个团队成员都能快速与团队分享他们的结果。MLflow 作为常规 Python 包安装和配置,因此它可以轻松集成到现有的技术栈中:

团队还决定利用 DVC 管道,使每个实验都能轻松重现。团队喜欢使用 Jupyter notebooks 来原型化模型,因此他们决定使用 papermill(papermill.readthedocs.io/en/latest/)来处理 notebooks,因为它们是参数化的 Python 脚本集。Papermill 允许从命令行执行 Jupyter notebooks,而无需启动 Jupyter 的 Web 界面。团队发现这个功能与 DVC 管道一起使用时非常方便,但运行单个 notebook 的命令行开始变得太长:

dvc run -d ../data/interim/ -o ../data/interim/01_generate_dataset -o ../reports/01_generate_dataset.ipynb papermill --progress-bar --log-output --cwd ../notebooks ../notebooks/01_generate_dataset.ipynb ../reports/01_generate_dataset.ipynb

为了解决这个问题,他们编写了一个 Bash 脚本,将 DVC 与 papermill 集成,以便团队成员能够通过更少的终端输入来创建可重现的实验:

#!/bin/bash
set -eu
​
if [ $# -eq 0 ]; then
 echo "Use:"
 echo "./dvc-run-notebook [data subdirectory] [notebook name] -d [your DVC dependencies]"
 echo "This script executes DVC on a notebook using papermill. Before running create ../data/[data subdirectory] if it does not exist and do not forget to specify your dependencies as multiple last arguments"
 echo "Example:"
 echo "./dvc-run-notebook interim ../notebooks/02_generate_dataset.ipynb -d ../data/interim/"
 exit 1
fi
​
NB_NAME=$(basename -- "$2")
​
CMD="dvc run ${*:3} -o ../data/$1 -o ../reports/$NB_NAME papermill --progress-bar --log-output --cwd ../notebooks ../notebooks/$NB_NAME ../reports/$NB_NAME"
​
echo "Executing the following DVC command:"
echo $CMD
$CMD 

在一个项目中使用多个开源 ModelOps 工具时,你的团队可能需要花一些时间将它们集成在一起。要做好准备,并合理规划。

随着时间的推移,代码的一些部分开始在 notebooks 中重复。PyScaffold 模板通过将重复的代码封装在项目的包目录 src 中,提供了解决此问题的方法。这样,项目团队可以快速在 notebooks 之间共享代码。为了在本地安装项目包,他们只需从项目的根目录使用以下命令:

pip install -e .

临近项目发布日期时,所有稳定的代码库都迁移到了项目的 srcscripts 目录中。scripts 目录包含一个用于训练新模型版本的单一入口脚本,模型输出到 models 目录中,DVC 跟踪该目录。

为了确保新的更改没有破坏任何重要功能,团队编写了一套使用pytestdocs.pytest.org/)的自动化测试,针对稳定的代码库。测试还检查了团队创建的一个特殊测试数据集上的模型质量。Oliver 修改了由 PyScaffold 生成的 GitLab CI/CD 模板,以确保每次新的提交推送到 Git 仓库时都会运行测试。

客户要求一个简单的模型 API,因此团队决定使用 MLflow 服务器(mlflow.org/docs/latest/models.html),因为 MLflow 已经集成到项目中。为了进一步自动化部署和打包过程,团队决定将 Docker 与 GitLab CI/CD 一起使用。为此,他们按照 GitLab 的指南来构建 Docker 镜像(docs.gitlab.com/ee/ci/docker/using_docker_build.html)。

项目整体的 ModelOps 流程包含以下步骤:

  1. 在代码中创建新的更改。

  2. 运行由 PyScaffold 提供的代码质量和风格检查的 pre-commit 测试。

  3. 在 GitLab CI/CD 中运行 pytest 测试。

  4. 在 GitLab CI/CD 中将代码和训练好的模型打包成 Docker 镜像。

  5. 将 Docker 镜像推送到 GitLab CI/CD 中的 Docker 镜像库。

  6. 在 GitLab UI 中手动确认后,运行update命令在客户的服务器上。这条命令将新版本的 Docker 镜像从镜像库推送到客户的服务器,并运行新版本的镜像来替代旧版本。如果你想了解如何在 GitLab CI/CD 中实现这一操作,可以查看这里:docs.gitlab.com/ee/ci/environments.html#configuring-manual-deployments

请注意,在实际项目中,你可能希望将部署过程拆分成多个阶段,至少包括两个不同的环境:预发布环境和生产环境。

创建端到端的 ModelOps 流水线简化了部署过程,并且让团队能够在代码进入生产环境之前发现 BUG,这样团队就能专注于构建模型,而不是执行重复的测试和部署新版本模型的操作。

本章的结论部分,我们将查看一份可以帮助你构建 ModelOps 流水线的工具清单。

你的项目的强大工具包

数据科学社区有大量开源工具可以帮助你构建 ModelOps 流水线。有时,面对无尽的产品、工具和库清单会感到困惑,因此我认为这份工具清单会对你的项目有所帮助并且富有价值。

关于 Python 的静态代码分析,参见以下内容:

这里是一些有用的 Python 工具:

  • PyScaffold (pyscaffold.readthedocs.io/)—一个项目模板引擎。PyScaffold 可以为你设置项目结构。dsproject 扩展(github.com/pyscaffold/pyscaffoldext-dsproject)包含一个很好的数据科学项目模板。

  • pre-commit (pre-commit.com)—一个允许你设置 Git 钩子的工具,每次提交代码时都会运行。自动格式化、风格检查、代码格式化以及其他工具可以在你决定使用 CI/CD 服务器之前集成到构建流水线中。

  • pytest (docs.pytest.org/)—一个 Python 测试框架,允许你使用可重用的 fixture 组织测试。在测试有许多数据依赖关系的数据科学流水线时,它非常有用。

  • Hypothesis (hypothesis.works)—一个 Python 的模糊测试框架,可以基于你的函数的元数据创建自动化测试。

对于 CI/CD 服务器,参考以下内容:

  • Jenkins (jenkins.io)—一个流行、稳定且历史悠久的 CI/CD 服务器解决方案。它包含许多功能,但与一些现代工具相比,使用起来有些笨重。

  • GitLab CI/CD (docs.gitlab.com/ee/ci/)—一个免费的 CI/CD 服务器,提供云端和本地部署选项。它易于设置和使用,但迫使你生活在 GitLab 的生态系统中,虽然这可能不是一个坏决定,因为 GitLab 是最好的协作平台之一。

  • Travis CI (travis-ci.org) 和 Circle CI (circleci.com)—云 CI/CD 解决方案。如果你在云环境中开发,这些非常有用。

对于实验跟踪工具,参考以下内容:

对于数据版本控制,参考以下内容:

  • DVC (dvc.org/)—用于数据科学项目的数据版本控制工具

  • GitLFS (git-lfs.github.com)—一个通用的解决方案,用于在 Git 中存储大文件

对于流水线工具,参考以下内容:

对于代码协作平台,参考以下内容:

  • GitHub (github.com/)—世界上最大的开源代码库,也是最好的代码协作平台之一

  • GitLab (about.gitlab.com)—功能丰富的代码协作平台,提供云端和本地部署选项

  • Atlassian Bitbucket (bitbucket.org/)—来自 Atlassian 的代码协作解决方案,能够与其其他产品如 Jira 问题追踪器和 Confluence Wiki 良好集成

关于部署代码,请参考以下内容:

  • Docker (www.docker.com/)—一个用于管理容器并将代码打包到一个独立的可移植环境中的工具,这些环境可以轻松地在任何 Linux 机器上进行部署和扩展

  • Kubernetes (kubernetes.io/)—一个容器编排平台,自动化容器化应用程序的部署、扩展和管理

  • Ansible (www.ansible.com/)—一款配置管理和自动化工具,对于不使用容器的部署环境,部署自动化和配置管理非常实用

摘要

在本章中,我们介绍了 ModelOps —— 一套用于自动化数据科学项目中常见操作的实践方法。我们探讨了 ModelOps 与 DevOps 的关系,并描述了 ModelOps 流水线中的主要步骤。我们讨论了管理代码、版本控制数据以及在团队成员之间共享项目环境的策略。我们还研究了实验跟踪和自动化测试在数据科学项目中的重要性。最后,我们概述了完整的 CI/CD 流水线与持续模型训练,并探索了一套可用于构建此类流水线的工具。

在下一章中,我们将探讨如何构建和管理数据科学技术栈。

第十二章:构建你的技术栈

技术选择具有持久的影响。一个项目的技术栈决定了你系统的功能性和非功能性能力,因此做出慎重的选择至关重要。技术与需求之间的双向链接为通过对比技术特性与项目需求来选择不同技术提供了一种分析方法。在本章中,我们将看到如何利用软件设计实践来形成项目特定的技术栈,并且看到应该构成所有项目共享的核心技术栈的技术。我们还将探索一种方法,比较不同的技术,以便你可以在看似相似的选项之间做出理性的选择。

在本章中,我们将覆盖以下主题:

  • 定义技术栈的元素

  • 选择核心技术与项目特定技术之间的取舍

  • 比较工具和产品

定义技术栈的元素

技术栈是你的团队用来交付产品和完成项目的一组工具。在选择技术时,你首先需要定义它们的目标,并全面记录所有的需求。从那里,你和你的团队可以清楚地了解哪些技术能帮助你实现最终目标。

构建技术栈与设计软件架构并行进行,因此你团队的工程师应从草拟一个能满足所有需求的系统设计开始。软件架构是一个广泛且深奥的技术话题,因此我们在本章中不会深入讨论。相反,我们将概述在选择最适合特定目标的技术时需要遵循的必要步骤。让我们开始吧:

  1. 收集需求并明确地定义目标。

  2. 为你的项目选择一组架构视图。架构视图包含了系统某些方面的视觉和文本描述。以下是架构视图的几个突出示例:

    • 基础设施视图:表示系统的物理部分。服务器、存储阵列和网络等都记录在此视图中。

    • 组件视图:表示你将要构建的软件系统的逻辑组件。组件视图应定义系统的独立部分以及它们之间的通信接口。

    • 部署视图:将组件视图的逻辑表示与基础设施视图的物理现实相匹配。部署视图应描述系统组件如何交付到相应的硬件上。

    • 其他视图:不同的软件架构设计方法定义了许多有用的视图。例如,ArchiMate 2.1 规范定义了 18 个架构视图,这些视图对于不同的利益相关者非常有用。为了简洁起见,我们将只讨论那些可能影响技术栈的主要视图,其他视图将省略。

  3. 根据团队已产生的需求和软件设计,定义开发和运营系统时所需技术功能的列表。不要忘记包括那些能够优化系统实验、开发、交付和运营的横向技术。横向技术可能不会帮助你发现任何特定的功能需求,但它们对项目整体是有益的。例如,实验追踪框架、数据版本控制系统和持续集成/持续部署CI/CD)服务器都是横向技术的例子。

作为一个示例,我们构建一个客户流失预测系统的技术栈。我们的客户已定义以下流失预测模块的需求列表。我们将省略技术细节,以便专注于整体流程:

  1. 处理来自营销数据库的数据,其中包含客户信息。数据集的大小不超过 5 GB 的原始数据。

  2. 每周一对客户流失预测模型进行训练。我们应当将一个月内未进行购买的客户视为流失客户。

  3. 通过远程 API 调用通知团队潜在的客户流失情况。该服务应在工作日内可用。

分解将每个需求分类为两种类型:功能需求FR)和非功能需求NFR)。功能需求包括所有与系统功能相关的需求,这些功能影响核心用例和最终用户。非功能需求包括所有适用于系统的一般性需求,并定义系统运行的约束条件。服务级别协议和可用性要求是非功能需求的典型例子。

团队已经将客户需求分解成以下列表:

  1. FR

    • FR1:系统必须与客户的营销数据库进行集成。

    • FR2:系统必须提供一个客户流失预测模型。我们可以将一个月内未进行购买的客户视为流失客户。

    • FR3:系统必须调用远程 API,通知营销部门潜在的客户流失情况。

    • FR4:模型应每周一执行一次。

  2. NFR

    • NFR1:系统应能够每周处理 5 GB 的数据。

    • NFR2:API 应在工作日内可用。

根据这一需求列表,团队提出了以下系统设计,该设计采用 ArchiMate 2.1 符号,通过 Archi 软件绘制(www.archimatetool.com/):

上图由两个层次组成:基础设施层和软件实现层。

软件层描述了不同组件和服务之间的关系:

  • 原始客户数据:代表流失预测系统所使用的原始数据。

  • 模型训练管道: 表示一组数据处理和模型训练步骤,作为一个软件组件进行分组。

  • 模型预测管道: 代表负责使用训练过的模型进行流失预测并生成客户流失警报的组件。

  • 调度器: 按照预定的计划运行管道,协调其他组件的工作。

  • 客户流失警报: 关于潜在客户流失的通知事件。

  • 营销 CRM 系统: 客户的 CRM 系统,已经部署并投入生产使用。

  • 通知 API: 一个服务,允许我们在 CRM 系统中创建关于客户的通知。

基础设施层,描述软件如何分配到特定硬件资源的物理结构,共有三部分:

  • 营销数据库服务器

  • 模型服务器

  • CRM 服务器

上述软件架构图为了简化起见,省略了许多技术细节,因为我们的目标是展示如何做出技术选择。接下来文本的核心思想不是加深你对软件架构这一广阔领域的知识,而是让你大致了解需求如何转化为合理的技术选择。理解这一过程可以帮助你引导你的专家团队做出高效的技术栈选择。项目对团队来说并不复杂,这项任务对他们来说相当标准。团队决定采用一套他们每个项目都使用的跨领域技术,作为公司标准:

  • Python 作为编程语言

  • Git 用于源代码版本控制

  • 数据版本控制 (DVC) 用于数据版本控制

  • GitLab CI/CD 作为 CI/CD 服务器

  • Jupyter Notebook 用于数据分析和可视化

为了实施 FR,团队决定使用以下技术:

  • FR1:用于数据库访问的 SQLAlchemy 库。

  • FR2:作为机器学习库的 scikit-learn。

  • FR3:API 调用请求。团队还决定使用单独的数据库来存储预测结果和模型执行日志。

  • FR4:团队决定使用 cron(一个流行的 Unix 调度程序,可以根据预定的调度表运行命令)作为主要的调度解决方案。

为了实施 NFR,团队决定执行以下操作:

  • NFR1:进行负载测试,并确定模型训练所需的最低服务器配置。从团队之前的经验来看,一台具有 8 核 CPU、1 GB 内存和 15 GB 硬盘的虚拟服务器应该足够,因此他们将该配置作为测试的基准。

  • NFR2:团队决定请求更详细的 API 使用信息,并询问每天预计的请求次数。结果发现,该 API 每天最多执行 10 次,因此单台 API 服务器就足以满足这一可用性要求。

在本节中,我们探讨了如何开发一个项目特定的技术栈。然而,还有另一个重要的维度是技术选择的关键:团队的专业知识和技能。在下一节中,我们将研究团队与项目技术栈之间的关系。

在核心技术与项目特定技术之间做出选择

技术选择应有助于实现项目需求,但同样重要的是要考虑团队的专业知识和能力,以及各种限制。例如,如果你的团队完全由 Python 开发者组成,即使团队认为 Julia 更适合该项目,选择 Julia 作为主要编程语言可能仍然是个糟糕的主意:

  • 所有团队成员都会花时间学习一门新语言,从而几乎破坏了使用该技术所带来的所有生产力提升。

  • 由于团队成员对新技术缺乏经验,团队的结论可能过于乐观。

如果团队持续培养成长型思维,并不断获得新知识,那么这两种风险会有所减缓,但永远不会完全消失。

团队的核心专业知识限制了项目中可以使用的技术。如果你希望拥有更多选择,单独开发一个团队技术栈就显得至关重要。持续的内部研究过程应确保你的核心技术栈保持最新。项目特定的技术栈可以通过调整核心技术栈以满足项目需求来形成。

我们可以将内部技术研究过程视为一个独立的长期项目,最好通过使用看板(Kanban)来管理:

  1. 团队中的某个成员发现了一项潜在有用的技术。

  2. 有经验的团队成员会迅速评估这项技术。如果技术看起来有前景,他们会将其放入内部研究积压任务中。

  3. 一旦团队经理决定可以投入时间进行内部研究过程,他们便开始整理积压任务。在此过程中,团队根据具体、可衡量、可实现、相关、时限SMART)标准来确定任务的优先级,并丰富任务定义。

  4. 责任人从积压任务中选择一个单独的任务,并尽量快速完成。如果遇到阻塞问题,应立即报告并解决,最好在其他团队成员的帮助下完成。

  5. 一旦研究完成,责任人会以文档或讲座的形式报告研究结果,以便团队决定是否将该技术纳入核心技术栈。

  6. 如果决策是积极的,那么制定一个广泛的内部技术采纳教育计划就变得至关重要。此任务的主要成果是准备一个研讨会、指南、说明书或其他教育材料,以便新旧团队成员可以用来熟悉这项技术。

核心技术栈不应包含仅适用于少数项目的过于具体的技术。本文的唯一目的是帮助你的团队构建一个能够解决大多数项目需求的技术基础。你的团队关注的范围越广,核心技术栈应该越通用。如果整个团队正在构建特定的产品,那么项目特定的技术栈与核心技术栈将开始合并为一个整体。

将核心技术栈适配到新项目的过程如下:

  1. 确定一组项目需求。

  2. 查看核心技术栈满足的需求。

  3. 如果核心技术栈违反了某些需求,寻找替代方案。

  4. 如果核心技术栈无法满足某些需求,寻找可以集成到核心技术栈中的补充技术。

  5. 在项目结束时,评估新添加到项目中的技术,判断它们是否适合核心技术栈。

使用这些流程,你可以将常常混乱且需求驱动的技术选择转化为一系列一致且合乎逻辑的步骤,从而做出有意义的决策。然而,即使是最细致的需求分解,仍然可能让你的团队在选择技术时感到困惑,因为不同框架、库和平台之间有许多交叉点和替代方案。在接下来的部分,我们将探讨如何从多种技术中做出选择。

比较工具和产品

我们应该选择 R 还是 Python? TensorFlow 和 PyTorch 哪个更好? 在互联网上可以找到关于做 Y 时选择 X 最好的无休止争论。那些讨论之所以不断进行,是因为技术世界没有万金油。每个专业团队都有其特定的使用案例,这使得某些技术选择对他们有效。没有任何一种技术能够满足所有人的需求。

X 与 Y 的争论常常发生在项目团队内部,这也是工程师们最浪费时间的活动。如果你试图将 X 与 Y 的辩论转变为寻找适合你具体需求的技术(这些需求已经明确、分类并文档化),你将在更短的时间内获得更有用的结果。选择最现代或最时尚的技术,对数据科学家和软件工程师来说,就像是玩俄罗斯轮盘。让我们探讨如何做出有关技术栈的深思熟虑的决策。

为了做出有意义的技术选择,你需要让这个过程更加系统化。首先,你需要制定一套比较标准,允许你对不同技术进行基准测试,并为研究活动提供模板。这些标准应该考察不同维度或需求群体,确保技术在你的具体案例中是有用的。

让我们通过案例研究来审视比较不同技术的具体细节。

案例研究 – 预测物流公司的需求

假设我们需要为我们的项目选择一个时间序列预测框架。我们的团队主要使用 Python,并需要提供一个能够为时间序列数据提供预测的工具。该系统的主要目标是预测公司运输的一组给定产品的需求。团队发现有很多不同的预测框架可供选择。

为了在这些产品之间做出选择,团队制定了以下比较标准:

ID 需求 定义 理由 评分 优先级
开发难易度
D1 与 Python 兼容 Python 是团队的主要编程语言。 3 必须
D2 与 scikit-learn 接口兼容 团队在scikit-learn库方面有丰富的经验。如果时间序列预测库能够与scikit-learn兼容,将会是一个有利的功能。 2 重要
D3 拥有良好的文档 1 补充
D4 可以在不到 10 行代码内完成预测 1 补充
D5 可以将时间序列作为原生数据类型处理 该框架应能处理原始时间序列数据,这样团队就不需要在数据集准备和特征工程上花费额外的时间。 2 重要
预测算法要求
F1 无需手动调优超参数 由于该库将用于大量时间序列,手动调优模型不切实际。该工具应支持自动化的超参数调优,或者在选择超参数时具备良好的鲁棒性,从而在默认设置下提供良好的预测结果。 3 必须
F2 提供多种预测方法 提供多种预测方法将使我们能够评估多个模型,并选择最适合每个特定时间序列的模型。 1 补充
F3 支持季节性时间序列 客户数据中的所有时间序列都有季节性模式。 3 必须
F4 提供置信区间以及预测值 置信区间可用于为每个预测提供不确定性范围,这是客户认为一个有用的功能。 2 重要
性能和数据要求
P1 可以在 15 秒内预测具有 100 个数据点的时间序列 大量的时间序列限制了我们在单一时间序列上可以花费的总时间。 2 重要
P2 可以处理具有可变长度和缺失数据的时间序列 数据质量不理想,数据中存在一些缺口。一些项目的历史数据比其他项目多。 2 重要

上述比较表包含以下列:

  • ID:这可以作为技术比较表中的简短标识符(下文提供)。

  • 需求定义:这应该描述感兴趣的能力。

  • 替代方案:这应该提供需求背后的动机。

  • 得分:显示需求的相对重要性,并将用于总结每个需求类别。

  • 优先级:表示每个需求的必要性,并将为每项技术提供额外的得分。

接下来,团队已经准备了一个框架比较列表,如下所示:

团队还制定了以下比较表格:

该表格还可以进一步总结,给出以下最终结果:

框架 开发难度得分 预测算法要求得分 性能和数据要求得分 满足强制性要求 满足重要要求 满足补充要求
pmdarima 10/12 8/9 0/4 3/3 3/5 1/3
statsmodels.tsa 8/12 6/9 2/4 2/3 3/5 2/3
Prophet 10/12 8/9 2/4 3/3 3/5 2/3
LightGBMtsfresh 7/12 3/9 2/4 2/3 2/5 1/3

如果愿意,你可以使用加权平均法将每个框架的得分总结为一个数字。然而,请记住,简化复杂决策为一个数字如果做得不对,可能会导致错误。

这些研究结果表明,根据初步需求,Prophet 被认为是更好的选择。然而,这些结果并不意味着 Prophet 是所有应用的最佳选择。技术选择应该有一定的偏向和观点,因为没有任何技术能适用于所有项目。例如,如果团队考虑了期望的平均指标值,排名可能会完全不同。在这种情况下,其他框架可能会因为提供了更准确的模型而获胜。

摘要

在本章中,我们已经看到了如何根据技术的需求来选择技术,而不是根据其周围的炒作。我们还探讨了如何构建需求,并从软件架构中推导出技术栈的主要元素。最后,我们讨论了核心技术栈和项目特定技术栈之间的区别,并考察了一种分析方法来比较不同的技术。

下一章将会总结本书的内容;恭喜你完成了本书的阅读!

第十三章:结论

首先,感谢您阅读本书!我希望本书的内容在呈现数据科学项目的整体管理方法方面对您有所帮助。数据科学管理是一个多维度的话题,要求管理者展现出技术、组织和战略方面的熟练能力,以便能够在任何组织中执行数据科学战略。

首先,数据科学经理需要了解数据科学能够做什么,以及其技术限制。没有对基本概念的理解,很容易误解同事或向客户提供过度承诺的项目结果。本书的什么是数据科学一节描述了机器学习和深度学习的基础知识,包括构成机器学习算法的数学概念背后的解释。我们探讨了技术和商业指标的世界,定义了数学优化,并研究了统计学和概率。这些概念帮助我们定义了机器如何通过最大似然估计进行学习。特别是,我们可以通过这个数学框架解释几乎每一个机器学习算法。我们还看到,由于“没有免费午餐定理”,机器学习世界中没有银弹。该定理指出,如果你在所有可能的数据集和任务上衡量一个机器学习算法的准确性,它将不会比随机选择更好。

接下来,我们的旅程继续向建立和维持团队一节发展,在那里我们学习了如何平衡长期和短期的团队建设目标。我们讨论了过于复杂的技术面试的缺陷以及如何避免它们。这里的主要观点是,首先看清你需要什么,然后寻找具有特定技能的人,而不是寻找可以做任何事情的超级数据科学家。我们还讨论了如何通过实际经验来进行数据科学面试。然后,我们探讨了团队平衡的概念,这形成了团队长期稳定性,使他们能够成长和发展。我们还触及了成长心态这一重要话题。通过自己遵循这一做法,您成为了团队的榜样。

数据科学项目管理部分,我们聚焦于项目管理,从创新和营销的战略角度进行全局观的分析。我们探讨了创新与数据科学的关系,并提供了高层次的策略来管理不同组织中的创新。我们从较低层次分析了数据科学项目管理,并检查了我们可以用来管理单个项目的流程。随后,我们基于 CRISP-DM 定义了数据科学项目生命周期,并回顾了客户、经理和实施团队在交付数据科学解决方案时常犯的错误。我们还涉及了软件组件的可重用性问题,并指出,创建可重用的组件将有助于项目开发,并提升团队的业务潜力。

总结而言,创建开发基础设施部分讨论了数据科学项目的工程方面。我们讨论了如何基于客户需求和自身核心技术专长创建技术栈。最后,我们展示了如何创建对比矩阵,以便在不同技术之间做出选择。

深化你的知识

如果你希望在数据科学管理领域继续深化你的知识,以下是一些值得阅读的书籍:

总结

恭喜你完成了这本书!希望它帮助你加深了对数据科学的理解,并且系统化了数据科学项目的管理技巧。请不要把你所学到的关于数据科学理论的知识抛诸脑后。为了掌握我们在本书中涉及的概念,你应该将它们应用到日常工作中。我还强烈建议你养成成长型思维方式,如果你还没有的话。你会惊讶于每天学习一点新知识,即使是最小的知识点,也能带给你多大的进步。没有一本书能涵盖数据科学管理的所有方面,但你可以通过参考本章提到的其中一本书或在掌握数据科学的过程中发现自己的道路,继续这段旅程。

posted @ 2025-07-20 11:32  绝不原创的飞龙  阅读(6)  评论(0)    收藏  举报