第 17 ソフトウェアの妥当性

チャプターリード: Martijn Schuemie

ソフトウェアの妥当性に関する中心的な質問は

ソフトウェアは期待通りに動作しているか?

ソフトウェアの妥当性は、証拠の質の重要な要素です。我々の分析ソフトウェアが期待通りに動作する場合にのみ、信頼性のある証拠を生み出すことができます。セクション 17.1.1 で述べたように、すべての研究をソフトウェア開発の演習として捉え、コモンデータモデル(CDM)から推定値や図表としての結果まで、分析全体を実行する自動化スクリプトを作成することが不可欠です。このスクリプトおよびこのスクリプトで使用されるソフトウェアが妥当性を持っている必要があります。セクション 8.1 で述べたように、私たちはカスタムコードとして全体の分析を書くこともできますし、OHDSI Methods Libraryで提供される機能を使用することもできます。Methods Libraryを使用する利点は、その妥当性を確保するためにすでに慎重に作業されているため、全体の分析の妥当性を確立する作業が少なくて済むことです。

この章では、まず妥当な分析コードを書くためのベストプラクティスを述べます。その後、Methods Libraryがどのようにしてソフトウェア開発プロセスとテストを通じて検証されているかを説明します。

17.1 研究コードの妥当性

17.1.1 再現性のための自動化の必要性

伝統的に、観察研究はプロセスというよりも旅と見なされることが多いです。データベースの専門家がデータセットをデータベースから抽出し、それをデータ分析者に手渡し、データ分析者はそれをスプレッドシートエディタや他のインタラクティブツールで開いて分析を開始することがよくあります。最終的には結果が得られますが、その過程がどのように進んだのかはほとんど保存されません。旅の目的地には到達しましたが、その正確な手順を再現することはできません。この慣行は再現性がないだけでなく、透明性にも欠けるため、結果を生むために何が行われたのかを正確に知ることができず、ミスがなかったことを確認することもできません。このため、すべての証拠を生み出す分析は完全に自動化されなければなりません。自動化というのは、分析を単一のスクリプトとして実装し、CDM形式のデータベースから結果(表や図を含む)までを一度のコマンドで再実行できるようにすることです。分析の複雑さは任意ですが、たとえば単一のカウントを生成するか、何百万もの研究質問に対して経験的に校正された推定値を生成するかにかかわらず、同じ原則が適用されます。スクリプトは他のスクリプトを呼び出すことができ、それらはさらに低レベルの分析プロセスを呼び出すことができます。

分析スクリプトは任意のコンピュータ言語で実装できますが、OHDSIではRが推奨されています。DatabaseConnector Rパッケージのおかげで、CDM形式のデータに直接接続でき、その他の高度な分析は OHDSI Methods Library の他のRパッケージを通じて利用可能です。

17.1.2 プログラミングのベストプラクティス

観察分析は非常に複雑になる可能性があり、最終結果を生成するためには多くのステップが必要です。この複雑さから、分析コードのメンテナンスが困難になり、エラーを発見しにくくなります。幸いなことに、コンピュータプログラマーは、長年にわたって複雑さに対応するコードの作成に関するベストプラクティスを開発してきました。これらのベストプラクティスは、コードを読みやすく、再利用しやすく、適応しやすく、検証しやすくします。(Martin 2008) これらのベストプラクティスを完全に議論するには多くの本が必要です。ここでは、特に次の4つの重要な原則を強調します:

  • 抽象化: すべてを行う単一の大きなスクリプトを書くのではなく、「ランダムサンプルを取る」など、明確な目標を持つ「関数」と呼ばれる単位にコードを整理することができます。関数が一度作成されると、それを大きなスクリプト内で使用する際に、関数が何をするかの細部を考える必要がなくなり、関数を簡単に理解できる概念として抽象化できます。
  • カプセル化: 抽象化を機能させるために、関数の依存関係を最小限にし、明確に定義する必要があります。例として、サンプリング関数には少数の引数(例えば、データセットとサンプルサイズ)があり、1つの出力(例えば、サンプル)があります。それ以外の何も、関数の動作に影響を与えるべきではありません。関数外の変数で設定されて関数内で使用されるいわゆる「グローバル変数」は避けるべきです。
  • 明確な命名: 変数や関数は明確な命名を行い、コードがほぼ自然言語のように読みやすくするべきです。例えば、x <- spl(y, 100)と書く代わりに、sampledPatients <- takeSample(patients, sampleSize = 100)というコードを書くことができます。現代の言語には変数や関数名の長さに制限はありません。省略の誘惑に抵抗してください。
  • 再利用: 明確でカプセル化された関数を書く利点の1つは、それらを再利用できることです。これにより時間が節約されるだけでなく、コードが少なくなるため、複雑さが減り、エラーの機会も減ります。

