약물감시(Pharmacovigilance) ADE 분류기
생의학 도메인 사전학습이 이상반응(ADE) 문장 스크리닝에 측정 가능하지만 제한적인 성능 향상을 가져온다는 것을 엄밀한 어블레이션으로 입증했습니다 — 그리고 통계 프로토콜이 모델 선택만큼이나 중요하다는 사실도 확인했습니다.
한눈에 보기
- 분야: 생의학 NLP / 약물감시(pharmacovigilance)
- 역할: 개인 프로젝트, 2026년 봄 학기
- 기술 스택: Python, PyTorch, HuggingFace Transformers, scikit-learn, pandas, 쌍체 부트스트랩(자체 구현)
- 핵심 지표: PubMedBERT macro-F1 0.938 vs. BERT 기준선 0.920; 차이 −0.012 (95% CI [−0.024, −0.003], 0 제외)
- 상태: 완료 — 커밋된 아티팩트에서 분석 재현 가능, GPU 불필요
문제 / 배경
약물감시 팀은 대량의 증례 보고서와 임상 문서를 검토하여 이상반응(ADE)을 기술한 문장을 탐지합니다 — 이는 이후의 정보 추출이나 신호 집계에 앞서 수행되는 이진 스크리닝 단계입니다. ADE Corpus v2는 의학 증례 보고서에서 추출한 23,516개 문장으로 구성된 벤치마크 데이터셋으로, 이 과제에 널리 활용됩니다. 일반 도메인 BERT 기준선, BioBERT(PubMed + PMC 추가 사전학습), PubMedBERT(PubMed에서 처음부터 사전학습, 도메인 전용 어휘 사용)의 세 가지 트랜스포머 인코더가 이 코퍼스에 적용된 바 있으나, 기존 비교 연구들은 훈련 실행 노이즈와 테스트셋 샘플링 노이즈를 거의 구분하지 않으며, 실제 효과 크기(macro-F1 약 1퍼센트포인트)에서의 정직한 신뢰구간 역시 보고하는 경우가 드뭅니다. 본 프로젝트는 두 가지 노이즈 원인을 명시적으로 유지하는 재현 프로토콜을 통해 두 가지 구체적인 질문에 답하고자 설계되었습니다: 생의학 사전학습이 실제로 도움이 되는가, 그리고 처음부터 사전학습한 모델(PubMedBERT)이 추가 사전학습 모델(BioBERT)보다 우수한가?
접근 방식
ADE Corpus v2에 대해 구조적 어블레이션을 수행했습니다. 분할 이전에 결정론적 중복 제거 단계를 적용하여 동일 레이블의 중복 문장을 제거하고 충돌 레이블 그룹도 처리하도록 했습니다(이번 버전에는 해당 사례가 없었으나 정책은 준수됨). 이를 통해 2,621개의 중복 행을 제거하여 20,895개 인스턴스를 확보하고, 층화 80/10/10 분할을 정수 인덱스로 커밋했습니다 — 모든 모델이 동일한 데이터를 사용합니다.
세 인코더 각각에 공유된 이진 분류 헤드(풀링된 [CLS] 표현에 대한 선형 레이어,
HuggingFace AutoModelForSequenceClassification 사용)를 파인튜닝했습니다.
민감도가 다른 백본에 단일 공유 학습률을 적용하면 암묵적인 불이익이 발생하므로, 모델별 3×3
검증 스윕을 실행하여 각 모델의 최적 학습률을 선택했습니다: BERT는 1e-4, 생의학 모델 두 가지는
모두 5e-5. 어블레이션 자체는 각 모델을 해당 스윕 최적 학습률로 10개 랜덤 시드에 걸쳐 실행하며,
실행별 지표와 원시 예측 배열을 디스크에 저장하여 재학습 없이 모든 하위 분석을 재현할 수 있도록 했습니다.
핵심 통계 결정은 시드 분산과 테스트셋 샘플링 분산을 분리하는 것이었습니다. 시드 간 표준편차(macro-F1 기준 0.003–0.007)는 "훈련이 얼마나 안정적인가?"에 답합니다. 쌍체 부트스트랩 — 시드 평균 예측에 대한 1,000회 반복, 95% 백분위수 CI — 은 "모델 간 차이가 실제인가, 아니면 테스트셋 운에 의한 것인가?"에 답합니다. 두 분산 원인을 분리함으로써 한쪽 노이즈가 다른 쪽을 증폭하거나 가리는 것을 방지했습니다. 또한 macro-F1과 함께 PR-AUC를 계산했습니다: 모델이 확률 순위(PR-AUC)를 개선하더라도 0.5 결정 경계(macro-F1)에서의 성능은 개선하지 않을 수 있으며, 이 둘을 혼동하면 생의학 사전학습이 실제로 무엇을 하는지 가려지기 때문입니다.
훈련은 Colab GPU에서 실행되었으며, 부트스트랩과 그래프 작업은 커밋된
results/ 아티팩트에서 로컬로 수 초 내에 실행됩니다.
결과
argmax 임계값 0.5, 모델별 10개 시드의 테스트 지표 시드 간 평균:
| 모델 | macro-F1 | F1 (양성 클래스) | PR-AUC |
|---|---|---|---|
| bert-base-uncased | 0.9200 | 0.8729 | 0.9432 |
| BioBERT | 0.9327 | 0.8932 | 0.9549 |
| PubMedBERT | 0.9377 | 0.9013 | 0.9608 |
쌍체 부트스트랩 신뢰구간 (쌍체, 1,000회 반복, 풀링된 테스트 예측에 대한 95% CI):
| 지표 | 비교 쌍 (a vs. b) | 차이 | 95% CI | 0 제외? |
|---|---|---|---|---|
| macro-F1 | bert-base vs. BioBERT | −0.0036 | [−0.0141, +0.0070] | 아니오 |
| macro-F1 | bert-base vs. PubMedBERT | −0.0121 | [−0.0236, −0.0025] | 예 |
| macro-F1 | BioBERT vs. PubMedBERT | −0.0085 | [−0.0176, −0.0002] | 예 |
| PR-AUC | bert-base vs. BioBERT | −0.0117 | [−0.0202, −0.0052] | 예 |
| PR-AUC | bert-base vs. PubMedBERT | −0.0177 | [−0.0311, −0.0067] | 예 |
| PR-AUC | BioBERT vs. PubMedBERT | −0.0060 | [−0.0165, +0.0026] | 아니오 |
결과 패턴: 생의학 계열 두 모델 모두 PR-AUC에서 BERT보다 높은 순위를 기록하며, 해당 신뢰구간은 0을 제외합니다. macro-F1에서는 PubMedBERT만 BERT 대비 명확히 구별 가능한 차이를 보이며, BioBERT의 macro-F1 향상은 확률 순위가 개선됨에도 불구하고 0.5 임계값에서 노이즈와 구분되지 않습니다.
주요 결정 사항 / 학습 내용
분할 전에 중복 제거. 원시 ADE Corpus v2에는 2,621개의 완전히 동일한 텍스트 중복이 포함되어 있습니다. 분할 후에 중복 제거를 수행하면 동일한 문장이 훈련셋과 테스트셋 모두에 포함될 수 있어 정보 누출이 발생합니다. 분할 전에 전체적으로 먼저 제거하면 이 문제를 깔끔하게 해결할 수 있습니다.
모델별 학습률 선택은 선택이 아닌 필수입니다. BERT의 최적 학습률은 1e-4였고, 생의학 모델 두 가지는 5e-5를 선호했습니다. 하나의 백본에 맞춰 튜닝된 단일 공유 학습률을 사용하면 나머지 모델이 암묵적으로 불이익을 받게 되며, 이는 최종 수치에서는 보이지 않지만 실험 설계상 실제로 존재하는 교란 변수입니다.
두 가지 노이즈 원인을 분리. 시드 분산과 테스트셋 샘플링 분산은 서로 다른 질문에 답합니다. 이 둘을 하나의 표준 오차로 합치면 "훈련이 잘 수렴했는가?"와 "이 테스트셋이 대표성을 갖는가?"가 혼동됩니다. 쌍체 부트스트랩으로 분리함으로써 BioBERT 결과가 더 명확해졌습니다: 확률 순위는 개선되지만 (구별 가능한 PR-AUC 차이) 0.5 임계값에서의 결정 품질은 그렇지 않습니다(구별 불가능한 macro-F1 차이). 이 구분은 더 노이즈가 많은 평가 프로토콜에서는 드러나지 않았을 것입니다.
효과 크기가 중요합니다. 통계적으로 구별 가능한 성능 향상은 macro-F1 기준 약 1퍼센트포인트 수준입니다. 이는 실제로 의미 있는 차이이지만, 크지는 않습니다 — 그리고 하나의 코퍼스에서 수행된 단일 이진 스크리닝 과제에서 얻은 결과를 NER, 관계 추출, 임상 문서에 일반화할 수는 없습니다. 작성 보고서는 "생의학 사전학습이 우월하다"는 결론을 전면에 내세우는 대신 이 점을 명시적으로 언급합니다.
한계점
- 단일 테스트 분할. 모든 부트스트랩 CI는 2,090행의 단일 파티션 내의 분산을 정량화합니다. 교차 검증 또는 다중 분할 재현 실험은 테스트 샘플링 노이즈에 대한 더 완전한 시각을 제공할 것입니다.
- 단일 시드 하이퍼파라미터 스윕. 모델별 학습률은 단일 검증 실행(시드 13)에서 선택되었습니다. 더 엄밀한 프로토콜은 여러 시드에 걸쳐 스윕을 수행할 것이며, 본 연구는 낮은 비용으로 타당한 최적값을 선택하는 방식을 택했습니다.
- 과제 범위가 제한적입니다. 이진 문장 분류는 이 코퍼스에서 가장 단순한 ADE 과제입니다. 스팬 추출, 관계 연결, 임상 문서 스크리닝, 비영어권 텍스트에 대한 결과 적용은 별도 검증 없이는 불가능합니다.
- 외부 검증 없음. 모든 평가는 ADE Corpus v2 내에서 이루어졌습니다. FDA 이상반응 서술, 전자건강기록(EHR) 노트, 소셜미디어 약물감시 피드에 대한 일반화는 검증되지 않았습니다.
- 오류 분석 없음. 집계 지표만 보고되며, 각 모델이 어떤 유형의 문장을 오분류하는지에 대한 검토는 수행되지 않았습니다.
기술 스택
- 모델링: Python, PyTorch, HuggingFace Transformers (
AutoModelForSequenceClassification), BERT / BioBERT / PubMedBERT 체크포인트 - 데이터: HuggingFace Datasets를 통한 ADE Corpus v2
- 평가: scikit-learn (지표, 층화 분할), 자체 구현 쌍체 부트스트랩(NumPy)
- 분석 / 시각화: pandas, Matplotlib, Jupyter (분석 노트북은 로컬에서 GPU 없이 실행)
- 훈련: Google Colab (GPU); 이후 모든 분석은 커밋된 아티팩트에서 실행
링크
- GitHub: github.com/tysonjohnsondev/pharmacovigilance-ade-classifier
- 분석 노트북:
notebooks/analysis.ipynb— 커밋된 실행 결과에서 모든 그래프와 표를 약 10초 내에 재생성, 재학습 불필요 - 데이터셋: ADE Corpus v2 — Gurulingappa et al. 2012 via HuggingFace Datasets