科学编程的再现性

时间:2010-04-29 01:07:11

标签: scientific-computing

除了产生不正确的结果之外,科学编程中最令人担忧的一个问题是无法再现您生成的结果。哪些最佳实践有助于确保您的分析具有可重现性?

8 个答案:

答案 0 :(得分:13)

       
  • 在线发布原始原始数据,并免费下载。
  •    
  • 使代码库开源并可在线下载。
  •    
  • 如果在优化中使用随机化,则多次重复优化,选择产生的最佳值或使用固定的随机种子,以便重复相同的结果。
  •     
  • 在执行分析之前,您应该将数据拆分为“培训/分析”数据集和“测试/验证”数据集。在“训练”数据集上执行您的分析,并确保您获得的结果仍然保留在“验证”数据集上,以确保您的分析实际上是可推广的,而不是简单地记忆所讨论的数据集的特性。

前两点非常重要,因为使数据集可用允许其他人对相同数据执行自己的分析,这会提高您自己分析有效性的可信度。此外,使数据集在线可用 - 特别是如果您使用链接数据格式 - 使爬虫可以将数据集与其他数据集聚合,从而实现具有更大数据集的分析......在许多类型的研究中,样本量有时候太小而不能对结果充满信心......但是共享数据集可以构建非常大的数据集。或者,有人可以使用您的数据集来验证他们在其他数据集上执行的分析。

此外,使您的代码成为开源代码可以让您的同行审查代码和过程。通常这样的评论会导致发现缺陷或进一步优化和改进的可能性。最重要的是,它允许其他研究人员改进您的方法,而无需实施您已经从头做的所有事情。当研究可以专注于改进而不是重新发明轮子时,它极大地加快了研究的步伐。

至于随机化......许多算法依靠随机化来实现其结果。随机和蒙特卡罗方法相当普遍,虽然它们已被证明在某些情况下会聚,但仍有可能得到不同的结果。确保获得相同结果的方法是在代码中使用一个循环来调用计算一定次数,并选择最佳结果。如果你使用足够的重复,你可以期望找到全局或接近全局的最佳值,而不是陷入局部最优。另一种可能性是使用预定的种子,虽然不是,恕我直言,这是一种很好的方法,因为你可以选择种子,让你陷入局部最优。此外,无法保证不同平台上的随机数生成器将为该种子值生成相同的结果。

答案 1 :(得分:9)

我是一名嵌入研究地球物理学家团队的软件工程师,我们目前(一如既往)致力于提高我们按需复制结果的能力。以下是从我们的经验中收集到的一些指示:

  1. 将所有内容置于版本控制之下:源代码,输入数据集,makefile等
  2. 构建可执行文件时:我们在可执行文件中嵌入了编译器指令,我们使用UUID标记构建日志,并使用相同的UUID标记可执行文件,计算可执行文件的校验和,自动生成所有内容并自动更新数据库(好的,它是只是一个平面文件,包含构建细节等
  3. 我们使用Subversion的关键字在每个源代码中包含修订号(等),并将它们写入生成的任何输出文件中。
  4. 我们进行了大量(半)自动回归测试,以确保新版本的代码或新构建变体产生相同(或类似的)足够的结果,并且我正在研究一系列程序来量化确实发生了变化。
  5. 我的地球物理学家同事确实分析了计划对投入变化的敏感性。我分析了他们(代码,而不是地理)对编译器设置,平台等的敏感性。
  6. 我们目前正在开发一个工作流程系统,它将记录每个作业的详细信息:输入数据集(包括版本),输出数据集,使用的程序(包括版本和变体),参数等 - 通常称为出处。一旦启动并运行,发布结果的唯一方法就是使用工作流程系统。任何输出数据集都将包含它们自己出处的详细信息,但我们尚未对其进行详细设计。

    我们对于将数值结果再现到最不重要的数字非常(或许太)放松了。我们工作的科学基础,以及我们基本数据集测量中固有的误差,不支持超过2或3秒的任何数值结果的有效性。

    我们当然不会为同行评审发布代码或数据,我们从事石油业务。

答案 2 :(得分:8)

已经有很多好的建议。我会添加(两者都来自痛苦的经历 - 出版之前,谢天谢地!),

1)检查结果的稳定性:

  • 尝试几种不同的数据子集
  • 重新输入
  • 重组输出
  • 调整网格间距
  • 尝试几个随机种子(如适用)

如果它不稳定,你就没有完成。

