# 인크레틴안전신호레이더 / IncretinSafetySignal-Kor

> 공개 FAERS 이상반응을 인크레틴 계열 약물군에 대해 **disproportionality**로 자동 채점하여
> "새로 떠오르는 안전 신호"를 알려주는 **오프라인 우선** 안전 레이더.

- **도메인:** Obesity (비만)
- **카테고리:** 연구 알림 (공개 FAERS disproportionality 안전신호 큐레이션)
- **MVP 한 줄:** 인크레틴 계열 약물군의 공개 FAERS 이상반응을 disproportionality로 자동 채점해 "새로 떠오르는 신호"를 알려주는 오프라인 우선 안전 레이더.

---

## ⚠️ 의학적 디스클레이머 (필독)

- 본 도구는 **참고용·연구용**입니다.
- **disproportionality(불균형 분석)는 인과관계가 아닙니다.** 신호(signal)는 "추가 검토가 필요한
  통계적 불균형"일 뿐, 위해(harm)의 증명이 아닙니다.
- FAERS 등 **자발적 보고(spontaneous report)** 데이터에는 다음 혼란요인이 내재합니다:
  - **보고 편향(reporting bias):** 분모(실제 노출 인구)가 불명 → 발생률(incidence)이 아님.
  - **notoriety bias:** 미디어·규제 경고 후 동일 AE 보고가 급증.
  - **적응증 혼재(channeling):** 같은 약물이 당뇨(diabetes)·비만(obesity)에 모두 쓰여 교란 가능.
- **본 저장소의 데이터는 전부 합성(synthetic) 시연 데이터**이며 실제 환자/실제 FAERS 데이터가 아닙니다.
- 임상적 의사결정의 단독 근거로 사용하지 마십시오.

---

## 핵심 기능 5가지

1. **약물군 사전 정의** — 인크레틴 계열 활성성분·브랜드명·한글표기 동의어 사전
   (semaglutide/Ozempic/Wegovy, tirzepatide/Mounjaro/Zepbound, retatrutide 등) +
   MedDRA PT 정규화(공개 PT 명칭 소문자 매칭). → `data/drug_synonyms.json`
2. **disproportionality 엔진** — 약물–AE 2×2 표로 **PRR·ROR·χ²·IC(BCPNN 근사)·EBGM 근사** + 95% CI
   계산. 신호 임계값 **PRR≥2 & χ²≥4 & n≥3** 적용. (표준 라이브러리 `math`만 사용, 공식 직접 구현)
3. **신규 신호 델타** — 직전 분기 대비 신호 **등장/소멸/강도 변화** diff
   (예: "신규 신호 aspiration; ROR 5.8→19.1").
4. **혼란요인 주석** — 신호마다 적응증 혼재·notoriety bias·보고 편향·희소 셀 경고 자동 부착.
5. **워치 다이제스트** — 관심 AE 그룹(GI·간담도·근골격·신경안과·호흡기)별 신호 요약 **Markdown** 출력.

---

## 실행법

요구사항: **Python 3.9+ 표준 라이브러리만** (pandas/scipy/duckdb 불필요, 외부 설치 없음, 네트워크 없음).

```bash
cd 2026-06-06-2-incretin-safety-signal-kor

python3 main.py --help                       # 옵션 전체
python3 main.py --selftest                   # 공식 손계산 검산
python3 main.py --quarters                   # 데이터 분기 목록

# 신호 표
python3 main.py --signals --quarter 2026Q1
python3 main.py --signals-only --group GI --quarter 2026Q1
python3 main.py --signals --drug 마운자로     # 동의어/브랜드명/한글 인식

# 신규 신호 델타 (직전 분기 대비)
python3 main.py --delta

# 혼란요인 주석 (신호만)
python3 main.py --confounders --drug tirzepatide --quarter 2026Q1

# 워치 다이제스트 (Markdown)
python3 main.py --digest --quarter 2026Q1
python3 main.py --digest --quarter 2026Q1 --out data/digest_2026Q1.md

# (옵션 없이 실행 시) 최신 분기 신호 표 + 델타 요약
python3 main.py
```

