Chapter 17 소프트웨어의 타당성

Chapter lead: Martijn Schuemie

이 장의 주요 질문은 다음과 같다.

소프트웨어가 우리의 예상대로 작동하는가?

소프트웨어의 타당성은 근거 품질의 필수적인 구성 요소이며, 분석 소프트웨어가 예상하는 기능을 수행하는 경우에만 신뢰 있는 근거를 생성할 수 있다. 17.1.1절에 설명한 대로 모든 연구를 소프트웨어 개발 활동으로 보고 CDM 데이터부터 추정치, 그림과 표에 이르는 결과를 생성하는 전체 분석을 실행하는 자동화된 스크립트를 만드는 것이 필수적이며, 이 스크립트와 스크립트 내에 사용된 모든 소프트웨어에 대해서 반드시 유효성 검증을 해야 한다. 8.1절에서 언급하였듯이, 전체 분석 과정을 사용자가 직접 자신의 코드로 작성하거나, 또는 오딧세이 연구방법론 라이브러리 OHDSI Methods Library에서 적절한 기능을 가져다 사용할 수도 있다. 연구방법론 라이브러리를 사용하면 이미 타당성을 보장하기 위해 여러 노력이 가해진 방법을 사용함으로써 전체 분석과정의 타당성을 정립하는 데 있어 부담을 덜 수 있다는 장점이 있다.

이 단원에서는 먼저 타당한 분석 코드를 작성하기 위한 몇 가지 모범 사례를 살펴볼 것이고, 그 이후 소프트웨어 개발 과정과 검사를 통해 연구방법론 라이브러리의 타당성을 검사하는 방법에 관해 설명할 것이다.

17.1 분석 코드의 타당성

17.1.1 재현성 충족을 위한 자동화

전통적으로 관찰연구는 종종 일련의 과정이라기보다는 여행에 비유되기도 한다. 데이터베이스 전문가는 데이터베이스에서 데이터 모음을 추출하여 이를 데이터 분석가에게 넘겨주고, 데이터 분석가는 스프레드시트 편집기나 다른 편집 도구를 사용하여 데이터 모음을 열고 분석을 수행한다. 마지막으로 분석 결과가 생성되지만, 어떻게 이 결과가 도출되었는지는 거의 보존되지 않는다. 여행의 목적지에는 도달했지만, 그곳에 도달하기 위해 취한 정확한 단계를 추적할 수는 없다. 이 방법은 재현할 수 없고 not reproducible, 투명성이 부족하기 때문에 lack transparency 온전히 받아들여지지 않는다.

따라서 (이런 한계를 극복하기 위해서) 근거를 생성하는 모든 분석은 완전히 자동화되어야 한다. 분석의 자동화라는 의미는 단일 스크립트에 CDM 형식의 데이터베이스에서부터 표와 그림을 포함하는 전체 분석 결과를 생성해 내는 전 과정을 담아내어, 단 하나의 명령으로 모든 전체 과정을 재실행 할 수 있도록 구현하는 것이다. 분석은 단순히 수를 세는 것부터 수백만 건의 연구 문제에 대해 경험적으로 보정된 추정치를 생성하는 것까지 다양한 복잡성을 띠지만, 동일한 원칙이 적용된다. 이 스크립트는 다른 스크립트를 호출하여 하위 분석 절차를 진행하도록 할 수 있다.

분석 스크립트는 모든 컴퓨터 언어를 통해 구현할 수 있으나, 오딧세이에서는 R 언어를 선호한다. DatabaseConnector 라는 R 패키지 덕분에 R 환경에서 CDM 형식의 데이터에 직접 연결하여 사용할 수 있으며, 오딧세이 연구방법론 라이브러리 OHDSI Methods Library 내의 다른 R 패키지를 통해 고급 분석을 사용할 수 있다.

17.1.2 프로그래밍 모범 사례

