不知道大家以前听没听说过“10x Developer”这个词,如果你连听都还没听说过,那可真是时候考虑放弃自己的程序猿事业了。就像传说一样,一些程序猿的战斗力能达到同行的10倍,也就是说一个10x程序猿能够替换一个10人的开发团队。
本篇文章我们就针对数据科学,来谈一谈如何才能成为一名传说中的10x老司机。本文作者主要从事数据挖掘及处理方面的开发工作,是西雅图女性程序员俱乐部PyLadies创始人,曾在PyData Seattle 2015上做过关于通过自然语言处理和机器学习调查用户体验的主题演讲。
以下正文
最近我在PyData Seattle(https://pydata.org/seattle2017/)发表了一个关于如何通过借鉴开发社区的提示和窍门来提高数据科学技能的主题演讲。这些建议将帮助开发者成为一名非常受团队成员和其他人欢迎的数据科学方面的老司机。
这篇文章分为五部分,其中包括:
- 10x开发者的历史和争议
- 项目设计
- 代码设计
- 工作工具
- 生产模式
当然,如果你想观看原始演讲的视频,可以点击这里
10x开发人员,顾名思义,就是比普通开发人员生产力高出10倍的人。
一个10x的开发人员,不只是能在一定时间内比普通开发人员生产更多代码,还能像boss一样调试bug,代码里的bug也更少。因为他们会测试代码,指导初级开发人员,编写自己的文档,并且拥有很多其他技能来让自己超越仅仅知道如何写代码的境界。
H. Sackman,W. J. Erikson和E. E. Grant在1968年进行了一个叫做“比较在线和离线编程性能的探索性实验研究”的实验,发现程序员在完成写代码的任务上有很大的时间差异。
虽然该实验选取的被研究人员平均开发经验已经达到了七年之久,但相互之间的时间差异却能达到惊人的20倍。
虽然该实验的设计存在一定的缺陷,例如将使用低级语言的程序员和使用高级语言的程序员混合到了一起,但之后越来越多的研究都发现了类似的结果。
虽然关于到底存不存在10x开发人员仍有着广泛的争论,但本文重点关注的不是这些,而是关注开发人员,如何通过从那些经验丰富并且被认为开发速度更快的人那里得到的提示和窍门,成为一名更有生产效率的数据科学家。
你得真正了解业务
不管你是为教育、生物技术还是金融公司工作,都应该至少对解决问题的业务有一个比较深入的了解。
为了有效地沟通数据分析背后的故事,你应该了解是什么在驱动业务,并且了解业务目标。
例如,如果你负责优化食品卡车的位置,那么你就需要了解客流量,竞争,该地区发生的事件,甚至天气。你需要想了解公司为什么要优化位置。可能是因为公司要增加现有卡车的销售量,或者是想要增加卡车数量。
哪怕你可能是今天在搜索网站工作,明天就到了金融公司去当数据科学家,你也应该为了使你的分析与利益相关者相关知道是什么让业务成为可能。
你还应该了解你所在项目的业务流程,例如知道谁需要签署最终结果,一旦你负责的部分完成,数据模型被传递给谁,以及预期的时间表是如何安排的。
***,你应该确保你知道这个项目的利益相关者是谁,并且能够向不懂技术的利益相关者讲明白这个项目实际的效果。就像是成为教育工作者一样,并能够向不懂技术的利益相关者讲明白为什么达成目标可能需要比他们预期的更多时间或资源。
当你了解了利益相关方的目标,并能够确保你沟通技术,专业知识和建立解决方案所需的时间,那么你在你们公司的价值一定会变得更大。
你得真正了解数据
了解业务很重要,了解数据更重要。你需要知道数据该怎样提取,何时提取,谁负责质量控制,为什么数据会可能存在差距(例如供应商的变化或提取方法的变化),什么可能会丢失,并且哪些其他数据源可以被添加进来以创建一个更准确的模型。
这真的需要你去和不同的团队交谈,并且不断地提出问题。不要害怕问他们正在做哪些工作,也不要害怕跟他们讨论你正在做哪些工作,因为你永远不知道大家是不是在做重复的工作,或者他们是否有一个更干净的版本的数据,而这恰恰是你需要数据。这样可以节省你大量查询数据库的时间,例如对SiteCatalyst进行多个API调用。
为什么在项目设计过程中多花费一些时间和精力可以让你成为10x数据科学家?
- 你只需要做那些需要完成的工作(在写代码之前已经思考过),这样就可以快速完成项目,因为你会减少工作量!
- 通过在客户/用户认为他们需要的东西和他们真正需要的东西之间发现不同,你就能把自己定位成这个领域的专家和共识的制定者。
- 你会巩固自己对问题的理解,从而减小犯那些重大错误的几率。
你得懂得代码设计
虽然在设计代码时有很多非常好的实践,但其中有一些非常突出的细节将大大增加你的生产效率。
我***次听到关于清晰度或清晰度胜过聪明才智的论述是在大学写作课。 被自己一时的聪明想法抓住,并使用今天刚想到的***词汇来表述想法是很容易的一件事,但是像编程一样,你这样做不仅可能会混淆自己,还会混淆别人。(小编注:比如不按变量命名规则,每次都是a,b,c。。。真的在日后看代码的时候很崩溃)
在上面的Scala示例中,***行显示了使用简写语法的sortBy方法。虽然简明扼要,但很难想象下划线代表什么。虽然这是许多人在匿名函数中表示参数名称的常见模式,但对于不太高级的开发人员(或者当你过了一段时间再看你的代码)时,搞明白代码到底代表什么的做法就变得很头痛了。
在第二个例子中,我们起码使用了一个参数名称,加上它还显示了赋值,我们可以看到它是通过序列x中的***一个元素排序的。
当代码不怎么抽象的时候,之后的调试才会更容易,所以在第三个例子中,我明确命名了我的参数,以便它表示数据。
当你的大脑必须要经历每一步,或者查找或回想代码的简写代表什么的时候,调试会需要更长的时间,添加新函数也会需要更长的时间,因此即使使用上述示例的简写可以简洁而快速地输入,从长远来看,明确命名参数对你和他人都会是有利的,从而避免你们耍小聪明犯下的错。
虽然我们不会检查缓存,但我们将介绍命名的重要性。想象一下,你正在查看一些旧的代码,你会看到序列按Scala示例进行排序:
- .sortBy(x => -x._2)
使用单个字母来命名序列根本提供不了有用的信息,因为当你可能从API,数据库或Spark中的数据流中提取数据时,你必须运行代码才能看到”x”到底代表什么。
所以保持与之前Scala的示例的代码应该是:
- sortBy(clothesCount => -clothesCount._2)
这样你就可以知道我们正在对什么进行排序,甚至不用运行代码。
但是,有时使用X作为变量名称却很好。例如,X通常用于机器学习库,其中X表示观察到的数据,而y是试图预测的变量。在这种情况下,使用这个领域约定俗成的表示,如“模型”,“拟合”,“预测”和“x”和“y”等字段是***不过的。
除了数据科学方面的要求,你还要遵循你所使用的语言的编程语言惯例。例如,我建议你去检查一下文档,如PEP for Python,来了解***做法。
通过规范你的命名约定,并通过清晰而不是耍小聪明的代码,它将使重构和调试更容易和更快。按照这两个代码设计的窍门,你将走上成为10x数据科学家的道路。
保持代码样式一致,与刚刚我们说的保持命名约定一样重要。要获得一些基本的风格点,你应该坚持一种情况,不要在同一个脚本中混合使用驼峰式大小写和snake的命名规范,否则的话,你的代码很快就会变得难以阅读和浏览。另一种你应该保持一致的方法是同一种任务要坚持使用相同方法。
例如,要从字典中删除重复项,并且需要在代码的好几个位置处执行此操作,那么就不要仅仅因为在Stack Overflow网站上看到过就使用其他创造性的方法来执行操作。使用最清晰和最不聪明的方法来让你的代码和脚本保持一致。并且,我还要再次强调,一致性的目的是为了避免让你自己和其他人混淆,这将有助于你更快地进行调试!(请注意,我们这段话的核心是调试)。
还记住我们刚刚谈到的,必须在代码中的多个地方删除字典中的重复项吗?使用函数,你就不需要多次重写代码。当然,即使你不重用代码,把代码封装在函数中也是至关重要的***做法。你的函数应该很小,小到只能做一件事情,以便可以重复调用。
当你不使用函数时,经常会有有全局变量导致命名冲突,代码不可测试和代码的不断重复。
通过使用函数,你的代码就可以自由组合,更易于编写测试单元。
但是不要仅仅止步于写一些只做一件事情的小函数,请务必抽象你的函数,以便重新使用它们 - 这样有助于降低代码冗余度,并能加快你的开发时间,这样做下去至少让你成为一个2x 程序猿。
尽管不太常见,但代码设计中很重要的一点是使用桩代码。桩代码是简单的mock类以及函数,可以显示输入,输出和注释,并为代码提供一个大纲。在你开始实际编写代码之前,使用桩代码会让你先考虑代码,并可以帮助你避免怪异的意大利面条式的代码。你会注意到你在编写代码之前有哪些重复的代码,并且会考虑最合适的数据结构。
上面的代码示例给我们展示了注释和文档。要真正成为一个被同事喜欢的程序猿,并提高自己作为一名数据科学家的效率,就要会写有用的简明扼要的注释。这不仅应该包括关于代码段的注释,还包括其输入和输出。
此外,关于docstrings可能最酷的是,它们可以通过大多数语言的库转换为文档。例如Python有一个名为Sphinx的库,可以让你将docstrings转换成完整的文档。
你现在可能知道你的代码是什么,但当你尝试调试或添加函数时,你和其他人将非常开心有注释。
无论你使用什么语言编写代码,请记得使用异常处理,并为你自己,同事和最终用户留下有用的错误信息。上面的代码显示了一个停止函数,能够传递来自正在调用的API的错误消息。
如果数据不是API需要的,那么它就会引发一个有用的错误消息。在你自己的代码中,你可以在停止函数中写一个消息,帮助用户:
- stop(paste0(“Make sure all your inputs are strings: ”, e))
以上示例来自“Hitchhikers Guide to Python”,它使用Python测试库Pytest。
尽管编写测试单元对于开发人员来说相当普遍,但这在数据科学领域却很少使用。当然,你可以使用交叉验证,混淆矩阵和其他方法来验证你的模型。 但是,你是否测试了正在为你获取数据的查询? 你使用的各种方法是如何清理和转换数据的,你的模型需要它们吗? 这些方面对于安全防范“Garbage in, garbage out”(小编注:这两个单词的意思是,如果将错误的、无意义的数据输入计算机系统,计算机自然也一定会输出错误、无意义的结果。)至关重要。 当你测试代码时,不仅这两个未来的证据可以反映可能引入错误的变化,而且当你有能力自己给自己检查代码时,每个人都会认为你就像一个摇滚明星一样耀眼,因为一旦代码被用于实际生产就会发现bug非常少。
为你的项目使用版本控制是成为10x数据科学家的重要一步。这最明显的好处是保存模型的不同版本,既可以轻松地进行团队工作,也可以通过在存储库中使用版本控制进行备份,防止在笔记本电脑被盗或硬盘驱动器坠毁的情况下丢失工作。
在beta版中,有一个名为Data Version Control的开源数据版本控制项目,对于数据科学工作流程来说看着很有希望。 它依靠Git,并允许通过构建数据依赖图来跨团队重现项目。你的数据会与你的模型分开保存,它与其他版本控件一样工作,允许你回滚到以前保存的备份。
10x开发人员知道使用正确的工具来完成工作,无论是使用库来节省时间,切换语言以实现性能,还是使用API,而不是自己从头构建解决方案。
比方说你现在有一些Twitter或其他社交数据要用来进行情绪分析。一个选择是自己标注数据,训练自己的模型,另一个则是使用预先训练的模型。不去自己建立每个数据模型来重新造轮子是很薄的。使用最适合工作的工具,即使这意味着使用你没有构建过的工具。
我们都写过一个与Cron工作配对的Bash脚本来自动化一些报告,但是,在你花费一些时间尝试调试由Cron自动执行的其他人撰写的报告时,你甚至不知道它在哪里运行,你会意识到必须有更好的方法才行。通过使用自动化工具,如Puppet,Chef,Ansible或任何其他流行的自动化工具,你就可以从集中的位置运行你的工作,因此调试他人(或你自己)的工作就能快很多。
有时你可能找不到一个团队来负责你设计的模型,这个时候就需要知道如何自己部署自己的模型。
虽然上面那副图中的提供商之间有很多差异,但它们包含了从难以置信的易用性到你需要的更多的设置和知识。本节的内容其实可以单独成为一个话题。如果你想了解有关模型托管的更多细节,可以查看我们的其他几个不同的报告,分别介绍部署模型(https://blog.algorithmia.com/building-intelligent-applications/ )以及部署和扩展你的深度学习模型(https://blog.algorithmia.com/deploying-deep-learning-cloud-services/)。
可能是致命伤的事情:
- 易用性
- 成本(包括附加组件和隐藏成本,如托管数据)
- 投标人锁定
- 语言可用性
通过了解如何部署模型,你才有能力通过数据来讲述故事,轻松地与团队成员共享(不管使用哪种语言)或将其部署到生产环境中,从而与数千用户共享。这将帮助你成为10x-er,因为一旦了解了这一点,你就可以创建更多性能更高的模型,使用户开心。当用户开心时,企业主就会开心。
成为10x数据科学家的技巧
为了让这篇文章圆满,这里有一些关于如何成为10x数据科学家的***的技巧:
- 模式匹配。这来自于以前遇到类似问题并意识到可以重用或修改当前问题解决方案的经验。
- 了解如何解释你的代码 - 给自己和其他人。 这意味着你可以在白板上,做/得到代码甚至协同编程。要习惯于谈论你的代码和思考过程。
- 了解如何/何时退出并重新开始。如果你意识到有一个更好的方法来解决问题,那就不要害怕重新开始。***就是重新开始,做一个更好的方法来完成,而不是放出一些不是***或高性能的东西。
- 创建你自己的Gists库,或通过GitHub或其他托管服务的存储库组织代码片段。
***,回顾整篇帖子,如何成为一个10x的数据科学家和如何调试其实是相同的主题。每个10x的开发人员都可以想象成一个主调试器,因为这个规则就是无论你的代码多长,你都可以将它乘以10,并得到你需要调试的时间。 成为一个很好的调试器的一个窍门就是使用异常处理,你可以在IDE中使用调试器,你可以通过代码查找逻辑中的错误,并检查涉及错误的库的源代码,以确保你正在传递代码需要的内容。
即使你从这个帖子只得到了几点收获,恭喜你,你已走上了成为10x数据科学家的道路。
当然,能不能抵达道路的尽头,就看你自己咯。