第 17 章 ソフトウェアの妥当性
著者: Martijn Schuemie
ソフトウェアの妥当性に関する中心的な問題は
ソフトウェアが期待通りに動作しているか?
ソフトウェアの妥当性は、エビデンスの質にとって不可欠な要素です。つまり、私たちの分析ソフトウェアが期待通りに機能してこそ、信頼性の高いエビデンスを生成できるのです。セクション 17.1.1 で説明されているように、すべての研究をソフトウェア開発の演習と見なすことが不可欠であり、共通データモデル(CDM)のデータから推定値や表形式の数値などの結果に至るまでの分析全体を実行する自動スクリプトを作成します。このスクリプト、およびこのスクリプトで使用されるソフトウェアはすべて検証されなければなりません。セクション 8.1 で説明されているように、分析全体をカスタムコードとして記述することも、OHDSI Methods Libraryで利用可能な機能を用いることもできます。Methods Libraryを使用する利点は、その妥当性を確保するためにすでに多大な注意が払われているため、分析全体の妥当性を確立する負担が軽減されることです。
本章では、まず有効な分析コードの記述に関するベストプラクティスについて説明します。次に、ソフトウェア開発プロセスとテストを通じて、Methods Libraryがどのように検証されているかについて説明していきます。
17.1 研究コードの妥当性
17.1.1 再現性のための自動化の必要性
従来、観察研究はプロセスというよりも旅路として捉えられることがよくありました。データベースの専門家がデータベースからデータセットを抽出し、それをデータ分析者に渡します。データ分析者はスプレッドシートエディタやその他のインタラクティブなツールで開き、分析作業を開始します。最終的に結果が生成されますが、その生成過程はほとんど保存されません。旅路の目的地に到達しても、そこへ至るまでの正確なステップを辿ることはできません。このようなやり方は、再現できないというだけでなく、透明性にも欠けるため、まったく受け入れられないのです。結果を導くために何が行われたのかが正確にわからないため、ミスがなかったことを検証することもできません。
したがって、エビデンスを生み出す分析はすべて完全に自動化されなければなりません。自動化とは、分析が単一のスクリプトとして実装されることを意味し、テーブルや図表を含め、CDM形式のデータベースから結果まで、単一のコマンドで分析全体をやり直せるようにしなければなりません。分析は任意の複雑さで実施でき、おそらくは単一のカウントのみを生成するか、あるいは何百万もの研究課題に対する経験的に校正された推定値を生成することになるでしょう。しかし、同じ原則が適用されます。スクリプトは他のスクリプトを呼び出すことができ、さらに下位レベルの分析プロセスを呼び出すこともできます。 分析スクリプトは、どのようなコンピュータ言語でも実装できますが、OHDSIではR言語が推奨されています。RのDatabaseConnectorパッケージのおかげで、CDM形式のデータに直接接続でき、また、OHDSI Methods Libraryの他のRパッケージを通じて、多くの高度な分析機能を利用できます。
17.1.2 プログラミングのベストプラクティス
観察分析は、最終結果を得るまでに多くのステップを必要とするため、非常に複雑になる可能性があります。この複雑性により、分析コードの維持が難しくなり、エラーが発生する可能性が高まるだけでなく、エラーに気づきにくくなる可能性もあります。幸いにも、コンピュータプログラマーは長年にわたり、複雑な問題に対処できるコードを書くためのベストプラクティスを開発してきました。そのコードは、読みやすく、再利用、適応、検証が容易になっています(Martin 2008)。これらのベストプラクティスについて詳しく説明すると、多くの書籍が書けるほどですので、ここでは以下の4つの重要な原則に焦点を当てます。
抽象化: すべてを実行する巨大なスクリプトを1つ書くのではなく、コードの行と行の間の依存関係がどこからどこへでも及ぶ(例えば、10行目に設定された値が1,000行目で使用される)いわゆる「スパゲッティ・コード」を避けるために、コードを「関数」と呼ばれる単位で整理することができます。関数は明確な目的を持つべきであり、例えば「ランダムなサンプルを抽出する」といったものです。関数を作成すれば、その関数が何を行うのかの詳細を考えることなく、より大きなスクリプトでその関数を使用することができます。
カプセル化:抽象化を機能させるには、関数の依存関係を最小限に抑え、明確に定義する必要があります。例のサンプリング関数は、いくつかの引数(例えばデータセットとサンプルサイズ)と1つの出力(例えばサンプル)を持つべきです。関数の動作に影響を与えるものは他に何もあってはなりません。いわゆる「グローバル変数」、つまり関数外で設定される変数は、関数の引数ではありませんが、関数内で使用されるため、避けるべきです。
わかりやすい命名:変数や関数はわかりやすい名前を付けるべきであり、コードはほとんど自然言語のように読みやすくすべきです。例えば、
x <- spl(y, 100)
の代わりに、sampledPatients <- takeSample(patients, sampleSize = 100)
と記述できます。省略したくなる衝動を抑えるようにしてください。最新の言語では、変数名や関数名の長さに制限はありません。再利用:明確で、うまくカプセル化された関数を書くことの利点のひとつは、それらを再利用できることが多いということです。これは時間を節約するだけでなく、コードの量が減ることによって複雑さが減り、エラーの可能性も少なくなることを意味します。
17.1.3 コードの検証
ソフトウェアコードの妥当性を検証する方法はいくつかありますが、観察研究を実施するコードには特に次の2つの方法が有効です。
コードレビュー:1人がコードを書き、別の1人がそのコードをレビューする。
ダブルコーディング:2人がそれぞれ独立して分析コードを書き、その後、2つのスクリプトの結果を比較する。
コードレビューには通常、作業量が少ないという利点がありますが、欠点としては、レビュアーがエラーを見逃す可能性があることです。一方、ダブルコーディングは通常、非常に手間がかかりますが、エラーを見逃す可能性は低く、不可能ではないことです。ダブルコーディングのもう一つの欠点は、多くの些細な恣意的な選択(例えば、「exposure end(曝露終了)」をexposure end date(曝露終了日)を含むと解釈すべきか、それともそうでないか)が必要なため、2つの別々の実装ではほとんどの場合に異なる結果が得られることです。その結果、本来独立しているはずの2人のプログラマーが、分析結果を一致させるために協力する必要が生じ、独立性が損なわれることになります。
単体テストなどの他のソフトウェア検証手法は、研究が通常、入力(CDMのデータ)と出力(研究結果)の間に高度な複雑な関係があるため、1回限りの活動であり、これらの手法はあまり適切ではありません。これらの手法は、Methods Libraryで適用されていることに注意してください。
17.1.4 Methods Libraryの使用
OHDSI Methods Library は、多数の関数を提供しており、ほとんどの観察研究は数行のコードを記述するだけで実施することができます。 Methods Library を使用することで、研究コードの妥当性を立証する負担のほとんどが Library に移行されます。 Methods Library の妥当性は、そのソフトウェア開発プロセスと広範なテストによって保証されています。
17.2 Methods Libraryのソフトウェア開発プロセス
OHDSI Methods Library はOHDSIコミュニティによって開発されています。Libraryへの変更提案は、GitHubのissue tracker(例えば、CohortMethod issue tracker59)とOHDSIフォーラムの2つの場所で議論されます60。いずれも一般公開されています。コミュニティのメンバーは誰でもライブラリにソフトウェアコードを寄与することができますが、リリースされたソフトウェアのバージョンに組み込まれる変更の最終承認は、OHDSI 集団レベルの推定ワークグループのリーダー(Marc Suchard博士とMartijn Schuemie博士)およびOHDSI 患者レベルの予測ワークグループのリーダー(Peter Rijnbeek博士とJenna Reps博士)のみが行います。
ユーザーはGitHubのリポジトリにあるマスターブランチから直接、または「drat」と呼ばれるシステムを通じて、RにMethods Libraryをインストールすることができます。Methods Libraryのパッケージの多くはRのComprehensive R Archive Network(CRAN)を通じて入手でき、この数は今後さらに増える見込みです。
OHDSIでは、Methods Libraryのパフォーマンスの正確性、信頼性、一貫性を最大限に高めるため、適切なソフトウェア開発やテスト方法を採用しています。重要なのは、Methods LibraryがApache License V2の条件に基づいてリリースされているため、Methods Libraryの基盤となるすべてのソースコード(R、C++、SQL、Javaのいずれであっても)は、OHDSIコミュニティのすべてのメンバーに、また一般公開されています。したがって、Methods Libraryに具現化されたすべての機能は、その正確性、信頼性、一貫性に関して、継続的な評価と改善の対象となります。
17.2.1 ソースコード管理
Methods Libraryのソースコードはすべて、GitHubを通じて一般公開されているソースコードバージョン管理システム「git」で管理されています。OHDSIMethods Libraryのリポジトリはアクセス制御されています。世界中の誰もがソースコードを閲覧でき、OHDSIコミュニティのメンバーであれば誰でも、いわゆるプルリクエストを通じて変更を提出することができます。OHDSI 人口レベル推定作業部会および患者レベル予測作業部会のリーダーシップのみが、こうしたリクエストを承認し、マスターブランチに変更を加え、新しいバージョンをリリースすることができます。GitHub リポジトリ内では、コード変更の継続的なログが管理されており、コードとドキュメントの変更のあらゆる側面が反映されています。これらのコミットログは、一般公開されています。
新しいバージョンは、OHDSI 集団レベルの推定ワークグループや患者レベルの予測ワークグループのリーダーシップにより、必要に応じてリリースされます。新しいリリースは、前のリリースのバージョン番号よりも大きなパッケージのバージョン番号(パッケージ内のDESCRIPTIONファイルで定義されている)をマスターブランチにプッシュすることから始まります。これにより、パッケージの確認とテストが自動的に開始されます。すべてのテストに合格すると、新しいバージョンがバージョン管理システムに自動的にタグ付けされ、パッケージがOHDSIドラフトリポジトリに自動的にアップロードされます。新しいバージョンは、3つのコンポーネントからなるバージョン番号で表されます。
新しいマイクロバージョン(例:4.3.2 から 4.3.3)は、バグ修正のみを示します。新しい機能はなく、前方および後方互換性が保証されます
新しいマイナーバージョン(例:4.3.3 から 4.4.0)は、機能追加を示します。後方互換性のみが保証されます
新しいメジャーバージョン(例:4.4.0から5.0.0)は、大幅な改訂を示します。互換性については保証されません。
17.2.2 ドキュメンテーション
Methods Library内のすべてのパッケージは、Rの内部ドキュメントフレームワークを通じて文書化されています。各パッケージには、そのパッケージで利用可能なすべての関数が記載されたパッケージマニュアルがあります。関数のドキュメントと関数の実装を一致させるため、Roxygen2ソフトウェアを使用して、関数のドキュメントとソースコードを1つのファイルにまとめています。パッケージマニュアルは、Rのコマンドラインインターフェースからオンデマンドで利用でき、パッケージリポジトリではPDFとして、またウェブページとしても利用できます。さらに、多くのパッケージには、そのパッケージの特定の使用事例を強調するビネットも用意されています。すべてのドキュメントは、Methods Libraryウェブサイトで閲覧できます 61。
Methods Libraryのソースコードはすべてエンドユーザーが利用できます。コミュニティからのフィードバックは、GitHubの課題追跡システムとOHDSIフォーラムを使用して促進されます。
17.2.3 現行および過去のアーカイブバージョンの利用可能性
Methods Libraryパッケージの現在および過去のバージョンは、2つの場所で入手できます。まず、GitHubバージョン管理システムには各パッケージの開発の全履歴が含まれており、各時点でのパッケージの状態を再現して取得することができます。最も重要なのは、GitHubで各リリースバージョンにタグ付けがされていることです。次に、リリースされたRソースパッケージは、OHDSIのGitHub dratリポジトリに保存されています。
17.2.4 メンテナンス、サポート、およびリタイアメント
Methods Libraryの各最新バージョンは、OHDSIによりバグレポート、修正、パッチに関して積極的にサポートされています。GitHubの課題追跡システムやOHDSIフォーラムを通じて問題を報告することができます。各パッケージにはパッケージマニュアルがあり、0個、1個、または複数のビネットがあります。オンラインビデオチュートリアルが利用可能であり、また、対面式のチュートリアルも随時提供されています。
17.2.5 有資格者
OHDSIコミュニティのメンバーは、複数の統計分野を代表しており、複数の地域にまたがる学術機関、非営利団体、業界関連機関に所属しています。 OHDSI集団レベルの推定ワークグループやOHDSI 患者レベルの予測ワークグループのすべてのリーダーは、認定された学術機関で博士号を取得しており、査読付き学術誌に多数の論文を発表しています。
17.2.6 物理的および論理的セキュリティ
OHDSI Methods LibraryはGitHub62システムでホストされています。GitHubのセキュリティ対策については、https://github.com/securityを参照してください。OHDSIコミュニティのすべてのメンバーがMethods Libraryに変更を加えるには、ユーザー名とパスワードが必要です。また、マスターブランチに変更を加えられるのは、集団レベルの推定ワークグループと患者レベルの予測ワークグループのリーダーのみです。ユーザーアカウントは、標準的なセキュリティポリシーや機能要件に基づいてアクセスが制限されています。
17.2.7 災害復旧
OHDSI Methods Libraryは GitHub システム上でホストされています。GitHub の災害復旧施設については、https://github.com/security に説明があります。
17.3 Methods Libraryのテスト
Methods Libraryで実行されるテストには、パッケージ内の個々の関数に対するテスト(いわゆる「単体テスト」)と、シミュレーションを使用したより複雑な機能に対するテストの2種類があります。
17.3.1 単体テスト
OHDSI により、ソースコードを既知のデータおよび既知の結果に対してテストできるように、多数の自動検証テストが維持、更新されています。各テストは、いくつかの単純な入力データの指定から始まり、この入力に対してパッケージのいずれかの関数を実行し、出力が期待通りのものであるかどうかを評価します。単純な関数では、期待される結果は明白であることがほとんどです(例えば、少数の対象者のみを対象としたサンプルデータで傾向スコアのマッチングを行う場合など)。より複雑な関数では、Rで利用可能な他の関数との組み合わせて、期待される結果が生成されることがあります(例えば、当社の大規模回帰エンジンであるCyclopsは、Rの他の回帰ルーチンを使用して単純な問題の結果を比較することでテストします)。私たちは、これらのテストを実行可能なソースコードの行の合計100%をカバーすることを目指しています。
これらのテストは、パッケージに変更が加えられた場合(具体的には、変更がパッケージリポジトリにプッシュされた場合)に自動的に実行されます。テスト中にエラーが検出された場合は、ワークグループのリーダーに自動的に電子メールが送信され、パッケージの新しいバージョンのリリース前に解決されなければなりません。これらのテストのソースコードおよび期待される結果は、必要に応じて確認および他のアプリケーションで使用することができます。これらのテストは、エンドユーザーおよび/またはシステム管理者にも利用可能であり、インストールプロセスの一部として実行することで、Methods Libraryのインストールに関する正確性、信頼性、一貫性に関する追加の文書および客観的な証拠を提供することができます。
17.3.2 シミュレーション
より複雑な機能については、入力に対して期待される出力がどのようなものであるべきかが常に明らかであるとは限りません。このような場合、特定の統計モデルを基に入力を生成し、機能がこの既知のモデルに沿った結果を生成するかどうかを検証するために、シミュレーションが使用されることがあります。例えば、SelfControlledCaseSeriesパッケージでは、シミュレーションデータにおける一時的な傾向を検出し、適切にモデル化できることを検証するために、シミュレーションが用いられます。