관찰연구 분석 방법은 최종 결과를 생성하기 위해 많은 단계를 거치거나 매우 복잡해질 수 있다. 이러한 복잡성으로 인해 분석 코드를 유지 관리하기 더욱 어려워지고, 오류가 발생할 가능성이 높아질 뿐 아니라 오류를 인식하기조차 어려울 수 있다. 다행히도 많은 컴퓨터 프로그래머는 수년 동안 복잡한 코드를 작성하고 다루는 데 있어서 이 코드를 읽고, 재사용하고, 적용하고, 검증하는 과정이 수월하도록 관리하는 몇 가지 모범 사례를 개발해 두었다. (Martin 2008) 이 우수 사례는 상당한 분량을 차지하므로, 여기서는 4가지 중요한 원칙을 강조하도록 하겠다.

  • 축약화 Abstraction: 모든 것을 수행하는 하나의 큰 스크립트 (소위 “스파게티 코드”라고 하며 코드 라인간 종속성이 있다. 예를 들면, 10행에서 설정된 값이 1000행에서 사용되는 경우를 들 수 있다) 를 작성하는 대신 코드를 “함수”라고 하는 작은 단위로 구성할 수 있다. 함수는 명확한 목표를 가져야 하며 (예를 들면 “무작위 샘플 추출”) 일단 생성하고 나면, 다른 스크립트에서도 직관적으로 사용할 수 있다. 이처럼 우리는 함수를 통해서 이해하기 쉬운 개념으로 코드를 추상화하고 축약할 수 있다.
  • 캡슐화 Encapsulation: 축약 작업이 진행되기 위해서는 함수 간의 의존성을 명확하게 정의하고 최소화해야 한다. 예로 들었던 무작위 샘플 추출 기능에서는 몇 가지 인수 arguments (예를 들어, 데이터 모음과 추출 집단의 크기)와 하나의 출력값 (예를 들어, 추출 집단)이 있어야 한다. 이 함수가 수행하는 기능에 있어서 어떠한 것도 영향을 줄 수 없어야 하며, 함수 외부에서 설정된 소위 “전역 변수 global variables”를 함수 내에서 사용하지 말아야 한다.
  • 명확한 명명 Clear naming: 변수 혹은 함수의 이름은 명확해야 하며, 자연어처럼 읽을 수 있도록 하라. 예를 들어, x <- spl(y, 100) 보다는 우리가 읽을 수 있도록 sampledPatients <- takeSample(patients, sampleSize = 100) 처럼 작성하라. 축약어를 사용하고자 하는 충동을 억눌러라. 현대 언어는 변수, 함수의 이름으로 사용하는 데 있어 충분히 다양하게 사용할 수 있다.
  • 재사용 Reuse: 명확하고 잘 캡슐화된 기능을 작성하였을 때 얻는 장점 중 하나는 계속해서 재사용할 수 있다는 점이다. 이렇게 하면 시간이 절약될 뿐 아니라 코드가 줄어 복잡성이 줄고, 오류가 발생할 가능성이 줄어 든다.

17.1.3 코드 검증

소프트웨어 코드의 타당성을 검증하기 위한 여러 가지 방법이 있지만, 관찰연구에서 사용하는 코드와 관련하여 두 가지 방법을 소개하고자 한다.

  • 코드 삼자 검토 Code review: 한 사람이 코드를 작성하고, 다른 사람이 코드를 검토한다.
  • 이중 코딩 Double coding: 두 사람이 독립적으로 분석 코드를 작성하고, 이후에 스크립트 실행 결과를 비교한다.

코드 삼자 검토는 일반적으로 작업량이 적지만, 검토자가 일부 오류를 놓칠 수 있다는 단점이 있다. 이중 코딩은 다소 노동 집약적이지만 오류를 놓칠 가능성이 적다. 이중 코딩의 다른 단점은 두 개별적인 코드의 구현이 대부분, 아니 언제나 다른 결과를 나타낸다는 점이다. 이는 임의적인 사소한 선택으로 인해 발생한다. (예를 들어 “노출 종료까지”라는 말은 노출 종료일을 포함하는가 포함하지 않는가?) 결과적으로, 독립적인 두 프로그래머는 독립적으로 이중 코딩을 수행해야 함에도, 분석을 상호 조정하기 위해 협력하여야 할 필요가 있다.

