データ解析が再現するということ、あるいは Common Workflow Language が僕らにもたらしてくれるもの
「入力として与えられたデジタルデータに対して、データの変形、データ型の変換、異なるデータの統合、統計手法の適用などの作業を行い、目的とする情報を得る一連の手順」のことを「データ解析」と称した場合に、「データ解析が再現する」とはどういうことかについて考えたい。
主に科学研究の文脈において「公表された研究を別のグループが追試したところ同じ結論が得られない」ケースが少なくないことから、"Reproducibility Crisis"として科学研究の再現性の問題が指摘されている[1]。ここで注意したいのは、ある研究結果が "Repruducible" であるとされるための要件である。Chris Drummond によれば reproducibility は replicability と混同されがちであるが、両者は異なる概念であり、明確に区別する必要があるとされる[2]。どちらも日本語では「再現性」と翻訳することができるが、replicability が「オリジナルと完全に同一の手順」から「同一の結論を導く」ことを示すのに対し、reproducibility は「オリジナルの手順に従って」「同一の結論を導く」、すなわち作業者や作業環境が異なることで、手順の厳密な正確性が失われた場合でも、同じ結論が得られることを示す概念であるとされている。前述の "Reproducibile Crisis" の文脈で話されているのは、「発表された論文に記載されたとおりに、発表者とは異なる人間が異なる環境でオリジナルの手順に従った場合に、同一の結論が導かれなかった」というケースについてである。
また類似した概念であるが「オリジナルと完全に同一の手順を繰り返すことができる」、すなわち作業者、作業環境も完全に同一である repeatability もこれらと混同されがちであるが明確に異なるものとされる。Carole Goble による ISMB/ECCB 2013 Keynote のスライドでは以下のような図で説明されている。
このような「再現性」という言葉の持つ曖昧さを了解した上で、昨今話題になる「データ解析の再現性」とは何かを考えると、まず最も違和感がないのは "Repeatable data analysis" である。書捨てのワンライナーや、手順を記録しないGUIでの操作によるデータ解析などは最も repeatable でない、と考えることができるし、解析の手順を実行可能なスクリプトとして保存すること、スクリプトの実行に必要なソフトウェアやライブラリをパッケージングすること、環境設定や実行ログの保管などのエンジニアリングによって repeatability は向上する。自然科学における実験、いわば化学物質や生物試料など「モノ」を対象として物理的な作業を行う場合には repeatable であることと replicable であることには操作を行う作業者や道具の違いが寄与するが、通常コンピューターを用いたデータ解析においては、プログラムはそのまま複製が可能であり、さらに作業者の違いは問題にならないので、repeatable であることは replicable であることとほぼ同義であろう。
さらにあるデータ解析が「replicable であるだけでなく reproducible でもある」ために求められるのは「手順がオリジナルとは厳密には同じではないが、オリジナルに従った同様の作業を行って、同じ結論を得ることができる」ことである。すなわち、マシンのOSが異なる、実行される手順をプログラムした言語が異なる、実行制御のためのフレームワークが異なる、ストレージや並列化のためのアーキテクチャが異なる、などの違いがあったとしても、解析の内容が同一であれば、同じ結果を得ることができる状態を実現することで「データ解析が再現する」といえる。クラウドコンピューティングプラットフォームの普及や、ソフトウェアと実行環境を可搬にするコンテナ仮想化の技術が普及したため、OSの違いや再実装の手間などは解消されつつあるが、データ解析においては大規模な計算機環境を用いる場合の実行制御や並列化など、依然として fully reproducible なデータ解析を実現するための課題は多い。
Common Workflow Language の誕生
計測機械の出力の大規模化に伴い、大型計算機でのデータ処理の需要が急激に増したゲノム解析の分野では、同じ機械から得られる同種のデータから、目的ごとに異なるソフトウェアを組み合わせた「ワークフロー」を構築し、生物試料(サンプル)ごとに繰り返し実行し、結果を統合あるいは相互に比較する、というデータ解析が一般的となっている。目的が細分化されているため、データを変換し、外部データを参照して結合し、統計処理を施し、といった多くのステップを実施するために数百のオープンソースソフトウェアが開発されている。データ解析者は必要なソフトウェアを選択し、ワークフローを構築し、大型の計算機で並列に処理するといった日常を過ごしている。この「ワークフローの構築」と「大規模なサンプルに対する効率のよい実行」を容易にするために、ワークフローエンジンと呼ばれるソフトウェア・フレームワークが数多く開発されている。代表的なものは Galaxy, Apache Taberna などが挙げられるが、その他にも数多くのワークフロー実行系が開発、公開されている。しかし、これらのソフトウェアは作業者の負担を減らしてくれる代わりに、異なるワークフローエンジンで同一の解析を実行するための移植コストが増大し、結果 reproducibility が下がってしまうことが問題となった。
2014年にボストンで行われた Open Bioinformatics Foundation (OBF) が主催する Codefest 2014 においてこの問題についての議論があり、異なる処理系の間で同一のワークフローの実行を可能にするために、ワークフローの内容を記述し、実行系の間で交換するための標準形式の策定を目的として Common Workflow Language (CWL) プロジェクトが発足した。毎年行われる Codefest とそれに続く Bioinformatics Opensource Software Conference (BOSC) での議論、さらに有志によるオープンソースでの開発によって、徐々に普及が進んでいる。
CWLの基本的な構造はYAML形式で実行するコマンドとその入出力を記述し、入出力の関係でワークフローの構造を書くというものである。以下に単純なサンプルを示す。
cwlVersion: v1.0 class: CommandLineTool hints: DockerRequirement: dockerPull: ubuntu baseCommand: echo stdout: output.txt inputs: text: type: string inputBinding: position: 1 outputs: message: type: stdout
cwlVersion: v1.0 class: CommandLineTool hints: DockerRequirement: dockerPull: ubuntu baseCommand: [sed, -e, 's:e:o:'] inputs: file: type: File inputBinding: position: 1 outputs: result: type: stdout stdout: result.txt
cwlVersion: v1.0 class: Workflow inputs: text: string outputs: workflow_out: type: File outputSource: sed/result steps: echo: run: echo.cwl in: text: text out: [message] sed: run: sed.cwl in: file: echo/message out: [result]
CWLについての詳しい情報は、CWLに関心がある/開発に参加している日本の有志によって書かれたはじめてのCWL、さらにこの記事から始まるCWL アドベントカレンダーの記事を参照して頂きたい。
個人的な話をすると、折しも Codefest 2014 をやっているちょうどその頃に、日本の片隅でデータ解析環境の可搬性について訴えるなどしており、さらにJSON形式のオレオレなワークフロー記述言語を設計したりしていたところ、タイミングよくCWLのことを知り、こりゃあいいやとBOSC 2015にCWLを立ち上げた人々に会いに行ったところからの付き合いです。その頃はまだ Draft として仕様が公開されているだけで例も少なく、実運用はあまり現実的ではありませんでした。こりゃあこの先コケることもあるかも分からんねと思ってウォッチを続けていましたが、そのうちに 1.0 がリリースされ、実行系の標準実装も整備され、コミッタも増え、周辺ツールも充実し、CWLのインポート・エクスポートに対応する実行系も増えてきました。個人的にも1.0系になったあたりから実戦投入しながら、CWLが何をするもので、何でないのか、使うことでどんなメリットが得られるのか、あるいはデメリットがあるのかを見極めつつ、ちょっとずつ周りの人に勧めています。
CWLがどんなもので、どんなpros/consがあるかはこのアドベントカレンダーの他の記事に譲るとして、ここで強調しておくべきことは、このプロジェクトがカンファレンスのハッカソンで自然と生まれ、どの組織や企業にも属さないが、しかし色々の組織から多くのコミッタが参加する、オープンソース・コラボレーションプロジェクトとして、数年に渡り継続しているということです。これまでにも各種プログラミング言語のためのバイオデータのためのライブラリである BioPerl, BioRuby, BioPython などなど、バイオインフォマティクスに関連するオープンソースの活動はありましたが、いずれも多かれ少なかれ、同じプログラミング言語を研究に使いたいという意味で目的が一致していたのではないかと思います。しかしCWLは、ワークフローエンジンの開発者たちにとっては、CWLの開発にコミットしたところで自身のプロダクトそれ自体の質が改善するわけでもないし、業績になるかもわからない。今のところ、CWLにコミットしたおかげで随分偉くなったとか、数億のグラントが取れたとか、そういう話は聞きません。ですから、参加する人のモチベーションはただ1つ、「科学とはこうあるべきだ、そのためにこれをしなくてはならないのだ」という loyalty なのではないかと思っています。俺達はなすべきをなしている、と。世界が間違っており、間違った世界は正さなくてはならない。コミッタは研究者だけでなくエンジニアもいますし、大学や研究所だけでなく企業の人間もいます。国籍も人種もタイムゾーンも様々、普段やっている業務もみんな違いますが、そういう同じ想いを持った人が集まっている。アベンジャーズみたいなものです。CWLの本当の価値は、そういった人々が集まって議論ができる、開発ができるコミュニティができていく過程そのものなのだと思います。
「標準を作る」ことはとても難しい作業です。多くの人に受け入れられなければ標準とはなりえない、しかし仕様策定の議論に人が集まれば集まるほど、シンプルでパワフルなものを作ることは困難です。正直、CWLにも微妙だなと思う部分は結構あります。javascriptのexpressionとか頭おかしいんじゃないかと思うし、ループや条件分岐なんかコンテナの中に入れろと思う(ループと分岐はまだ議論されている段階で実装はされてないです)。出来る限り軽量にして、拡張する余地を残すに留めるべきだ、Keep it fucking simple stupid だと何度も伝えましたが、そんなことはみんな分かっていて、でもなるべく多くの人の意見を取り入れていくということも、CWLというコミュニティを育てる上でとても大事なことなのです。だから、短期的には、CWLを使ってみる、CWLの分からないことを質問してみる、必要な仕様について議論する、実装の手伝いをする、ドキュメントを書く、といった貢献が報われるかどうかはわかりません。でも、そこで得られるコミュニティとの関わり、人のつながりは絶対に失われないし、将来の財産になるはずだという実感があります。だからこそ、欧米のコミュニティと距離的時差的にコミュニケーションが取りづらい東アジアの人たちも、もっとこのコミュニティに入ってきて、一緒に議論ができればいいなと思っています。このアドベントカレンダーが目に留まって、ちょっと興味を持った人がいたら、前述のCWL Start Guide JPを読んでみる、プロジェクトのページを見てみる、生命科学系データ解析に携わる人が集まる毎月のイベント Galaxy meetupに来てみる、などなど色々の関わり方があります。一緒に世界を救いましょう。
Baker, M. (2015). Irreproducible biology research costs put at $28 billion per year. NATURE News, 9.
Drummond, C. (2009). Replicability is not reproducibility: nor is it good science.