发布上述测试的结果(或者至少保留证据,并提及你做过)。

2)抽查中间结果

是的,您可能会在一个小样本上开发该方法,然后研究整个混乱。磨削正在进行中,几次达到中间峰值。更好的是,尽可能收集有关中间步骤的统计数据,并查找其中的异常迹象。

再次,任何惊喜,你必须回去再做一次。

并且,再次保留和/或发布此内容。


我喜欢的事情包括

  • 源代码控制---无论如何你都需要它。
  • 记录构建环境。出版的内容很不错。
  • 计划提供代码和数据。

另一个没有人提到过:

3)记录代码

是的,你正在忙着写它,并且可能正忙于设计它。但我并不是说一份详细的文件,而是对所有惊喜的一个很好的解释。无论如何你都需要写出来,所以把它当作纸上的先机。并且您可以将文档保存在源代码管理中,以便您可以随意丢弃不再适用的块 - 如果您需要它们,它们将会存在。

使用构建指令和“如何运行”模糊来构建一个README并不会有什么坏处。如果您要提供代码,人们会问这些东西......另外,对我来说,回头看看有助于我保持正轨。

答案 3 :(得分:6)

发布程序代码,使其可供审核。

这不是针对你的,但这是我的咆哮:

如果您的工作是由纳税人资金赞助,如果您将结果发布在同行评审期刊中,请在开源许可下或公共领域提供源代码。 我厌倦了阅读有人提出的这个伟大的算法,他们声称这是x,但没有提供验证/检查源代码的方法。如果我看不到代码,我无法验证你的结果,因为算法的实现可能会有很大的差异。

在我看来,将纳税人支付的工作放在研究人员无法接触的范围内并不是道德的。推动论文反对科学,但在可用的工作方面却没有给公众带来任何实际好处。

答案 4 :(得分:4)

我认为以前的很多答案都错过了你的问题的“科学计算”部分,并回答了适用于任何科学的非常一般的东西(使数据和方法公开,专门针对CS)。

他们缺少的是你必须更专业:你必须具体说明你使用的编译器版本,编译时使用的开关,你使用的操作系统版本,所有版本的所有版本您链接的库,您正在使用的硬件,同时在您的计算机上运行的其他内容,等等。有发表的论文,其中每一个因素都以非平凡的方式影响结果。

例如(在Intel硬件上)您可能正在使用一个使用FPU的80位浮点数的库,进行O / S升级,现在该库现在可能只使用64位双精度数,并且您的结果可以大幅提升如果你的问题病情最小,那就改变了。

编译器升级可能会改变默认的舍入行为,或者单个优化可能会颠倒2个指令完成的顺序,而且对于病态系统,繁荣,不同的结果也是如此。

哎呀,有一些关于次优算法在实际测试中显示“最佳”的时髦故事,因为它们是在笔记本电脑上测试的,当它过热时会自动降低CPU的速度(这是最佳算法所做的)。 p>

源代码或数据都不会显示这些内容。

答案 5 :(得分:2)

在互联网上发布代码,数据和结果。在论文中写下URL。

另外,将您的代码提交给“竞赛”。例如,在音乐信息检索中,有MIREX

答案 6 :(得分:1)

以某种方式记录配置参数(例如,如果您可以将某个变量设置为某个值)。这可能在数据输出中,也可能在版本控制中。

如果您一直在更改程序(我是!),请确保记录您正在使用的程序版本。

答案 7 :(得分:0)

也许这有点偏离主题,但要关注@Jacques Carette关于科学计算细节的主要内容,请参阅Verification& amp;验证(“V& V”)文献中的一些特定问题,特别是那些模糊可重复性和正确性之间界限的问题。现在云计算正变得越来越成为大型模拟问题的一种选择,随机分组随机CPU之间的可重复性将更受关注。此外,我不知道是否可以将“正确性”与结果的“可重复性”完全分开,因为您的结果源于您的计算模型。尽管您的模型似乎适用于计算群集A但不适用于群集B,但您需要遵循一些指导原则来保证您的工作流程以使此模型合理。具体到再现性,V& V社区中存在一些嗡嗡声,将可重复性误差纳入整体模型的不确定性(我将让读者自己研究)。

例如,对于计算流体动力学(CFD)工作,黄金标准是the ASME V&V guide。对于应用的多物理场建模和仿真人员(其一般概念适用于更大的科学计算社区),这是内化的重要标准。