단위 검정 unit testing과 같은 다른 소프트웨어 검증 방법은 관찰 연구 특성상 데이터의 입력 (CDM 내의 데이터) 과 출력 (연구 결과) 사이에 높은 복잡도의 관계를 가진 일회성 과정이므로 다소 유용하지 못하기 때문에 관련성이 적다고 할 수 있다. 이러한 다른 검증방법은 연구방법론 라이브러리 내에서는 적용 되어있다는 점을 주의하라.

17.1.4 연구 방법론 라이브러리의 활용

오딧세이 연구방법론 라이브러리 OHDSI Methods Library 는 수많은 기능을 제공하기 때문에, 대부분의 관찰 연구를 몇 줄의 코드만으로도 구현할 수 있다. 따라서 연구방법론 라이브러리를 사용하면 개인 연구 내에서 연구자가 타당성을 입증해야 하는 부담이 연구방법론 라이브러리로 옮겨가게 된다. 연구방법론 라이브러리의 타당성은 자체의 소프트웨어 개발 과정과 광범위한 시험을 통해 보장된다.

17.2 연구 방법론 라이브러리 소프트웨어의 개발 과정

오딧세이 연구방법론 라이브러리는 오딧세이 커뮤니티에서 개발하였으며, 라이브러리에 변경이 제안된 사항은 GitHub의 issue tracker (예를 들어 CohortMethod issue tracker55)와 오딧세이 포럼56, 이 두가지 장소에서 논의된다. 두 장소 모두 공개되어 있다. 커뮤니티의 모든 구성원은 소프트웨어 코드를 라이브러리에 제공할 수 있지만, 기존에 배포된 소프트웨어 버전에 대한 변경사항은 오딧세이 인구 수준 추정(PLE) 그룹 리더십 (현재 Marc Sucahrd 박사, Martigin Schuemie 박사)과 환자 수준 예측(PLP) 그룹 리더십 (현재 Peter Rijinbeek 박사, Jenna Reps 박사)만이 최종 결정할 수 있다.

사용자는 연구방법론 라이브러리의 GitHub 저장소(master branch)에서 직접 설치할 수 있고, “drat”이라는 시스템을 이용하여서도 최신 버전을 설치할 수 있다. R의 Comprehensive R Archive Network(CRAN)을 통해서 다양한 연구방법론 라이브러리 패키지를 사용할 수 있으며, 이용할 수 있는 패키지의 수는 점점 증가할 것으로 예상된다.

오딧세이 연구방법론 라이브러리의 정확성, 신뢰성 및 일관성을 최대화하기 위해서 합리적인 소프트웨어 개발법 및 시험 방법을 사용한다. 연구방법론 라이브러리의 모든 원천 코드는 Apache License V2로 배포됨에 따라, R, C++, SQL, Java 등 어떤 언어로 작성이 되었어도, 오딧세이 커뮤니티의 모든 회원과 대중이 동료 평가 peer review를 할 수 있다. 따라서, 연구방법론 라이브러리 내부에 구현된 모든 기능은 정확성, 신뢰성 그리고 일관성의 향상을 위해서 지속적인 비판과 이로 인한 개선이 이루어져야 한다.

17.2.1 원천 코드 관리

연구방법론 라이브러리의 모든 원천 코드는 github을 통해 접근할 수 있는 원천 코드 버전 관리 시스템인 git을 통해 관리되며, 오딧세이 연구방법론 라이브러리 저장소의 접근을 관리하고 있다. 전 세계 누구나 원천 코드를 볼 수 있으며, 오딧세이 커뮤니티의 멤버 누구나 pull request라고 부르는 코드 변경 요청을 제출할 수 있다. 오딧세이 인구 수준 추정(PLE) 그룹과 환자 수준 예측(PLP) 그룹 리더십은 이 코드 변경 요청을 승인할 수 있고, master branch을 변경하고 새로운 버전을 배포할 수 있다. 지속적인 코드 변경사항 로그는 GitHub 저장소에 유지되며, 코드와 문서의 모든 변동 사항을 반영한다. 이러한 변경사항 로그가 대중으로부터의 검토를 가능하게 한다.