**정적 대시보드:** `index.html`을 브라우저로 열면 됩니다. 데이터가 파일에 인라인되어 있어
**네트워크 없이** 신호 표(필터·정렬)와 델타 하이라이트가 동작합니다. (외부 CDN/fetch 없음)

> `--online`은 openFDA 실시간 호출을 위한 자리표시자이며, **오프라인 우선 정책에 따라 의도적으로
> 비활성(네트워크 코드 미구현)** 입니다. 기본 경로는 항상 로컬 합성 데이터입니다.

---

## 통계 공식 (검증 가능)

2×2 분할표 (해당 약물·해당 AE = a):

|              | AE(해당) | AE(기타) |
|--------------|:-------:|:-------:|
| **약물(해당)** |    a    |    b    |
| **약물(기타)** |    c    |    d    |

- `PRR = (a/(a+b)) / (c/(c+d))`
- `ROR = (a·d) / (b·c)`
- `χ²` = Yates 연속성 보정 포함(표 출력) / 미보정(`--selftest` 검산용) 둘 다 구현.
- `IC = log2(a / E)`, `E = (a+b)(a+c)/N` — **BCPNN의 정보성분 경량 근사**
  (정통 BCPNN은 사전분포 기반 IC025 산출 필요; 본 구현은 점추정 근사임 — 코드 주석 명시).
- `EBGM ≈ a/E` — Empirical Bayes 수축(shrinkage) 미적용 단순 관측/기대비 근사
  (정통 EBGM/MGPS는 감마-포아송 베이즈 모형 필요; **근사임을 명시**).
- 95% CI: ROR/PRR 모두 **로그 스케일 정규근사**, 0 셀이면 Haldane(+0.5) 보정.

---

## 데이터 출처

- **openFDA FAERS** (`https://api.fda.gov/drug/event.json`)의 집계 스키마를 모사.
- 단, **오프라인 우선이므로 실제 외부 네트워크 호출은 하지 않습니다.** 본 저장소에는
  openFDA 2×2 집계를 **모사한 합성 시드**(`data/faers_synthetic.json`, 2개 분기)만 포함.
- MedDRA PT 명칭은 공개적으로 통용되는 Preferred Term 표기를 사용(정규화 간소화).

---

## 검수 체크리스트

- [ ] `python3 -c "import ast; ast.parse(open('main.py').read())"` → 구문 통과
- [ ] `python3 main.py --selftest` → "검산 일치: OK"
- [ ] `python3 main.py --signals --quarter 2026Q1` → 신호 표 출력, SIGNAL 행 존재
- [ ] `python3 main.py --delta` → 신규/소멸/강도변화 섹션 출력
- [ ] `data/*.json` 3종 로드 성공
- [ ] `index.html` 존재 + 네트워크 없이 렌더(외부 http/CDN/fetch 없음)
- [ ] 손계산 검산 1건 (QA.md 기록)

상세 검수 로그는 [`QA.md`](QA.md) 참조.

---

## 파일 구성

```
2026-06-06-2-incretin-safety-signal-kor/
├── README.md                     # 본 문서
├── main.py                       # Python CLI 진입점 (표준 라이브러리만)
├── index.html                    # 정적 오프라인 대시보드 (데이터 인라인)
├── QA.md                         # 검수 로그
└── data/
    ├── faers_synthetic.json      # 합성 FAERS 2×2 집계 (2개 분기, 델타 시연)
    ├── drug_synonyms.json        # 인크레틴 약물군 동의어 사전
    ├── ae_groups.json            # AE 그룹 → MedDRA PT 매핑
    ├── dashboard_data.json       # (엔진이 생성) HTML/검수용 채점 결과
    └── digest_2026Q1.md          # (예시) 다이제스트 출력물
```
