出色代码成就机器学习:数据科学的软件工程技巧和最佳实践


全文共3766字 , 预计学习时长10分钟
出色代码成就机器学习:数据科学的软件工程技巧和最佳实践
本文插图
图源: realpython
如果你对数据科学感兴趣 , 那么可能对这个工作流程很熟悉:通过运行Jupyter notebook开启一个项目 , 然后开始编写python代码、运行复杂的分析甚至训练模型 。 随着notebook文件的函数、类、图和日志的大小不断增长 , 你会发现自己面前堆积了巨大的一团代码块 。 运气好的话 , 一切都能顺利进行 。 那你真的很厉害!
但是 , Jupyter notebook隐藏了一些严重的陷阱 , 可能会让代码变成噩梦 。 让我们看看这是如何发生的 , 然后讨论一下防止这种情况出现的最佳编码方法 。
出色代码成就机器学习:数据科学的软件工程技巧和最佳实践
本文插图
Jupyter Notebook的问题
通常 , 如果你想使Jupyter原型开发更上一层楼 , 事情结果可能会不符合你的预期 。 这是笔者在使用此工具时遇到的一些情况 , 你应该也很熟悉:
· 将所有对象(函数或类)定义并实例化后 , 可维护性就变得非常困难:即使想对函数做些小改动 , 也必须将其放在笔记本中的某个位置进行修复 , 然后重新运行重新编码 。 你一定不希望这种事情发生 。 将逻辑和处理功能分离在外部脚本中不是更简单吗?
· 由于其交互性和即时反馈 , jupyternotebook促使数据科学家在全局名称空间中声明变量 , 而不是使用函数 。 这在python开发中是不好的做法 , 它限制了有效的代码重用 。
由于笔记本电脑变成容纳所有变量的大型状态机 , 因此也会损害其可重复性 。 在这种配置下 , 必须记住要哪个结果被缓存 , 哪个结果没有被缓存 , 还必须期望其他用户遵循你的单元执行顺序 。
· 笔记本在后台格式化的方式(JSON对象)使代码版本控制变得困难 。 这就是为什么笔者很少看到数据科学家使用GIT提交不同版本的笔记本 , 或合并分支以实现特定功能 。
因此 , 团队协作变得低效笨拙:团队成员开始通过电子邮件或Slack交换代码段和笔记本 , 回滚到以前的代码版本成为一场噩梦 , 文件组织开始变得混乱 。 这是在没有正确版本控制的情况下, 使用Jupyter notebook两到三周后 , 我在项目中通常看到的内容:
analysis.ipynb analysis_COPY(1).ipynb analysis_COPY(2).ipynb analysis_FINAL.ipynb analysis_FINAL_2.ipynb
Jupyter notebook非常适合探索和快速制作原型 。 它们肯定不是为可重用性或生产用途而设计的 。 如果你使用Jupyter notebook开发了数据处理管道 , 那么最好的情况是代码仅按照单元执行顺序以线性同步方式在笔记本电脑或VM上运行 。
但这并没有说明你的代码在更复杂的环境中的行为方式 , 例如 , 较大的输入数据集 , 其他异步并行任务或分配较少的资源 。 实际上我们很难测试笔记本 , 因为它们的行为有时是不可预测的 。
· 作为一个将大部分时间花在VSCode上的人 , 我常常利用功能强大的扩展来进行代码添加、样式格式化、代码结构、自动完成和代码库搜索 , 因此当切换回Jupyter时 , 笔者不禁感到有些无能为力 。 与VSCode相比 , Jupyter notebook缺少强制执行最佳编程实践的扩展 。
好了 , 抱怨到此为止 。 笔者真的很喜欢Jupyter , 认为它对设计工作非常有用 。 你肯定可以用它来引导小项目或快速创建想法原型,但你必须遵循软件工程的原则 。 当数据科学家使用notebook时 , 有时会忽略这些原则 , 让我们一起回顾下其中一些吧 。
出色代码成就机器学习:数据科学的软件工程技巧和最佳实践
本文插图
让代码再次出色的小技巧
这些技巧是从不同的项目、笔者参加的聚会以及过去合作过的软件工程师和架构师的讨论中汇编而来的 。 注意 , 以下内容皆假设我们正在编写python脚本 , 而不是notebook 。


推荐阅读