새로운 버전은 필요 시 두 오딧세이 그룹의 리더십의 판단 하에 배포 된다. 프로그램 패키지의 DESCRIPTION 파일에 정의된 대로 패키지 버전 번호가 배포 버전의 번호보다 큰 master branch로 변경사항을 push 하여 새 배포가 시작된다. 이는 자동으로 패키지를 테스트하고, 모든 검사를 통과하면 버전관리 시스템에서 새 버전에 자동으로 태그가 지정되고 패키지가 오딧세이 drat 저장소에 자동으로 업로드된다. 새 버전은 3가지 표기 원칙에 따라 번호가 부여된다

  • 세부 버전 Micro version (4.3.2 에서 4.3.3으로 변경하는 경우) 버그를 수정한 경우에 한 함. 새로운 기능 추가는 없으며, 상위, 하위호환성도 보장됨.
  • 부 버전 Minor version (4.3.3 에서 4.4.0으로 변경하는 경우) 기능적으로 추가가 되었을 때. 하위 호환성이 보장됨.
  • 주 버전 Major version (4.4.0 에서 5.0.0으로 변경하는 경우) 주요 개선사항이 생겼을 때. 호환성을 보장하지 않음.

17.2.2 문서화

연구방법론 라이브러리의 모든 패키지는 R 내부 문서화 프레임워크를 통해 문서화 된다. 각 패키지에는 패키지에서 사용 가능한 기능을 설명하는 정의서를 가지고 있다. 기능 정의서 및 기능 구현에 관한 사항을 정리하기 위해서 기능 문서와 원천 코드를 단일 파일로 결합하는 roxygen2 소프트웨어를 사용한다. 패키지 설명서는 R의 명령 입력을 통해 패키지 저장소에 PDF 형태로 제공된다. 또한 많은 패키지는 패키지의 활용법을 담은 도움글 vignettes을 가지고 있다. 모든 문서는 연구방법론 라이브러리의 웹사이트에서 확인할 수 있다.57

모든 연구방법론 라이브러리의 원천 코드는 실제 사용자가 사용할 수 있으며, GitHub의 issue 시스템 및 오딧세이 포럼을 사용하여 커뮤니티의 피드백을 받을 수 있다.

17.2.3 현재 및 과거 버전으로의 접근

연구방법론 라이브러리 패키지의 현재 및 과거 버전은 아래 두 위치에서 접근할 수 있다. 먼저 GitHub 버전관리 시스템은 각 패키지의 전체 개발 과정을 가지고 있으며, 각 단계의 패키지의 상태를 재구성하고 검색할 수 있다. 각각의 출시 버전이 GitHub에 태그 되어있다. 두 번째는 오딧세이 GitHub의 drat 저장소에 R 소스 패키지가 저장되어 있다.

17.2.4 유지 보수, 지원 및 중단

오딧세이는 각 최신 버전의 연구방법론 라이브러리 내 버그를 보고하고 수정하고 패치하는 것을 적극적으로 지원하고 있다. GitHub 이슈 시스템과 오딧세이 포럼을 활용하여 관련 문제를 제기 및 보고할 수 있다. 각 패키지는 패키지 설명서와 추가적으로 도움글, 온라인 비디오 튜토리얼 영상이나 자료가 제공된다.

17.2.5 검증된 인력

오딧세이 커뮤니티의 회원은 통계학의 여러 분야에 해당되는 사람들로 구성되어 있고, 학계, 비영리단체, 산업계 등의 다양한 기반을 가진 전 세계 사람들로 구성되어 있다.

오딧세이의 인구 수준 추정(PLE) 그룹과 환자 수준 예측(PLP) 그룹의 리더는 공인된 교육기관의 박사 학위를 보유하고 있으며, 동료평가 저널에 다양하게 논문을 게재해오고 있다.

17.2.6 물리적, 논리적 보안체계