17.1.3 コードの検証

ソフトウェアコードの妥当性を検証するためのいくつかのアプローチがありますが、観察研究を実装するコードに特に関連するものが2つあります:

  • コードレビュー: 1人がコードを書き、もう1人がそのコードをレビューします。
  • ダブルコーディング: 2人がそれぞれ独立して分析コードを書き、その後2つのスクリプトの結果を比較します。

コードレビューの利点は通常、作業量が少ないことですが、レビュー担当者がいくつかのエラーを見逃す可能性があるという欠点があります。ダブルコーディングは非常に労働集約的ですが、多くの小さな任意の選択が必要となるため、2つの個別の実装はほぼ常に異なる結果を生み出します(例えば「曝露終了まで」を終了日を含むと解釈するかどうか)。結果として、2人の独立したプログラマーはしばしば分析を調整するために一緒に作業しなければならず、その独立性が失われます。

ユニットテストなどの他のソフトウェア検証の慣行は、入力(CDMのデータ)と出力(研究結果)の間に非常に複雑な関係がある場合が多いため、ここではあまり関連性がありません。これらの慣行はMethods Library では適用されています。

17.1.4 Methods Libraryの使用

OHDSI Methods Library は、ほとんどの観察研究をわずか数行のコードで実装できるようにする、豊富な機能セットを提供しています。したがって、Methods Libraryを使用することで、研究コードの妥当性を確立する負担の多くがLibraryに移転されます。Methods Libraryの妥当性は、そのソフトウェア開発プロセスと広範囲のテストによって保証されています。 ## メソッドライブラリのソフトウェア開発プロセス

OHDSIメソッドライブラリはOHDSIコミュニティによって開発されています。このライブラリに対する提案された変更は、GitHubのイシュートラッカー(例としてCohortMethodのイシュートラッカー39)とOHDSIフォーラム40で議論されます。これらは一般に公開されており、誰でも参加できます。ライブラリにソフトウェアコードを貢献できるのはコミュニティのメンバーなら誰でも可能ですが、リリースバージョンに組み込まれる変更の最終承認は、OHDSI人口レベル推定作業グループのリーダーシップ(Marc Suchard博士とMartijn Schuemie博士)およびOHDSI個別予測作業グループのリーダーシップ(Peter Rijnbeek博士とJenna Reps博士)のみが行います。

ユーザーはGitHubリポジトリのマスターブランチから直接、または常にマスターブランチと最新の状態である「drat」というシステムを通じて、Rにおけるメソッドライブラリをインストールできます。いくつかのメソッドライブラリパッケージはRの包括的なRアーカイブネットワーク(CRAN)を通じて利用可能であり、その数は時間とともに増加する予定です。

OHDSIは、メソッドライブラリの性能の正確性、信頼性、一貫性を最大限にするために、合理的なソフトウェア開発およびテスト手法を採用しています。重要なことに、メソッドライブラリはApache License V2の規約の下でリリースされており、R、C++、SQL、およびJavaのいずれのソースコードもOHDSIコミュニティの全てのメンバー、さらには一般の人々によるピアレビューに利用可能です。したがって、メソッドライブラリに組み込まれた全ての機能は、その正確性、信頼性、および一貫性に関して継続的な批判および改善を受けることになります。

17.1.5 ソースコード管理

