One corticolimbic gain, four factors, four clocks — and a fifth clock inside the ruler.
이 모델은 불안을 하나의 무차원 피질–변연계 이득(corticolimbic gain)
E_amy × S_glu
Φ = ───────────────────────────
C_pfc·(1 + e_ex·EXPECT) × I_gaba
으로 쓴다. 분자에 두 인자, 분모에 두 인자가 있는 비(ratio) 이며, 네 인자는 각각 다른 약물군이 서로 다른 시간상수로 움직인다. 그리고 이 모든 것은 HAM-A라는 포화형(saturating) 척도를 통해 읽히는데, 그 척도는 자기 자신의 다섯 번째 시계(기대효과 + 평균회귀)를 얹는다.
| 인자 | 의미 | 움직이는 약물 | 시간상수(모델 계산값) |
|---|---|---|---|
I_gaba |
GABA-A 억제 효율 (분모) | 벤조디아제핀 | 0.5 d (효과 t50 2.5 d) |
S_glu |
시냅스전 글루타메이트 방출확률 (분자) | 프레가발린 (α2δ-1) | 2.0 d (효과 t50 4.5 d) |
C_pfc |
전전두엽 하향 조절 용량 (분모) | SSRI/SNRI, CBT | 40 d (효과 t50 35 d) |
E_amy |
편도체/BNST 흥분 구동 (분자) | CBT, 만성 5-HT | 수 주 |
EXPECT+FLUCT |
기대효과 + 등록 시점 평균회귀 | (모든 팔에 공통) | 가장 빠름 — 8주 위약효과의 57%가 1주에 |
세 가지 결과가 이 대수식에서 가정이 아니라 계산으로 나온다 — 그리고 세 가지 사전 기대는 반증되어 그대로 보고된다.
| 파일 | 내용 |
|---|---|
gad_qsp_model.dot · .svg · .png |
기계론적 지도 — 206 노드 · 19 클러스터 · 301 엣지 |
gad_python_reference.py |
실행 가능한 참조 구현 (49 ODE). README·mrgsolve·Shiny의 모든 숫자는 여기서 나온다 |
gad_calibrate.py |
보정. 5개 파라미터, 6개 숫자. 어떤 시도가 왜 실패했는지까지 기록 |
gad_analysis.py → gad_reference_output.txt |
12개 시나리오 블록 전체 실행 결과 (472행) |
gad_mrgsolve_model.R |
mrgsolve 모델 (50 구획). 참조 구현을 식 단위로 옮긴 것 |
mkmrgsolve.py |
위 R 파일 생성기 — 보정값·초기조건이 어긋날 수 없게 만든다 |
gad_shiny_app.R |
Shiny 대시보드 (12 탭) |
gad_references.md · mkrefs.py |
118개 문헌 / 113개 고유 PMID, 전부 PubMed에서 실시간 조회 |
gad_calibration.json · gad_attractor_cache.npz |
보정 결과와 무투약 어트랙터 캐시 |
calib.log · calib_stage1_joint.log |
보정 로그 (실패한 첫 시도 포함) |
렌더링·실행:
dot -Tsvg gad_qsp_model.dot -o gad_qsp_model.svg
dot -Tpng -Gdpi=150 gad_qsp_model.dot -o gad_qsp_model.png
python3 gad_calibrate.py # 5개 파라미터 재보정
python3 mkmrgsolve.py # gad_mrgsolve_model.R 재생성
python3 gad_analysis.py # gad_reference_output.txt 재생성
python3 mkrefs.py # gad_references.md 재생성
Rscript -e 'shiny::runApp("gad_shiny_app.R")'적합된 파라미터는 5개뿐이다.
| 파라미터 | 적합 대상 |
|---|---|
fluct0 = 3.85, kfl = 2.00 /d |
위약군 곡선의 모양 — Khan 2011 (PMID 21694613) 1주 −5.94 / 8주 −11.10, Rickels 2005 (PMID 16143734) 4주 −8.40 |
k5ht_eff = 0.126 |
에스시탈로프람–위약 차 −2.45 (Slee 2019 NMA, PMID 30712879) |
emax_pgb = 0.094 |
프레가발린–위약 차 −2.79 (Slee 2019 NMA) |
emax_a2 = 0.571 |
알프라졸람 1.5 mg–위약 차 −2.50 (Rickels 2005) |
dvisit = 0.30과 e_ex = 0.55는 적합하지 않고 구조적으로 고정했다. 이유는 §6.
적합 결과 (6개 숫자):
placebo week 1 : -5.75 target -5.94
placebo week 4 : -9.60 target -8.40 <-- 미스
placebo week 8 : -10.09 target -11.10 <-- 미스
escitalopram 10 delta : -2.45 target -2.45
pregabalin 300 delta : -2.79 target -2.79
alprazolam 1.5 delta : -2.50 target -2.50
위약군 잔차는 구조적이다. 두 시험의 위약 곡선은 −5.94 → −8.40 → −11.10으로 거의 직선인데, 이 모델의 위약 반응은 4주 무렵 정체한다. 정직하게 말하면 이 모델은 8주까지 계속 떨어지는 위약 곡선을 만들지 못한다.
나머지는 전부 out-of-sample. 아래 §3–§5의 모든 숫자가 그렇다.
| 약물 | 모델 | 보고값 | |
|---|---|---|---|
| 에스시탈로프람 10 mg | −2.45 | −2.45 | ← 적합 |
| 프레가발린 300 mg | −2.79 | −2.79 | ← 적합 |
| 벤라팍신 ER 150 mg | −4.24 | −2.69 | 과대예측 |
| 둘록세틴 60 mg | −2.53 | −3.13 | 과소예측 |
| 케티아핀 XR 150 mg | −0.57 | −3.60 | 큰 미스 |
| 부스피론 45 mg | −0.27 | (효과 있으나 표본 작음) | 과소예측 |
SNRI 두 개의 방향이 서로 반대로 틀렸다는 점이 의미 있다 — NET 점유율 곡선 (EC50 260 ng/mL vs 46 ng/mL)이 벤라팍신에 너무 관대하고 둘록세틴에 너무 인색하다.
| 팔 | 1주 모델 | 1주 보고 | 8주 모델 | 8주 보고 |
|---|---|---|---|---|
| 위약 | −5.75 | −5.94 | −10.09 | −11.10 |
| 케티아핀 50 | −6.24 | −7.47 | −10.61 | −13.31 |
| 케티아핀 150 | −6.18 | −8.19 | −10.66 | −13.54 |
| 케티아핀 300 | −6.10 | −7.23 | −10.68 | −11.87 |
모델은 케티아핀에 거의 효과를 주지 않는다. 이 모델에서 케티아핀의 유일한 항불안 경로는 노르케티아핀의 NET 억제(150 mg에서 점유율 0.295)인데, 실제 케티아핀은 5-HT2A/2C 길항, α1 차단, H1 차단을 통해 작동하며 이 모델에는 그 경로가 없다. 보고된 역-U자 용량반응(300 mg < 150 mg)도 재현하지 못한다 — §9의 가상 집단에서 이상반응 기반 탈락을 넣어도 −10.16(300) vs −9.88(150)으로 여전히 단조롭다. 이것은 파라미터 문제가 아니라 구조의 결손이며, 그대로 보고한다.
급성기 보정만 가지고, 12주 개방표지 → 반응자 무작위 배정 → 76주 추적을 설계 그대로 시뮬레이션한 결과:
| 모델 | 보고값 | |
|---|---|---|
| 개방표지 반응자 비율 | 65% | 76% |
| 76주 재발률, 에스시탈로프람 계속 | 17% | 19% |
| 76주 재발률, 위약 전환 | 66% | 56% |
| 위험비 (위약/약물) | 3.83 | 4.04 |
급성기 보정은 이 숫자들을 전혀 본 적이 없다. 약을 끊으면 C_pfc가 자기 시간상수
(30 d)를 따라 도로 내려가고, 그것이 두 팔을 갈라놓는다 — 76주 시점 Φ_n 1.14 (계속)
대 1.41 (위약).
Rickels는 유의성 패턴으로 보고했다: 프레가발린은 정신·신체 둘 다 유의,
알프라졸람은 정신만 유의(신체 p = 0.21). 모델은 그 방향을 재현한다 —
위약대비 차의 신체/정신 비가 프레가발린 1.33, 알프라졸람 0.89. S_glu는 근긴장
항목을 직접 먹이지만 I_gaba는 Φ를 통해서만 신체 항목에 닿기 때문이다.
이 저장소의 규칙상, 모델을 만들기 전에 세운 기대가 계산에 의해 무너지면 조용히 지우지 않고 그대로 적는다.
(1) "SSRI 용량반응이 평평한 것은 SERT 점유 쌍곡선 때문이다" — 아니다. 점유율은 확실히 평평해진다 (10 mg 0.744 → 20 mg 0.853, 상대 +15%). 그런데 HAM-A 차는 −2.45 → −4.23로 73% 커진다. 재흡수 항이 바닥에 가까워지면서 세포외 5-HT가 가파르게 오르기 때문이다 (1.98 → 2.62). Baldwin 2006 (PMID 16946363)은 20 mg가 10 mg보다 유의하게 낫지 않다고 보고했는데, 모델은 1.8점의 우위를 예측한다. 임상적 평탄성은 이 모델 안에 없는 무언가(가장 유력하게는 20 mg에서의 탈락)에서 와야 한다.
(2) "병용은 척도 포화 때문에 하위가산(sub-additive)이다" — 반대다. Φ는 세 쌍 모두에서 정확히 곱셈적이다 (오차 −0.4%, −1.2%, −0.7%). 이게 이 섹션의 강한 결과다. 그런데 HAM-A에서는 107%, 115%, 112% — 초가산 (super-additive) 이다. HAM-A 연결함수는 효과가 작을 때 볼록하고 바닥에 가까워져야 오목해지는데, GAD 시험의 3–4점짜리 효과는 볼록 구간에 있다. 따라서 임상적 예측이 뒤집힌다: GAD 병용요법은 단독요법 차의 합을 넘어야 한다.
(3) "Φ가 비(ratio)이므로 중증일수록 약물–위약 차가 커진다" — 상쇄된다. 경증/중등도/중증 3분위에서 차이는 −1.68 / −1.76 / −1.46으로 평평하고 비단조다. 중증 환자는 척도의 더 가파른 곳에 있지만 위약 반응도 함께 크다 (−12.34 대 −8.21). 중증 환자 선별로 검정력을 얻는다는 논리는 이 모델에서 따라 나오지 않는다.
(a) 점유–효과 간극이 계산으로 나온다. SERT는 0.5일만에 절반 차단되고 HAM-A는 35일만에 절반 움직인다 — 70배. 이건 적합된 게 아니라 느린 두 단계의 직렬 연결이다:
| 단계 | t50 |
|---|---|
| SERT 점유 | 0.5 d |
| 5-HT1A 자가수용체 탈감작 (게이트) | 10.5 d |
| 세포외 5-HT | 14.5 d |
| BDNF | 23.5 d |
| C_pfc | 40.0 d |
| HAM-A | 35.0 d |
같은 점유율(0.574 → 0.744)에서 급성 5-HT 상승은 12.9%, 만성은 98.6%. 게이트가 열려서다. 그래서 발현 곡선이 지수함수가 아니라 S자다.
(b) 다섯 번째 시계는 차이를 줄이지 않는다. 파묻는다. 1주 시점 위약군은 −5.75점 움직이는데 그 위에 얹히는 최대 약물 증분은 −1.75점이다. 개별 환자를 1주에 관찰하는 임상의는 무엇을 처방했든 다섯 번째 시계를 보고 있다. 약물의 시계는 오직 차이에서만 보인다.
(c) 검정 민감도(assay sensitivity)가 유도된다. e_ex만 쓸어보면
(약리는 한 줄도 안 바뀐다):
| e_ex | 위약 ΔHAM-A | esc10 차 | pgb300 차 | lzp3 차 |
|---|---|---|---|---|
| 0.00 | −3.85 | −1.57 | −2.03 | −1.75 |
| 0.55 | −10.09 | −2.45 | −2.79 | −2.91 |
| 1.00 | −16.95 | −3.10 | −3.20 | −3.17 |
| 1.50 | −20.03 | −0.04 | −0.21 | −0.09 |
기대효과가 매우 큰 사이트에서는 약리가 동일한데도 측정 가능한 효과가 사라진다.
기대가 C_pfc를 올리고, C_pfc는 Φ의 분모에 있고, HAM-A는 Φ의 포화함수이기
때문이다. 실패한 다기관 시험의 흔한 사인(死因)이 여기서 가정이 아니라 결과로 나온다.
(d) 벤조디아제핀: 아단위 하나가 두 개의 시계를 만든다. 로라제팜 3 mg/d 지속 투여에서
| 1일 | 14일 | 168일 | |
|---|---|---|---|
α1 풀 R_a1 (진정) |
0.895 | 0.380 | 0.377 |
α2/3 풀 R_a2 (항불안) |
0.999 | 0.972 | 0.892 |
진정은 2주 만에 42% 사라지는데 항불안 풀은 168일에도 0.892다. 이것이 "진정에는 내성이 붙지만 항불안 효과에는 거의 안 붙는다"는 임상 관찰의 아단위 수준 설명이다.
(e) 벤조 브릿지는 준 만큼 돌려받는다. 에스시탈로프람에 로라제팜 3주를
얹으면 1주에 −1.76점을 벌지만, 감량 구간에서 DEPEND가 풀리면서 6주에는
−0.22, 12주에는 −0.01로 수렴한다.
이 파일들에는 실패한 시도가 지워지지 않고 남아 있다. gad_calibrate.py의
독스트링과 calib_stage1_joint.log를 보라.
-
첫 번째 합동 적합은 위약 1주를 구조적으로 놓쳤다.
kfl(등록 시점 평균회귀의 감쇠율)을 손으로 0.075/d에 고정해 두었기 때문이다. 기대효과 항은 WORRY·SLEEPD· AUTON을 거쳐야 하므로 원리적으로 빠를 수 없고, 빠를 수 있는 건FLUCT뿐인데 그게 묶여 있었다.kfl을 풀자 1주가 맞았다. -
위약 반응의 "실제 하향조절"과 "선택 편향"은 세 개의 요약 숫자로 분리되지 않는다.
fluct0,kfl,dvisit을 함께 적합하자 최적화기는dvisit을 하한 (0.02)으로 밀어붙이고 위약 반응 전체를 가산적FLUCT항(9.72점, τ 5.8 d)에 넣어버렸다. 세 숫자만 보면 완벽한 적합이지만, 그렇게 하면 §5(c)의 검정 민감도 논증이 의존하는 생물학적 기대 경로가 조용히 꺼진다. 그래서dvisit과e_ex는 적합하지 않고 구조적으로 고정하고, 대신 §5(c)에서 명시적으로 쓸어본다. 이 저장소에서 기대효과 크기에 의존하는 모든 주장은 구조적 선택에 대한 주장이며, 그렇게 표시했다.
kfl은 결국 상한(2.0/d, τ 0.35 d)에 붙었다. 즉 적합은 등록 시점 상승분이
사실상 즉시 사라지기를 원한다 — 실제 증상 변동이라기보다 기저점수 인플레이션
이라는 뜻이다. 이것도 그대로 적어둔다.
Python 참조 구현을 실제로 돌려보지 않았다면 전부 그럴듯한 채로 남았을 것들:
- HPA 축이 발산했다. CRH → 코르티솔 → GR 하향조절 → 되먹임 약화 → CRH의
루프 이득이 1을 넘었다. 과잉 코르티솔이 모든 하류 효과에
x/(1+0.5x)로 들어가도록 바꿔 유계로 만들었다. - 질환 루프 전체의 이득도 1을 넘었다. 편도체 → 수면결핍 → 편도체가 발산.
Φ의 모든 하류 결과가
phi_n이 아니라 포화 초과항z = (Φn−1)/(1+(Φn−1)/3)을 읽도록 하고,E_amy에 로지스틱 천장(EAMAX = 3),SLEEPD에 천장(4)을 걸었다. - CBT 창(window)이 서로를 덮어썼다. 한 번의 실행에 CBT 팔이 둘 이상 있으면 나중 것이 앞 것을 끄고 있었다 — "CBT 단독" 팔이 위약과 수치적으로 완전히 동일하게 나와서 발각됐다. 누적으로 고쳤다.
- 약효를 절대 변화량에 적합했다. 그 결과 알프라졸람의 총 변화(−10.9)는 정확히 맞추면서 위약대비 차는 두 배 넘게 틀렸다. 위약 모델의 오차를 약물 파라미터가 전부 흡수한 것이다. 차이(difference) 에 적합하도록 바꿨다.
- 프레가발린이 점수에 닿는 경로가 둘이었다. 직접 증상완화 항(
b_pgb,h_pgb)이 크게 잡혀 있어서 보정이emax_pgb를 0.029로 밀어버렸다 — 즉S_glu가 아무 일도 안 하는데 약은 듣는 상태. "S_glu는 프레가발린의 인자"라는 주장이 공허해진다. 직접 경로를 줄이고 구조적 선택임을 명시했다. - 질환 중증도의 눈금이 3분의 1만큼 어긋나 있었다. DIS = 1의 안정 HAM-A가
25.9였는데, 시험이 보고하는 24–27은 등록 시점 점수다. 등록 기준은 변동의
꼭대기를 선별한다.
kdis_*를 2.5로 나눠 안정 점수 19.4 / 등록 점수 23.1이 되도록 고쳤다. 가상 집단이 없었으면 못 봤을 오류다.
- 적분기: 손으로 쓴 RK4(dt = 30분, 피험자에 대해 벡터화)를
scipyLSODA (rtol 1e-9)와 대조 — 7일간 에스시탈로프람 10 mg QD + 프레가발린 300 mg BID 이후 HAM-A 상대오차 1.3e-06, 최악의 상태변수 1.1e-03(감쇠 중인 흡수 구획). - 스텝 크기: dt를 절반(1/96 d)으로 줄여도 HAM-A는 2.0e-05만 움직인다.
- 어트랙터: 무투약 평형점은 dt = 1/8, 1/12, 1/24에서 소수점 4자리까지 동일 (평형점은 RK4 사상의 고정점이므로 스텝에 무관).
- mrgsolve 이식:
$MAIN의 초기조건은 참조 구현의 어트랙터를 DIS의 3차식으로 적합한 것이며 최대 상대오차 5.7e-03(SLEEPD). 생성기(mkmrgsolve.py)가 보정값과 초기조건을 함께 써넣으므로 두 구현이 어긋날 수 없다.
정직한 한계 하나: 이 환경에 R 툴체인이 없어서 gad_mrgsolve_model.R과
gad_shiny_app.R은 실행되지 않았다. R 파일은 Python 참조 구현을 식 단위로
대조해 작성했으나 그 자체로 검증되지는 않았다. 또한 mrgsolve에는 방문 시점의
이산적 기대효과 갱신을 도즈로 표현할 방법이 없어, 빠르게 감쇠하는 VISCUE 구획
(kvis = 48/d)으로 같은 사상을 근사했다 — 헤더에 명시했다.
49개 ODE (mrgsolve에서는 VISCUE 포함 50 구획):
| 블록 | 상태변수 |
|---|---|
| PK (20) | 에스시탈로프람 2구획+효과부위, 벤라팍신+ODV, 둘록세틴, 프레가발린, 벤조디아제핀+효과부위, 부스피론+1-PP, 케티아핀+노르케티아핀 |
| 신경전달 (4) | SHT, AUTO(5-HT1A 자가수용체), NE, A2AUTO |
| 가소성·회로 (4) | BDNF, CPFC, EAMY, TRAF(α2δ 수송) |
| GABA-A (3) | RA1(진정, τ 2.6 d), RA2(항불안, τ 42 d), DEPEND(적응, τ 20 d) |
| HPA (4) | CRH, ACTH, CORT, GR |
| 증상층 (4) | SNS, AUTON, SLEEPD, WORRY |
| 시험 기계장치 (2) | EXPECT, FLUCT |
| 이상반응 (6) | RNAU, RDIZZ, RH1, SEXD, WT, RACT |
| 동반질환·위험 (2) | MADRSS, CUMHAZ |
측정으로 고정한 상수 (적합하지 않음):
| 상수 | 값 | 출처 |
|---|---|---|
| 에스시탈로프람 SERT EC50 | 5 ng/mL (10 mg에서 점유 0.80) | PET/TDM (PMID 38287888, 27557550) |
| 벤라팍신 NET EC50 | 260 ng/mL → 75–225 mg에서 점유 0.21–0.44 | Arakawa 2019, 측정 8–61% (PMID 30649319) |
| 벤조 결합부위 EC50 | 96 ng/mL 로라제팜 등가 → 항불안 용량에서 점유 ~20% | Atack 2007 [¹¹C]플루마제닐 (PMID 17164474) |
| 프레가발린 t½ / 신장 청소 | 6.3 h / CrCl 비례 | PMID 17940637, 12638396 |
| α1 = 진정, α2/3 = 항불안, α5 = 진정 내성 | 구조 | knock-in 연구 (PMID 15282283) |
시나리오 17개가 gad_reference_output.txt에 있다:
무투약 자연경과 · 네 시계 비교 · Rickels 4주 5팔 · Khan 8주 4팔 · 용량반응
스윕(에스시탈로프람 4용량, 벤라팍신 3용량 × CYP2D6 3표현형, 둘록세틴 2용량,
부스피론) · 위약/기대효과 스윕 · 벤조 12주 후 급중단 vs 4주 감량 vs 지속 ·
병용 3쌍 · 벤조 브릿지 · CBT 단독/병용 · 가상 집단 6팔 (n = 200, 탈락·LOCF) ·
Allgulander 무작위 중단 (n = 260 → 169×2, 76주) · 신기능/CYP2D6/복약순응도 ·
적분기 검증.
환자·처방 → PK/점유율 → 네 인자 → 네 시계 → 임상 종말점 → 시험 시뮬레이터 → 시나리오 비교 → 용량반응 → 벤조디아제핀(내성·반동) → 이상반응 → 검정 민감도 스윕 → 재발 예방. 각 탭은 위 §3–§5의 계산을 대화형으로 다시 만들도록 짜여 있다.
gad_references.md — 118개 항목 / 113개 고유 PMID, 20개 섹션.
모든 제목·저널·연도·저자·PMID는 mkrefs.py가 NCBI esearch + esummary로
실시간 조회한 것이며 기억에서 쓴 것이 아니다. 각 항목에는 모델이 그 논문에서
무엇을 가져왔는지(intent) 가 함께 적혀 있어서, 검색이 의도와 다른 논문을
집어온 경우 한눈에 보이게 했다(전부 맞지는 않는다 — 그것이 이 표기의 목적이다).
⚠️ E-utilities의 기본 정렬은 관련도가 아니라 날짜다.sort=relevance를 빼면 "불안과 심혈관 위험"에 2026년 탈모 메타분석이 걸린다. 실제로 첫 빌드에서 그렇게 됐고,mkrefs.py에 그 사고 기록과 함께 주석으로 남겼다.
교육·연구 목적의 QSP 모델입니다. 공개 문헌과 임상시험 데이터를 바탕으로 구성했으나 독립적으로 검증·인증되지 않았으며, 실제 임상 의사결정, 처방, 또는 규제 제출에 직접 사용해서는 안 됩니다. 특히 §3.2(케티아핀), §4(반증된 사전 기대), §6(식별 불가능성), §8(R 코드 미실행)에 적힌 한계를 읽지 않고 이 모델의 숫자를 인용하지 마십시오.