오딧세이 연구방법론 라이브러리는 GitHub58 시스템에서 호스팅되고 있다. GitHub의 보안에 관한 부분은 다음 사이트에서 확인할 수 있다. https://github.com/security 오딧세이 커뮤니티의 모든 구성원은 연구방법론 라이브러리를 변경 요청할 수 있으며, 이 때 사용자아이디와 비밀번호가 요구된다. 변경사항을 승인은 인구 수준 추정(PLE) 그룹과 환자 수준 예측(PLP) 그룹의 리더를 통해서 가능하다. 사용자 계정은 표준 보안정책 및 기능 요구사항에 따라 접근이 제한된다.

17.2.7 복구 체계

오딧세이 연구방법론 라이브러리는 GitHub 시스템에 호스팅되어 있다. GitHub의 사고 복구 체계는 다음 사이트에서 확인할 수 있다: https://github.com/security

17.3 연구방법론 라이브러리 기능 검사

우리는 연구 방법론 라이브러리를 패키지의 단순 기능 검사 (단위 검정)와 시뮬레이션을 이용한 고난도 기능검사의 두 가지로 나누어 테스트를 수행하고 있다.

17.3.1 단위 검증

잘 알려진 데이터 및 결과에 대해서는 원천 코드를 자동으로 테스트 할 수 있는 자동 유효성 검사가 오딧세이에 의해서 운영되고 개선되고 있다. 각 유효성 검사는 일부 입력데이터를 지정하고, 검사 대상의 패키지 중 하나의 기능을 실행하고 출력이 정상적인지의 여부를 평가한다 (예를 들어 소수의 환자군을 가진 임시 데이터를 가지고 성향점수 매칭을 시행함). 더욱 복잡한 기능의 경우 R에서 사용할 수 있는 다른 기능을 조합하여 예상 결과를 생성해볼 수 있다 (예를 들어 대용량 회귀분석 엔진인 Cyclops는 간단한 문제에 대한 결과를 여러 회귀 방법을 통해서 비교하여 테스트함). 오딧세이에서는 실행 가능한 코드라면 100% 테스트 할 수 있도록 하는 것을 목표로 하고 있다.

이 검사 기능은 패키지가 수정되었을 때 자동으로 수행되게 되어 있다 (정확히는 변화된 패키지가 GitHub 저장소에 push 되었을 때). 검사 도중 에러 발생 시 자동으로 그룹 리더들에게 이메일이 발송되고, 새로운 패키지 버전 이전에 문제를 반드시 해결하도록 하고 있다. 이 검사에 대한 코드와 예상 결과는 검토 가능할 뿐 아니라 적절한 다른 환경에서도 적용할 수 있으며, 관리자뿐만 아니라 일반 사용자도 설치 과정의 일부로 실행하여 연구방법론 라이브러리의 정확성, 신뢰성 및 일관성에 대한 객관적 증거를 제공할 수 있다.

17.3.2 모의시행

더 복잡한 기능은 입력했을 때 어떤 결과를 나타내는지 뚜렷하지 않은 경우도 있다. 이러한 경우 모의 시행 simulation을 하기도 하는데, 특정한 통계 모델에서 나온 값을 입력하고 알려진 모델의 결과값을 생성하는지 여부를 확인한다. 예를 들어 SelfControlledCaseSeries 패키지에서 모의 시행은 분석 방법이 임시 데이터를 이용해서 시간의 흐름을 적절히 파악해서 모델을 만들었는지 검증하는 데 사용한다.

17.4 요약

  • 관찰 연구는 재현성과 투명성을 보장하기 위해서 CDM 데이터에서부터 결과에 이르기까지 전체 분석을 실행하는 자동화된 스크립트를 구현해야 한다.

  • 연구에 사용하는 분석 코드는 축약화, 캡슐화, 명확한 명명법, 코드 재사용이라는 좋은 프로그래밍 방법을 준수해야 한다.

  • 코드 삼자 검토 또는 이중 코딩을 사용하여 사용자의 코드를 검증할 수 있다.

  • 연구방법론 라이브러리는 관찰 연구에 사용할 수 있는 검증된 기능을 제공한다.

  • 연구 방법론 라이브러리는 검증된 소프트웨어 및 검사법 개발을 목표로 하는 개발 과정을 통해 검증된다.