
从实战角度解读数据科学
在过去几年里,数据科学已经被各行各业广泛接纳。数据科学起初在更大程度上来说是一个研究课题,源于科学家们为了理解人类智能、打造人工智能而做出的努力。后来,事实证明它能带来真正的商业价值。
举个例子。Zalando公司是欧洲最大的时装零售商之一,就在大量地利用数据科学来提供数据驱动的推荐和其他功能。在很多地方,包括产品页面、目录页面、广告邮件和重定向页面上,都会为用户提供“推荐”这样的后端服务。
有很多种方法可以生成数据驱动的推荐。协同过滤程序会收集整个用户群在产品浏览、愿望清单和购买等方面的用户行为,然后处理这些信息,确定哪些商品拥有类似的用户模式。这种方法的优点在于计算机不必了解商品本身的任何信息,缺点是必须要有庞大的流量,不然无法获得关于商品的充足信息。另一种方法只着眼于商品的各种属性,比如推荐同一品牌或者颜色相近的其他商品。当然,有很多途径可以延伸使用这些方法或者把它们综合运用起来。
还有更简单的一些方法,基本只通过计数来生成推荐,但在实际操作上,这类方法的复杂度几乎没有上限。例如,就个性化推荐而言,我们一直在研究对从各种角度对商品进行排序的机器学习排名方法。上图显示的是用于优化这一方法的成本函数,主要是为了说明数据科学有时具有的复杂程度。该函数采用包含正则项的对偶加权排名指标。虽然在数学上非常精确,但也非常抽象。这种方法不仅能用于电子商务领域的推荐,还能用于解决各种各样的排名问题,前提是排名对象具备适合的特征。
那么,如何将上面提到的这类非常正规的数学方法引入产品开发?数据科学和工程之间又是怎样对接的?哪种组织和团队架构最适合采用这种方法?这些是非常重要且合理的问题,因为它们决定了对一名数据科学家或者一整支数据科学家团队的投资到最后是否真能取得回报。
在后文中,我将根据我个人从事机器学习研究工作和在Zalando公司领导数支数据科学家和工程师团队的实战经验,对这些问题进行探讨。
让我们先着眼于数据科学系统和后端开发系统,看看如何才能把这两个系统结合起来。
典型的数据科学工作流程如下:第一步永远是找出问题,然后收集相关数据,可能来自于数据库或者开发记录。视你所在机构的数据可用性而定,这可能就已经非常困难了,你必须先弄清楚谁能让你有权访问那些数据,然后弄清楚谁能确保你顺利拿到那些数据。得到数据后,接着对其进行预处理,提取数据特征,以期获取有用信息,帮助解决问题。将这些特征输入机器学习算法,再将得出的模型用测试数据进行评估,以预测模型用于未来数据的效果。
这一管道通常会一次性建设完毕,往往由数据科学家使用Python等编程语言,手动完成各个步骤。Python有很多的数据分析库和数据可视化库。根据数据量的大小,也可能使用Spark或Hadoop这样的分布式计算系统,但数据科学家往往先从数据的一个子集着手。
从小处着手的主要原因在于,这个过程不是只进行一次,而是会迭代很多次。从本质上来说,数据科学项目本身是探究性的,所得结果在某种程度上是开放性的。目标可能很明确,但在刚开始的时候,常常不知道哪些数据可用,或者可用数据是否适合。毕竟,选择采用机器学习这种方法,已经意味着你不能妄想只靠编写一套程序就能解决问题。你必须采用一种数据驱动的方法。
这意味着该管道将会迭代和改进很多次,尝试不同的数据特征、不同的预处理方式、不同的机器学习算法,甚至可能回到原点,添加更多的数据源。
整个过程本质上是迭代的,常常具有高度的探究性。在模型表现看起来比较像样后,就该准备用现实数据来测试了。这时便轮到开发系统出场。
开发系统和数据科学系统之间的最主要区别可能在于,开发系统是持续运行的实时系统。数据必须得到处理,模型必须不断更新。输入事件也常常被用来计算点击率等关键绩效指标。模型经常每隔几小时就使用可用数据重新训练一次,然后加载入开发系统中,通过采用REST架构的接口提供数据
出于性能和稳定性的考虑,那些系统常常用Java之类的编程语言编写。
如果把开发系统和数据科学系统放在一起比较,就会得出以上这张图。右上方是数据科学系统,使用Python这样的编程语言或者Spark这样的分布式计算系统,但通常包含手动触发的一次性计算和为了优化系统而进行的迭代。其结果是一个模型,它本质上就是一堆描述学习模型的数字。然后,开发系统会加载该模型。开发系统会是一套更为传统的的企业系统,用Java这样的语言编写,并且保持持续运行。
当然,上图有点简化。实际上,模型必须反复训练,因此还必须将某个版本的数据处理管道嵌入开发系统,以便时不时地更新模型。
请注意图中的A/B测试,它会在实时系统中执行,对应的是数据科学系统中的评估步骤。通常来说,A/B测试和模型评估不完全具有可比性,因为在没有真正把推荐商品显示给用户看的情况下,A/B测试很难模拟出线下推荐的效果,但A/B测试应该有助于模型性能的提升。
最后要注意的是,这整个系统不是建立后就“完事”。如同必须先迭代和精调数据科学系统的数据分析管道一样,整个实时系统也需要随着数据分布情况的变化进行迭代,并且为数据分析打开新的可能性。我认为,这种“外部迭代”既是最大的挑战,也是最重要的挑战,因为它将决定你能否持续改善系统,保证你最初对数据科学的投资不会付诸东流。
到目前为止,我们主要讨论了各系统在软件开发中的典型情况。人们对开发系统真正能够达成的稳健度和高效性的期望高低不一。有时,直接部署一套用Python编写的模型就足够了,但探究部分和开发部分通常就此分道扬镳。
如何协调数据科学家和开发人员之间的合作?这是一个重大的挑战。从某种程度上来说,“数据科学家”还是一个新职业,但他们所做的工作明显有别于开发人员所做的工作。这两者很容易在沟通上存在误解和障碍。
数据科学家的工作通常具有高度的探究性。数据科学项目常常始于一个模糊的目标,或者有关哪种数据和方法可用的设想。你往往只能试验你的想法,洞悉你的数据。数据科学家会编写大量代码,但其中很大一部分代码都是为了测试想法,并不会直接用在最终的解决方案中。
而开发人员把更多的精力用于编写代码。他们的目标就是编写系统,打造具有所需功能性的程序。开发人员有时也从事探究性的工作,比如原型建造、概念验证或者基准测试,但他们的主要工作就是写代码。
这些不同之处也在代码日渐开发出来的方式上表现得非常明显。开发人员常常尽量遵循一个明确定义的过程,其中涉及为独立的工作流创建分支程序,接着对各个分支进行检查,然后再并入主干。开发人员可以并行工作,但需要把已核准的分支集成到主干程序中,然后再从主干上建立新的分支,如此往复。这一切是为了确保主干能以有序的方式完成开发。
正如我上文所说,数据科学家也会编写大量代码,但这些代码常常是为了探索和尝试新的想法。所以,你可能会先开发出一个1.0版,但并不太符合你的预期,接着便有了2.0版,进而产生2.1和2.2版。然后你放弃了这个方向,又做出了3.0和3.1版。这时你意识到,如果把2.1版和3.1版的一些想法结合起来,就能得到更好的解决方案,因此有了3.3和3.4版,这便是最终的解决方案。
有意思的是,你会很想保留那些走进死胡同的版本,因为以后你可能还会再用到它们。你也可能会把其中一些令你满意的成果加入一个日渐壮大的工具箱,它就像是你个人的机器学习库。开发人员喜欢删除“死亡代码”(也是因为他们知道以后随时都能重新恢复那些代码,而且他们知道如何快速地做到这一点),而数据科学家则喜欢保留代码,以防万一。
在实践中,这两个不同之处意味着开发人员和数据科学家在一起工作时常常会出问题。标准的软件工程实践并不适合数据科学家的探究性工作模式,因为两者致力于的目标不同。代码检查和分支—检查—整合这套有序的工作流程,在数据科学家这边完全行不通,只会拖慢他们的进度。同理,把探究性模式应用于开发系统也行不通。
那么,我们如何让数据科学家和开发人员之间的合作对双方都最有利?第一反应可能是把二者分开。例如,彻底分开代码库,让数据科学家独立工作,制定规范文档,然后由开发人员加以实现。这种方法可行,但效率很低,而且容易出错,因为重新实现可能引入错误,尤其是在开发人员不熟悉数据分析算法的情况下。另外,进行外部迭代以改善整个系统,也取决于开发人员是否有足够的能力来实现数据科学家的规范文档。
幸好,很多数据科学家也想成为更好的软件工程师,很多软件工程师也有心成为更好的数据科学家。因此,我们已经开始尝试更加直接一点、有助于加快整个过程的合作模式。
例如,数据科学家和开发人员的代码库仍然可以分开,但数据科学家可通过一个明确定义的接口,把他们的算法和一部分的开发系统钩连起来。显然,与开发系统进行通信的代码必须遵守更严格的软件开发实践,但仍然由数据科学家负责。这样一来,他们不仅能在内部迅速迭代,还能在开发系统中迭代。
这种架构模式的具体实现方式的一种,便是采用微服务架构,并让开发系统能够查询数据科学家的微服务以获得建议。这样一来,原本被数据科学家用于离线分析的整个管道也能同时用于执行A/B测试,甚至可在无需开发人员重新实现所有代码的状态下直接添加进开发系统。这也更强调数据科学家的软件工程技能,但我们发现拥有那套技能的数据科学家越来越多。为了反映这一事实,Zalando公司已经把数据科学家的头衔改为了“研究工程师(数据科学方向)”。
依靠像这样的方法,数据科学家能够迅速行动,用离线数据迭代,遵从软件开发的具体要求迭代,整个团队能把稳定的数据分析解决方案逐渐移植到开发系统中。
到此为止,我已经大致剖析了把数据科学引入软件开发的典型架构。大家必须弄明白一个关键的概念,那就是这类架构需要不断适应和改进(就像使用实时数据的所有数据驱动项目一样)。能够迅速迭代、尝试新方法和在A/B测试中用实时数据测试结果,这些是最重要的。
根据我的经验来看,让数据科学家和开发人员各自为政是无法做到这一点的。但同时,必须承认他们的工作模式不同,因为他们的目标不同:数据科学家的工作更具探究性,而开发人员更关注于打造软件和系统。如果让双方以一种最适合这些目标的方式工作,并在他们之间定义一个明确的接口,就有可能把双方结合在一起,迅速地尝试新方法。这要求数据科学家具备更多的软件工程技能,或者至少要有能够架通两个世界的工程师提供支持。
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
MySQL 执行计划中 rows 数量的准确性解析:原理、影响因素与优化 在 MySQL SQL 调优中,EXPLAIN执行计划是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 对象的 text 与 content:区别、场景与实践指南 在 Python 进行 HTTP 网络请求开发时(如使用requests ...
2025-09-15CDA 数据分析师:激活表格结构数据价值的核心操盘手 表格结构数据(如 Excel 表格、数据库表)是企业最基础、最核心的数据形态 ...
2025-09-15Python HTTP 请求工具对比:urllib.request 与 requests 的核心差异与选择指南 在 Python 处理 HTTP 请求(如接口调用、数据爬取 ...
2025-09-12解决 pd.read_csv 读取长浮点数据的科学计数法问题 为帮助 Python 数据从业者解决pd.read_csv读取长浮点数据时的科学计数法问题 ...
2025-09-12CDA 数据分析师:业务数据分析步骤的落地者与价值优化者 业务数据分析是企业解决日常运营问题、提升执行效率的核心手段,其价值 ...
2025-09-12用 SQL 验证业务逻辑:从规则拆解到数据把关的实战指南 在业务系统落地过程中,“业务逻辑” 是连接 “需求设计” 与 “用户体验 ...
2025-09-11塔吉特百货孕妇营销案例:数据驱动下的精准零售革命与启示 在零售行业 “流量红利见顶” 的当下,精准营销成为企业突围的核心方 ...
2025-09-11CDA 数据分析师与战略 / 业务数据分析:概念辨析与协同价值 在数据驱动决策的体系中,“战略数据分析”“业务数据分析” 是企业 ...
2025-09-11Excel 数据聚类分析:从操作实践到业务价值挖掘 在数据分析场景中,聚类分析作为 “无监督分组” 的核心工具,能从杂乱数据中挖 ...
2025-09-10统计模型的核心目的:从数据解读到决策支撑的价值导向 统计模型作为数据分析的核心工具,并非简单的 “公式堆砌”,而是围绕特定 ...
2025-09-10CDA 数据分析师:商业数据分析实践的落地者与价值创造者 商业数据分析的价值,最终要在 “实践” 中体现 —— 脱离业务场景的分 ...
2025-09-10机器学习解决实际问题的核心关键:从业务到落地的全流程解析 在人工智能技术落地的浪潮中,机器学习作为核心工具,已广泛应用于 ...
2025-09-09SPSS 编码状态区域中 Unicode 的功能与价值解析 在 SPSS(Statistical Product and Service Solutions,统计产品与服务解决方案 ...
2025-09-09CDA 数据分析师:驾驭商业数据分析流程的核心力量 在商业决策从 “经验驱动” 向 “数据驱动” 转型的过程中,商业数据分析总体 ...
2025-09-09R 语言:数据科学与科研领域的核心工具及优势解析 一、引言 在数据驱动决策的时代,无论是科研人员验证实验假设(如前文中的 T ...
2025-09-08T 检验在假设检验中的应用与实践 一、引言 在科研数据分析、医学实验验证、经济指标对比等领域,常常需要判断 “样本间的差异是 ...
2025-09-08在商业竞争日益激烈的当下,“用数据说话” 已从企业的 “加分项” 变为 “生存必需”。然而,零散的数据分析无法持续为业务赋能 ...
2025-09-08随机森林算法的核心特点:原理、优势与应用解析 在机器学习领域,随机森林(Random Forest)作为集成学习(Ensemble Learning) ...
2025-09-05Excel 区域名定义:从基础到进阶的高效应用指南 在 Excel 数据处理中,频繁引用单元格区域(如A2:A100、B3:D20)不仅容易出错, ...
2025-09-05