メソッドライブラリのソースコード全体は、GitHubを介して公にアクセス可能なバージョン管理システム「git」で管理されています。OHDSIメソッドライブラリのリポジトリはアクセス制御されています。世界中の誰でもソースコードを閲覧でき、OHDSIコミュニティのメンバーなら誰でもプルリクエストを通じて変更を提出できます。これらのリクエストを承認し、マスターブランチに変更を加え、新しいバージョンをリリースできるのは、OHDSI人口レベル推定作業グループと個別予測作業グループのリーダーシップのみです。コード変更の継続的なログはGitHubリポジトリ内で維持されており、コードとドキュメントのあらゆる変更点を反映しています。これらのコミットログは一般に公開され、レビュー可能です。

新しいバージョンは必要に応じてOHDSI人口レベル推定作業グループと個別予測作業グループのリーダーシップによってリリースされます。新しいリリースは、パッケージのバージョン番号(パッケージ内のDESCRIPTIONファイルで定義されている)が前のリリースのバージョン番号よりも大きい状態でマスターブランチに変更をプッシュすることから始まります。これにより、パッケージのチェックとテストが自動的にトリガーされます。すべてのテストが合格すると、新しいバージョンはバージョン管理システムで自動的にタグ付けされ、OHDSIのdratリポジトリに自動的にアップロードされます。新しいバージョンは三つの要素からなるバージョン番号を使用して番号付けされます:

  • 新しいマイクロバージョン(例: 4.3.2から4.3.3へ)はバグ修正のみを示します。新しい機能はなく、前方および後方の互換性が保証されます。
  • 新しいマイナーバージョン(例: 4.3.3から4.4.0へ)は機能の追加を示します。後方互換性のみが保証されます。
  • 新しいメジャーバージョン(例: 4.4.0から5.0.0へ)は主要な改訂を示します。互換性については一切保証されません。

17.1.6 ドキュメンテーション

メソッドライブラリのすべてのパッケージは、Rの内部ドキュメンテーションフレームワークを通じてドキュメント化されています。各パッケージには、そのパッケージ内で利用可能なすべての機能を説明するパッケージマニュアルがあります。関数のドキュメントとその実装の間のアライメントを促進するために、roxygen2 ソフトウェアが使用され、関数のドキュメントとソースコードを1ファイルにまとめています。パッケージマニュアルはRのコマンドラインインターフェースを通じて随時利用可能であり、パッケージリポジトリ内のPDFとして、またはウェブページとして提供されています。さらに、多くのパッケージには特定のユースケースを強調したビネットもあります。すべてのドキュメントはメソッドライブラリのウェブサイト41から閲覧することができます。

すべてのメソッドライブラリのソースコードは最終ユーザーが利用可能です。コミュニティからのフィードバックは、GitHubのイシュートラッキングシステムおよびOHDSIフォーラムを利用して受け付けています。

17.1.7 現行および過去のアーカイブバージョンの利用可能性

現行および過去のメソッドライブラリパッケージのバージョンは、二つの場所で利用可能です。まず、GitHubのバージョン管理システムには各パッケージの完全な開発履歴が含まれており、任意の時点でのパッケージの状態を再構築して取得することができます。一番重要なことは、各リリースバージョンがGitHubでタグ付けされていることです。次に、リリースされたRソースパッケージはOHDSIのGitHub dratリポジトリに保存されています。

17.1.8 メンテナンス、サポート、およびリタイアメント

現行のメソッドライブラリの各バージョンは、バグ報告、修正、およびパッチに関してOHDSIによって積極的にサポートされています。問題はGitHubのイシュートラッキングシステムおよびOHDSIフォーラムを通じて報告できます。各パッケージにはパッケージマニュアルと、ゼロ、一つ以上のビネットがあります。オンラインビデオチュートリアルが利用可能であり、対面でのチュートリアルも随時提供されています。

17.1.9 有資格者

OHDSIコミュニティのメンバーは多くの統計分野を代表し、学術機関、非営利団体、業界関連機関に所属しており、複数の大陸にまたがっています。

OHDSI人口レベル推定作業グループとOHDSI個別予測作業グループの全リーダーは認定された学術機関からのPhDを持ち、査読付きジャーナルに多数の論文を発表しています。

17.1.10 物理的および論理的セキュリティ

OHDSIメソッドライブラリはGitHub42システムにホストされています。GitHubのセキュリティ対策はhttps://github.com/securityで記述されています。OHDSIコミュニティのメンバーがメソッドライブラリに修正を加えるにはユーザー名とパスワードが必要であり、マスターブランチを変更できるのは人口レベル推定作業グループおよび個別予測作業グループのリーダーシップのみです。ユーザーアカウントは標準的なセキュリティポリシーおよび機能要件に基づいてアクセスが制限されています。

17.1.11 災害復旧

OHDSIメソッドライブラリはGitHubシステムにホストされています。GitHubの災害復旧施設についてはhttps://github.com/securityで記述されています。

17.2 メソッドライブラリのテスト

メソッドライブラリに対して実行されるテストは、パッケージ内の個々の関数のテスト(いわゆる「ユニットテスト」)と、シミュレーションを使用したより複雑な機能のテストの2種類に分類されます。

17.2.1 ユニットテスト

既知のデータと既知の結果に対してソースコードをテストするための大規模な自動化された検証テストセットがOHDSIによって維持およびアップグレードされています。各テストは、いくつかの単純な入力データを指定することから始まり、この入力に対してパッケージ内の関数の一つを実行し、その出力が期待通りのものであるかどうかを評価します。単純な関数の場合、期待される結果は明らかであることが多いです(たとえば、数人の被験者のみを含む例データに対して傾向スコアマッチングを実行する場合)。より複雑な関数の場合、期待される結果はRで利用可能な他の関数の組み合わせを使用して生成されることがあります(たとえば、Cyclops、大規模回帰エンジンは、他の回帰ルーチンとの結果の比較を含む単純な問題のテストによって検証されています)。これらのテストは合計で実行可能なソースコードのすべての行を100%網羅することを目指しています。

これらのテストは、パッケージに変更が加えられたとき(具体的には、パッケージリポジトリに変更がプッシュされたとき)に自動的に実行されます。テスト中に記録されたエラーはいずれも、作業グループのリーダーシップにメールが自動的に送信され、新しいバージョンがリリースされる前に解決されなければなりません。これらのテストのソースコードおよび期待される結果は、他のアプリケーションで適切に使用するために閲覧および使用可能です。また、これらのテストはエンドユーザーおよび/またはシステム管理者が利用可能であり、方法ライブラリのインストールプロセスの一部として実行され、インストールの正確性、信頼性、および一貫性に関する追加のドキュメントおよび客観的証拠を提供します。

17.2.2 シミュレーション

より複雑な機能については、入力に対して期待される出力が何であるかは明らかでないことがよくあります。これらの場合には、特定の統計モデルを前提として入力を生成し、その機能が既知のモデルに一致する結果を生成するかどうかを確認するために、シミュレーションが使用されることがあります。たとえば、SelfControlledCaseSeries パッケージでは、方法がシミュレーションデータにおける時間的傾向を適切に検出およびモデル化できることを確認するためにシミュレーションが使用されています。

17.3 まとめ

  • 観察研究は、CDMのデータから結果までの全解析を実行する自動化されたスクリプトとして実装されるべきです。これにより、再現性と透明性が確保されます。

  • カスタムスタディコードは、抽象化、カプセル化、明確な命名およびコードの再利用を含む、最良のプログラミングプラクティスに従うべきです。

  • カスタムスタディコードは、コードレビューまたは二重コード化によって検証できます。

  • メソッドライブラリは観察研究で使用できる検証済みの機能を提供します。

  • メソッドライブラリは、正確なソフトウェアを作成することを目的としたソフトウェア開発プロセスや、テストによって検証されています。

References

Martin, Robert C. 2008. Clean Code: A Handbook of Agile Software Craftsmanship. 1st ed. Upper Saddle River, NJ, USA: Prentice Hall PTR.