# [8-1] 정형 다중오믹스·임상 수치 행렬용 프라이버시 보존 합성데이터 생성 및 TSTR 검증 엔진 설계서

2026-11-14 · APOSTOLUS 8-1 · 대상 자료: `TCGA`(RNA-seq TPM/count, methylation beta, 생존·병기), `GEO`(외부 발현 코호트), `MIMIC-IV`(비식별 정형 검사·활력징후 요약)

## 0. 범위와 실행 상태

이 문서는 정형 수치 테이블의 결합분포를 모사하는 차분프라이버시 생성 엔진과 그 검증 하네스의 소프트웨어 설계다. 염기·아미노산 서열 설계, 합성생물학, 파운데이션 LLM 증류는 다루지 않는다. 입력은 유전자 ID별 발현 행렬, CpG beta 행렬, 정형 임상 변수 테이블로 한정한다.

| 구분 | 상태 | 근거 |
| --- | --- | --- |
| 스키마·정규화 계층, DP 회계, 기준 생성기 G0, TSTR/TRTR 판정, DCR·MIA 게이트 | 표준 라이브러리 Python으로 구현하고 가상 자료에서 실행 | `synth8/`, `evidence/synth8-run.json` |
| 독립 감사(다른 구현으로 재계산) | 4개 관문 860개 검사 일치 | `evidence/synth8-audit.json` |
| 사이트 요약(영·한 문구, 수치는 감사 파일 경로로 채움) | 사이트 검사기 통과 | `evidence/synth8-summary.json`, 규약 `site-data/README.md` |
| 주 생성기 G1(잠재 확산 + DP-SGD)과 Shared–Private VAE | 수식과 PyTorch 인터페이스로 규정. 이 저장소에는 torch가 없어 학습을 실행하지 않았다 | 2.3–2.7절 |
| TCGA·GEO·MIMIC-IV 실자료 학습과 보존율 실측 | 미실행. 목표 지표(TSTR/TRTR ≥ 95%, MIA AUROC ≤ 0.55)의 실자료 달성 여부는 이 문서의 결론이 아니다 | 4절 |

가상 자료 실행의 결론은 두 가지다. 첫째, 판정 장치는 정답을 아는 네 생성기(독립 재표집, 전체 복사, 15% 복사, 독립 주변분포)를 모두 옳게 가른다(3.7절). 둘째, 정답을 미리 정하지 않고 측정한 해석적 DP 기준 생성기 G0는 $\varepsilon=2$에서 프라이버시 게이트를 확정 통과하지만 바이오마커 순위 보존율이 0.914로 95%에 못 미쳐 출시가 차단된다. 따라서 두 목표의 동시 달성은 G1이 G0를 넘어서는지에 달려 있고, 그 판정 절차가 이 설계의 3절이다.

---

## 1. 산출물 1 — 이종 모달리티 정형 스키마와 배치 효과 정규화 계층

### 1.1 데이터 계약

엔진은 원 코호트의 키를 받지 않는다. 적재 단계에서 행 키를 불투명 토큰으로 다시 매기고(`^[A-Z]{1,3}-[0-9]{6}$`), 원 키와의 대응표는 엔진 밖에 둔다.

| 테이블 | 행 단위 | 열 | 값 제약 |
| --- | --- | --- | --- |
| `cohort_manifest` | 프라이버시 단위(환자) 1행 | `row_key`, `source`∈{TCGA, GEO, MIMIC_IV}, `batch_id`(조직 수집기관·플레이트·기관의 불투명 코드), `split`, `dua_tag`, `modality_mask` | 환자당 1행. 같은 환자의 표본이 여럿이면 사전 규칙으로 1개만 남긴다 |
| `expr_matrix` | `row_key` × `gene_id` | Ensembl gene ID(버전 고정), TPM 또는 count | TPM ≥ 0, 유한 실수. `feature_manifest`의 유전자 집합과 정확히 일치 |
| `meth_matrix` | `row_key` × `cpg_id` | Illumina probe ID, beta | $0 \le \beta \le 1$. 검출 실패는 `null`과 마스크 |
| `clin_table` | `row_key` 1행 | 변수 사전에 등록된 변수만: `kind`∈{continuous, binary, categorical, ordinal, survival_time, event}, 단위, 허용 범위·범주 | 결측은 `null`. 날짜는 받지 않고 기준일 대비 상대 일수만 |
| `feature_manifest` | 특징 1행 | `feature_id`, `modality`, 단위, 주석 버전, 공개 통계 출처 | 학습 전 동결, SHA-256 기록 |

`MIMIC-IV`는 `subject_id` 단위로 1행을 만든다. `labevents`·`omr`·활력징후는 사전 정의한 창(예: 입원 후 첫 24시간)의 최소·최대·평균·관측 수로 요약하고, `anchor_age`는 구간화하며, 시각 열과 자유 텍스트는 싣지 않는다. `TCGA`는 open-access 등급의 발현·메틸화·임상만 쓰고 controlled-access 자료는 입력 계약에서 제외한다. 동일인을 연결할 근거가 없는 세 자료원은 서로 독립 도메인으로 다룬다.

**최소수집과 금지 필드.** 키 이름이 `name|mrn|ssn|rrn|birth|dob|address|phone|email|zip|postcode|barcode|uuid|subject_id|hadm_id|stay_id|patient_id|case_id|date|note|text`에 걸리면 어느 깊이에 있든 행 전체를 거부한다(`FORBIDDEN_FIELD`). 등록되지 않은 열(`UNKNOWN_FIELD`), 특징 집합 불일치(`FEATURE_SET`), 범위·범주·자료형·비유한값 위반도 거부 코드로 반환한다. 합성 테이블은 원 단위로 복원한 뒤 같은 검사기를 통과해야 출시 판정에 들어간다. 구현: `synth8/schema.py` `validate_record`, 고정 사례 15건.

**출시 선행 조건(거버넌스).** 자료원별 DUA가 파생자료 공개를 허용하는지는 엔진이 판정하지 않는다. `dua_tag`가 `RELEASE_REVIEWED`가 아닌 자료원에서 학습한 생성기의 산출물은 3.5절의 출시 규칙에 들어가기 전에 차단한다. MIMIC-IV 원자료는 외부 서비스로 전송하지 않고 오프라인에서만 처리한다. 이 선행 조건은 실자료 적재 단계의 설계 규정이며, 자료원이 없는 가상 하네스의 출시 규칙에는 들어 있지 않다.

### 1.2 정규화 계층 (L0 → L1 → L2)

프라이버시 회계의 원칙은 "비공개 행을 건드리는 모든 연산은 원장에 한 줄로 남는다"이다. 그래서 정규화를 표본 간 통계가 필요 없는 층과 필요한 층으로 나눈다.

**L0 — 표본 내 변환(프라이버시 비용 0).** 한 행의 값만으로 계산한다.

$$x^{\text{expr}}_{ij}=\log_2(\mathrm{TPM}_{ij}+1),\qquad x^{\text{meth}}_{ij}=M_{ij}=\log_2\frac{\beta_{ij}+\epsilon_M}{1-\beta_{ij}+\epsilon_M},\ \ \epsilon_M=10^{-3}$$

count 입력은 같은 행의 라이브러리 크기로 CPM을 만든 뒤 같은 로그를 적용한다. 필요하면 행 내부 순위를 공개 기준 분포의 분위수로 옮긴다: $x'_{ij}=F_{\text{ref}}^{-1}(\hat F_i(x_{ij}))$. $F_{\text{ref}}$는 GEO 등 공개 코호트에서 만든다.

**L1 — 공개 매개변수 표준화(프라이버시 비용 0).** $\tilde x_{ij}=(x_{ij}-m^{\text{pub}}_j)/s^{\text{pub}}_j$. $m^{\text{pub}}, s^{\text{pub}}$와 특징 선택(분산 상위 유전자, 경로 유전자 집합, 프로브 필터)은 공개 코호트 또는 공개 주석에서만 정한다. 임상 연속 변수의 결측은 0(공개 평균)으로 채우고 결측 지시 열을 따로 둔다.

**L2 — 배치 보정.** 두 경로가 있다.

(a) *실자료 팔(TRTR)과 평가용 실자료*: ComBat 형식의 경험적 베이즈 위치–척도 보정. 공변량 설계 $X_i$(보존할 생물학적 변수)를 두고

$$z_{ij}=\frac{\tilde x_{ij}-\hat\alpha_j-X_i\hat\beta_j}{\hat\sigma_j},\qquad \hat\gamma_{bj}=\frac1{n_b}\sum_{i\in b}z_{ij},\quad \hat\delta^2_{bj}=\frac{1}{n_b-1}\sum_{i\in b}(z_{ij}-\hat\gamma_{bj})^2$$

배치 $b$ 안에서 특징들에 걸친 사전분포 $\gamma_{bj}\sim\mathcal N(\bar\gamma_b,\tau_b^2)$, $\delta^2_{bj}\sim\mathrm{IG}(\lambda_b,\theta_b)$의 초매개변수를 적률로 정하고 다음을 수렴할 때까지 반복한다.

$$\gamma^*_{bj}=\frac{n_b\tau_b^2\hat\gamma_{bj}+\delta^{*2}_{bj}\bar\gamma_b}{n_b\tau_b^2+\delta^{*2}_{bj}},\qquad \delta^{*2}_{bj}=\frac{\theta_b+\tfrac12\sum_{i\in b}(z_{ij}-\gamma^*_{bj})^2}{n_b/2+\lambda_b-1}$$

$$x^{\text{adj}}_{ij}=\hat\sigma_j\,\frac{z_{ij}-\gamma^*_{bj}}{\delta^*_{bj}}+\hat\alpha_j+X_i\hat\beta_j$$

모든 추정은 학습 분할에서만 한다. 시험 분할이 학습과 같은 배치를 공유하면 동결한 $(\gamma^*,\delta^*)$를 적용한다(모드 A). TCGA처럼 기관 단위로 분할해 시험 배치가 학습에 없으면 라벨 없이 그 배치 자체의 특징으로 기준 배치에 정렬하고(모드 B), $n_b$가 사전 하한보다 작으면 보정을 생략하고 표시를 남긴다. 구현: `fit_batch`/`apply_batch`(가상 하네스는 공변량 항 $X_i\hat\beta_j$가 없는 형태와 모드 A를 실행한다).

(b) *DP 생성 경로*: 비공개 행에 (a)를 적용하면 그 통계가 회계 밖에서 새어 나간다. 특징 공간의 배치 평균을 DP로 공개하면 $L_2$ 민감도가 $\propto\sqrt p$라서 $p\gg n$에서 잡음이 신호를 덮는다. 그래서 배치 효과는 $k$차원 잠재공간에서 다룬다. 공개 기저로 사영한 잠재 벡터 $z_i$에 대해

$$\mathbb E[z_i\mid c_i,b_i]=\mu_{c_i}+\gamma_{b_i},\qquad \sum_b n_b\gamma_b=0$$

를 DP로 공개한 셀 합에서 가중 최소제곱으로 적합하고(2.2절), 생성은 기준 조건 $\gamma=0$에서 한다. 신경망 생성기에서는 인코더·디코더에 배치 임베딩을 조건으로 주고 DP-SGD로 함께 학습하며 생성 시 기준 배치를 넣는다. 어느 쪽이든 추가 프라이버시 비용은 원장에 이미 잡힌 항목뿐이다.

가상 자료 실측: 오믹스 20개 특징의 배치 분산 비율 $\eta^2$가 학습 0.157 → 0.00006, 동결 매개변수를 적용한 보류 분할 0.162 → 0.0029로 줄었고 아형 분산 비율은 0.131 → 0.150으로 유지됐다.

### 1.3 Shared–Private Disentangled Latent Space

모달리티 $m\in\{\text{expr},\text{meth},\text{clin}\}$, 관측 마스크 $r^{(m)}_i$, 표본 $i$에서 관측된 모달리티 집합 $A_i$. 잠재 변수는 공유 $z_s\in\mathbb R^{d_s}$와 모달리티별 사적 $z_p^{(m)}\in\mathbb R^{d_p}$로 나눈다.

**인코더와 Product-of-Experts 결합.** 각 인코더는 관측값과 마스크를 받아 공유 사후분포의 평균·정밀도와 사적 사후분포를 낸다.

$$q_m(z_s\mid x^{(m)})=\mathcal N\big(\mu^{(m)}_s,\operatorname{diag}(1/\tau^{(m)}_s)\big),\qquad q(z_p^{(m)}\mid x^{(m)})=\mathcal N\big(\mu^{(m)}_p,\operatorname{diag}\sigma^{(m)2}_p\big)$$

$$\tau_s=1+\sum_{m\in A_i}\tau^{(m)}_s,\qquad \mu_s=\tau_s^{-1}\sum_{m\in A_i}\tau^{(m)}_s\mu^{(m)}_s$$

사전분포 $\mathcal N(0,I)$가 정밀도 1의 전문가로 들어가므로 모달리티가 통째로 빠진 표본도 같은 식으로 처리된다.

**디코더와 가능도.** $p(x^{(m)}\mid z_s,z_p^{(m)},b)$. 발현(L1 표준화값)은 특징별 분산을 갖는 Gaussian, count를 직접 쓸 때는 라이브러리 크기 offset을 둔 Negative Binomial, 메틸화는 M-value Gaussian 또는 beta 값의 Beta 가능도, 임상 변수는 종류별 Gaussian·Bernoulli·Categorical·누적 로짓, 생존은 구간 $j=1..J$의 이산시간 위험 $h_j(z_s)$로 $\prod_{j<k}(1-h_j)\,h_k^{e}(1-h_k)^{1-e}$. 재구성 손실은 관측 항목에만 걸고, 결측 지시 자체를 Bernoulli head로 모형화해 합성 표가 결측 구조를 재현하게 한다.

**표본별 손실.**

$$\begin{aligned}
\ell_i={}&\sum_{m\in A_i}\lambda_m\,\mathbb E_q\big[-\log p(x^{(m)}_i\mid z_s,z^{(m)}_p,b_i)\big]+\beta_s\,\mathrm{KL}\big(q(z_s\mid x_i)\,\|\,\mathcal N(0,I)\big)+\beta_p\sum_{m\in A_i}\mathrm{KL}\big(q(z^{(m)}_p\mid x^{(m)}_i)\,\|\,\mathcal N(0,I)\big)\\
&+\lambda_{\text{align}}\sum_{m<m'\in A_i}\big\|\mu^{(m)}_s-\mu^{(m')}_s\big\|_2^2+\lambda_{\times}\sum_{m\ne m'\in A_i}\mathbb E_{q_m(z_s\mid x^{(m)}_i)}\big[-\log p(x^{(m')}_i\mid z_s,z^{(m')}_p{=}0,b_i)\big]+\lambda_{\text{sup}}\,\ell_{\text{sup}}(y_i,z_s)
\end{aligned}$$

정렬 항은 같은 표본의 모달리티별 공유 사후 평균을 맞추고, 교차 재구성 항은 한 모달리티의 공유 잠재만으로 다른 모달리티를 복원하게 해 공유 정보가 $z_s$로 가게 한다. 분리는 세 겹이다. ① 구조: 디코더 $m$은 $z_p^{(m)}$만 보므로 사적 잠재가 다른 모달리티를 설명할 수 없다. ② 매개변수 제약: 공유·사적 사영 head의 직교 벌점 $\|W_s^{(m)\top}W_p^{(m)}\|_F^2$. ③ 공개 사전학습 단계에서만: 배치 단위 교차공분산/HSIC 벌점, InfoNCE 정렬, 배치 판별기 또는 MMD.

**DP-SGD 호환성.** DP-SGD는 손실이 표본별 합 $\sum_i\ell_i$로 분해될 때만 표본별 클리핑이 민감도를 묶는다. 표본을 서로 엮는 항은 비공개 학습에서 쓸 수 없다.

| 항 | 표본별 분해 | 비공개(DP) 단계 | 공개 사전학습 단계 |
| --- | --- | --- | --- |
| 재구성, KL, 표본 내 정렬 $\|\mu^{(m)}_s-\mu^{(m')}_s\|^2$, 교차 재구성, 생존·분류 head | 가능 | 사용 | 사용 |
| head 직교 벌점(자료 무관) | 자료 무관 | 클리핑·잡음 뒤에 더함 | 사용 |
| InfoNCE·배치 대조 손실, HSIC/교차공분산, MMD, 배치 판별기, BatchNorm 통계 | 불가 | 금지(GroupNorm/LayerNorm으로 대체) | 사용 |
| 공발현 정규화(2.4절): 생성 표본과 공개·DP 기준의 비교 | 비공개 행을 직접 쓰지 않음(입력은 생성 표본, 공개 사전분포, 이미 원장에 잡힌 DP 통계) | 클리핑·잡음 뒤에 더함 | 사용 |

이 분류는 표준 표본별 클리핑 DP-SGD를 쓰는 G1 구현이 지켜야 할 설계 규칙이다(표본을 엮는 손실이 다른 DP 메커니즘으로도 불가능하다는 뜻은 아니다). 현재 저장소의 코드는 회계와 클립·잡음 집계만 실행하며 이 규칙을 강제하지 않는다. G1 구현에는 두 검사를 붙인다. ① 모델에 BatchNorm 계열 모듈이나 배치 통계 버퍼가 있으면 학습을 거부한다. ② 무작위 배치에서 표본별 기울기의 합이 배치 손실 합의 기울기와 일치하는지, 그리고 한 표본을 바꿨을 때 다른 표본의 표본별 기울기가 변하지 않는지 단위 시험으로 확인한다.

**$p\gg n$ 처리.** 특징 선택과 1차 차원 축소는 공개 자료에서만 한다: 공개 코호트의 분산 상위 유전자, 경로 유전자 집합, 공개 코호트 PCA 또는 공개 사전학습 인코더. 비공개 자료는 그 결과인 $k$차원 잠재에서만 통계와 기울기를 낸다. DP 잡음의 크기는 건드리는 좌표 수에 비례하므로 $k$가 프라이버시–유틸리티 균형의 1차 손잡이다.

---

## 2. 산출물 2 — 프라이버시–유틸리티 동시 달성 생성 아키텍처

### 2.1 단계 구성과 프라이버시 원장

| 단계 | 건드리는 자료 | 내용 | 원장 항목 |
| --- | --- | --- | --- |
| A 공개 사전학습 | 공개만(GEO 등) | L1 매개변수, 특징 선택, Shared–Private VAE 사전학습, 공개 공발현 사전분포 $C^{\text{pub}}$ | 없음 |
| B1 DP 충분통계 | 비공개 | 클리핑한 잠재의 셀 개수·셀 합·2차 적률을 Gaussian mechanism으로 공개 → G0와 공발현 기준 $\tilde C$ | `G0_COUNTS`, `G0_SUMS`, `G0_MOMENT` |
| B2 DP-SGD | 비공개 | 잠재 denoiser(필요 시 디코더 저랭크 어댑터)를 표본별 클리핑·잡음으로 학습 | `DPSGD(q, σ, T)` |
| C 표집·복원 | 없음(후처리) | 기준 배치 조건에서 표집, 원 단위·자료형 복원, 스키마 검사 | 없음 |
| D 판정 | 실자료 시험 분할, 보류 분할 | TSTR/TRTR, DCR, MIA, 원장 대조, 출시 규칙 | 없음(판정 결과는 공개 범위를 따로 정한다) |

원장은 Rényi 곡선으로 합성한다. Gaussian 항목은 $\varepsilon(\alpha)=\alpha\rho$, DP-SGD 항목은 2.5절의 식이고, 전체를 더한 뒤 한 번만 $(\varepsilon,\delta)$로 바꾼다. Gaussian 항목만 있을 때는 $\alpha$에 대한 최소화가 닫힌 식 $\rho+2\sqrt{\rho\ln(1/\delta)}$로 풀리고(2.2절, `eps_from_rho`), DP-SGD 항목이 섞이면 같은 곡선을 정수 차수 격자에서 최소화한다(2.5절, `eps_from_rdp`). 격자 최솟값은 연속 최솟값보다 작을 수 없으므로 보수적인 쪽이다. 원장에 없는 비공개 접근이 하나라도 있으면 형식 보장은 `ABSENT`다. 초매개변수는 공개 대리 자료에서 고르거나, 비공개 자료로 고를 때는 그 선택 비용을 원장에 넣는다(무작위 횟수 반복 선택의 RDP 회계).

프라이버시 단위는 환자다. 인접 관계는 한 환자 행의 추가·제거이고 $\delta<1/n_{\text{ref}}$로 둔다($n_{\text{ref}}$는 공개 참조 크기, 2.5절). MIMIC-IV에서 한 환자의 여러 입원을 쓰려면 환자 단위로 기울기를 먼저 합친 뒤 클리핑한다.

### 2.2 기준 생성기 G0 — DP 조건부 인자 Gaussian

공개 기저 $W\in\mathbb R^{p\times k}$(공개 코호트 공분산의 상위 고유벡터), 고유값 $\Lambda$, 공개 잔차 표준편차 $d^{\text{pub}}$. 비공개 행의 잠재 벡터와 클리핑:

$$z_i=\begin{bmatrix}\Lambda^{-1/2}W^\top(\tilde x_i-m)\\ \tau_i\end{bmatrix}\in\mathbb R^{k+1},\quad \tau_i=\frac{\log t_i-m_{\log t}^{\text{pub}}}{s_{\log t}^{\text{pub}}},\qquad \bar z_i=z_i\cdot\min\!\big(1,\,R/\|z_i\|_2\big)$$

조건 셀 $c$(아형 × 사건 여부)와 배치 $b$로 세 통계를 낸다.

$$N_{cb}=\sum_i\mathbb 1[c_i=c,b_i=b],\qquad S_{cb}=\sum_{i:\,c_i=c,b_i=b}\bar z_i,\qquad M=\operatorname{triu}\Big(\sum_i\bar z_i\bar z_i^\top\Big)$$

**민감도.** 한 행은 정확히 한 셀에 속하므로 행 하나의 추가·제거에 대해 $\|\Delta N\|_2=1$, $\|\Delta S\|_2=\|\bar z\|_2\le R$이다. 2차 적률은 상삼각 성분 벡터의 Euclid 노름으로 재며 $\|\Delta M\|_2^2=\sum_{a\le e}\bar z_a^2\bar z_e^2\le\sum_{a,e}\bar z_a^2\bar z_e^2=\|\bar z\|_2^4\le R^4$, 곧 $\|\Delta M\|_2\le R^2$이다. 셀 수와 무관하다. 단위 테스트가 60개 행 각각을 빼며 세 차이의 노름을 직접 잰다(`test_clipped_statistics_have_the_ledgered_sensitivity`). 잠재 차원은 자료에서 읽지 않고 공개 설정으로 넘긴다. 행이 하나도 없는 자료도 한 행짜리 자료의 이웃이므로 같은 모양의 영 통계에 같은 잡음을 더해 모형을 낸다(`test_g0_releases_a_model_for_an_empty_private_data_set`).

**공개와 회계.** $\tilde N=N+\mathcal N(0,\sigma_N^2)$, $\tilde S=S+\mathcal N(0,\sigma_S^2I)$, $\tilde M=M+\mathcal N(0,\sigma_M^2I)$에서

$$\rho=\frac{1}{2\sigma_N^2}+\frac{R^2}{2\sigma_S^2}+\frac{R^4}{2\sigma_M^2},\qquad \varepsilon=\rho+2\sqrt{\rho\ln(1/\delta)}$$

목표 $\varepsilon$에서 $\rho=(\sqrt{\ln(1/\delta)+\varepsilon}-\sqrt{\ln(1/\delta)})^2$를 구해 세 통계에 20/40/40%로 나눈다.

**후처리(추가 비용 0).** 후처리 함수 `_postprocess`가 받는 것은 잡음을 더한 세 통계와 고정 설정뿐이다. 비공개 행도 잡음 전 통계도 받지 않으므로 DP의 후처리 불변성에 따라 예산을 더 쓰지 않는다. 셀 평균 $\hat m_{cb}=\tilde S_{cb}/\tilde N_{cb}$에 가법 모형 $\mu_c+\gamma_b$를 가중 backfitting으로 맞추고, 셀 내 공분산 $\hat\Sigma=(\tilde M-\sum_{cb}\tilde N_{cb}\hat m_{cb}\hat m_{cb}^\top)/(\tilde N-\#\text{cells})$의 고유값을 $[\lambda_{\min},\lambda_{\max}]$로 잘라 양의 정부호로 만든다. 표집은 $c\sim\tilde N_{c\cdot}$, $z\sim\mathcal N(\mu_c,\hat\Sigma)$, $\tilde x=m+W\Lambda^{1/2}z_{1:k}+d^{\text{pub}}\odot\xi$, $t=\exp(s\,z_{k+1}+m)$이다.

G0의 역할은 셋이다. ① 해석적으로 회계가 끝나는 하한선(G1은 같은 $\varepsilon$에서 G0를 넘어야 채택). ② $\tilde C=W\Lambda^{1/2}\hat\Sigma_{1:k}\Lambda^{1/2}W^\top+\operatorname{diag}(d^{\text{pub}})^2$가 2.4절 공발현 기준. ③ 잠재 화이트닝과 조건 사전분포의 초기값.

**소표본에서의 잡음 크기.** 셀 평균은 $\tilde S/\tilde N$이므로 오차의 1차 근사는 합 잡음과 개수 잡음 두 항이다.

$$\operatorname{Var}(\hat m_c)\approx\frac{\sigma_S^2}{n_c^2}+\|\mu_c\|^2\frac{\sigma_N^2}{n_c^2},\qquad \frac{\sigma_S}{n_c}=\frac{R}{n_c\sqrt{2\rho_S}},\quad \frac{\sigma_N}{n_c}=\frac{1}{n_c\sqrt{2\rho_N}}$$

아래 표는 분모를 참 개수로 둔 두 항의 크기다(실행값). 구현은 여기에 잡음 개수의 하한 처리와 가법 모형의 셀 간 평균화가 더해지므로 표는 후처리 평균의 정확한 표준편차가 아니라 차수를 보는 근사다. $R=4.5$, 몫은 개수 20%·합 40%, $\delta=10^{-5}$, 잠재 좌표의 표준편차가 1인 단위.

| 셀 크기 $n_c$ | 항 | $\varepsilon=1$ | $\varepsilon=3$ | $\varepsilon=8$ |
| ---: | --- | ---: | ---: | ---: |
| 42 (TCGA-BRCA 학습 분할의 양성 수) | 합 잡음 $\sigma_S/n_c$ (좌표당) | 0.830 | 0.288 | 0.117 |
| 42 | 개수 잡음 $\sigma_N/n_c$ (상대) | 26.1% | 9.0% | 3.7% |
| 330 | 합 잡음 $\sigma_S/n_c$ (좌표당) | 0.106 | 0.037 | 0.015 |
| 330 | 개수 잡음 $\sigma_N/n_c$ (상대) | 3.3% | 1.2% | 0.5% |

양성 42명 규모에서는 $\varepsilon\le1$의 클래스 조건부 통계가 신호(클래스 간 거리 1–2)와 같은 크기의 잡음을 갖는다. 이 표가 2.6절 운영점 선택의 근거다. 잡음 개수가 모두 하한 아래로 떨어지는 실현값도 유효한 출력이므로, 그때 G0는 공개 사전분포(화이트닝 잠재의 영평균·단위 공분산, 균등 셀 가중)로 물러난다.

### 2.3 주 생성기 G1 — 조건부 잠재 확산

잠재 $z_0=[z_s;z_p^{(1)};\dots;z_p^{(M)}]$를 G0의 DP 통계로 화이트닝한다. 조건 $c$는 아형, 병기, 사건·생존 구간, 모달리티 마스크의 임베딩이다.

$$q(z_t\mid z_0)=\mathcal N\big(\sqrt{\bar\alpha_t}\,z_0,\ (1-\bar\alpha_t)I\big),\qquad \ell^{\text{diff}}_i=\frac1K\sum_{k=1}^{K}w(t_k)\,\big\|\epsilon_k-\epsilon_\theta\big(\sqrt{\bar\alpha_{t_k}}z_{0,i}+\sqrt{1-\bar\alpha_{t_k}}\,\epsilon_k,\ t_k,\ c_i\big)\big\|_2^2$$

표본 하나에 $K$개의 $(t_k,\epsilon_k)$를 뽑아 평균한 뒤 클리핑한다(noise multiplicity). 기울기 분산은 줄고 프라이버시 비용은 그대로다. 조건을 확률 $p_{\text{drop}}$로 지워 classifier-free guidance를 쓴다: $\hat\epsilon=(1+w)\,\epsilon_\theta(z_t,t,c)-w\,\epsilon_\theta(z_t,t,\varnothing)$. denoiser는 잔차 MLP($d\le64$ 입력, FiLM 조건, LayerNorm)로 두어 매개변수 수를 수만 개 수준으로 묶는다. 표집은 DDIM 50–100단계, 조건 분포는 $\tilde N_{c\cdot}$에서 뽑는다.

대안인 조건부 계층형 VAE는 $p(z_2\mid c)\,p(z_1\mid z_2,c)\,\prod_m p(x^{(m)}\mid z_1,b)$로 두고 상위 $z_2$가 공유 요인, 하위 $z_1$이 모달리티별 요인을 맡는다. 손실은 표본별 ELBO이므로 같은 DP-SGD 절차를 쓴다. 선택 기준은 3절 하네스의 동일 $\varepsilon$ 비교다.

### 2.4 공발현 네트워크 보존 정규화

비공개 배치의 상관행렬과 생성 배치의 상관행렬을 직접 맞추는 벌점은 표본을 서로 엮어 DP-SGD와 양립하지 않는다. 대신 기준을 공개 사전분포와 DP 통계에서 만들고, 벌점은 생성 표본에만 건다.

$$C^{\text{ref}}=\omega\,\operatorname{corr}(\tilde C)+(1-\omega)\,C^{\text{pub}},\qquad \mathcal L_{\text{coex}}(\theta)=\frac{1}{|\Omega|}\Big\|P_\Omega\big(\operatorname{corr}_{z\sim p_\theta(\cdot\mid c),\,c\sim\tilde\pi}[\,G_\theta(z)\,]-C^{\text{ref}}\big)\Big\|_F^2+\lambda_{\text{eig}}\sum_{r\le r_0}\big(1-\langle v_r(\theta),v^{\text{ref}}_r\rangle^2\big)$$

$\Omega$는 사전 등록한 모듈(경로·공개 공발현 간선)의 유전자 쌍, $v_r$는 모듈 고유유전자 방향이다. $\mathcal L_{\text{coex}}$의 기울기에는 비공개 행이 들어가지 않으므로 클리핑·잡음을 거친 기울기에 그대로 더한다(후처리 불변성). 판정 지표는 실자료 대비 상관행렬 상삼각의 상대 Frobenius 오차와 간선 순위의 Spearman 상관이다.

### 2.5 DP-SGD

Poisson 표집률 $q$, 나눗셈 분모 $B$, 클립 노름 $C$, 잡음 배수 $\sigma$, 스텝 수 $T$는 모두 학습 전에 고정하는 공개 상수다. $q$를 실제 비공개 행 수로 나눠 정하면 한 행의 추가·제거가 모든 행의 포함 확률을 바꾸므로 아래 회계를 쓸 수 없다. 그래서 $q=B/n_{\text{ref}}$로 두되 $n_{\text{ref}}$는 사전 등록한 공개 참조 크기(공개 명부의 분할 크기)이고, 실제 행 수가 그와 달라도 $q$와 $B$는 바꾸지 않는다. 분할 크기를 공개할 수 없는 자료에서는 $q$를 직접 지정한다.

$$\tilde g_t=\frac1B\Big(\sum_{i\in\mathcal B_t}g_{t,i}\cdot\min\big(1,\,C/\|g_{t,i}\|_2\big)+\mathcal N\big(0,\ \sigma^2C^2I\big)\Big),\qquad \theta_{t+1}=\theta_t-\eta\,\big(\tilde g_t+\nabla_\theta\mathcal R_{\text{pub}}(\theta_t)\big)$$

$\mathcal B_t$는 각 행을 독립 확률 $q$로 포함해 만든다(고정 크기 셔플은 이 회계와 맞지 않는다). 나눗셈은 실제 배치 크기가 아닌 $B$로 한다. 배치가 비어도 공개된 매개변수 차원 전체에 잡음을 더한 벡터를 낸다. 빈 배치에서 출력이 비거나 잡음이 빠지면 그 사실만으로 표집 여부가 드러나 $\delta<q$인 보장이 깨진다(`noisy_mean`은 차원을 인자로 받으며, 초안의 이 누락은 교차검증에서 발견해 고쳤다). $\mathcal R_{\text{pub}}$는 직교 벌점과 $\mathcal L_{\text{coex}}$다. 정수 차수 $\alpha\ge2$의 Rényi 발산 상한은

$$\varepsilon_{\text{SGM}}(\alpha)=\frac{1}{\alpha-1}\log\sum_{j=0}^{\alpha}\binom{\alpha}{j}(1-q)^{\alpha-j}q^{j}\exp\!\Big(\frac{j^2-j}{2\sigma^2}\Big)$$

이다(구현은 극한인 $q=0$에서 0, $q=1$에서 $\alpha/2\sigma^2$를 따로 반환한다). 전체 예산은

$$\varepsilon=\min_{\alpha}\Big[T\,\varepsilon_{\text{SGM}}(\alpha)+\alpha\,\rho_{\text{B1}}+\frac{\ln(1/\delta)}{\alpha-1}\Big]$$

로 구한다. 구현 `synth8/dp.py`의 이항 전개값은 감사기가 정의식 $\frac{1}{\alpha-1}\log\mathbb E_{z\sim\mathcal N(0,\sigma^2)}[((1-q)+q\,e^{(2z-1)/2\sigma^2})^\alpha]$를 Simpson 구적으로 적분한 값과 상대오차 $10^{-6}$ 이내로 일치한다. 운영 구현에서는 암호학적 난수원, 부동소수점 잡음의 이산화, 조기 종료·체크포인트 선택의 회계 포함을 요구한다.

목표 $\varepsilon$의 20%를 B1에 배정하고 나머지를 DP-SGD에 쓰는 계획의 잡음 배수(실행값):

| 계획 | $n_{\text{ref}}$, $B$, $T$, $\delta$ | $\varepsilon=1$ | $\varepsilon=3$ | $\varepsilon=8$ | 형식 AUROC 상한 0.55 ($\varepsilon\approx0.2006$) |
| --- | --- | ---: | ---: | ---: | ---: |
| `TCGA_BRCA_LATENT` | 372, 62, 360, $10^{-5}$ | $\sigma=15.94$ | 5.62 | 2.41 | 78.00 |
| `MIMIC_IV_SUBJECT` | 50,000, 1,000, 1,500, $10^{-6}$ | $\sigma=4.35$ | 1.67 | 0.92 | 20.94 |

### 2.6 형식 보장과 MIA AUROC ≤ 0.55의 관계

$(\varepsilon,\delta)$-DP 산출물에 대한 어떤 멤버십 검정도 $\mathrm{TPR}\le\min\{e^{\varepsilon}\mathrm{FPR}+\delta,\ 1-e^{-\varepsilon}(1-\delta-\mathrm{FPR})\}$를 만족한다. 두 직선은 $\mathrm{FPR}^*=(1-\delta)/(1+e^{\varepsilon})$에서 만나고, 그 위쪽 넓이를 적분하면

$$\mathrm{AUROC}_{\text{MIA}}\ \le\ 1-\frac{(1-\delta)^2}{1+e^{\varepsilon}}$$

이다(단위 테스트가 수치 적분과 대조). 이 상한은 나머지 자료를 고정하고 한 환자의 추가·제거를 가르는 검정에 대한 것이다. 멤버 여부를 무작위로 정하는 실험의 모집단 ROC는 환자별 제약의 평균이어서 같은 상한을 따르지만, 서로 다른 분포에서 온 멤버·비멤버를 비교한 경험 AUROC에는 적용되지 않는다(분포 차이만으로 0.5를 넘을 수 있다). 이 상한을 0.55로 만들려면 $\varepsilon\le\ln\!\big((1-\delta)^2/0.45-1\big)\approx0.2006$이 필요하고, 위 표처럼 TCGA 규모에서 $\sigma\approx78$을 요구한다. $\varepsilon=1,3,8$에서는 형식 상한이 각각 0.731, 0.953, 0.9997이어서 0.55를 보장하지 못한다.

따라서 "MIA AUROC ≤ 0.55"는 두 수준으로 나누어 판정한다.

- **형식 수준**: 원장의 $(\varepsilon,\delta)$와 그 AUROC 상한을 항상 함께 보고한다. $\varepsilon\le0.2$이면 모든 공격에 대해 0.55가 보장된다.
- **경험 수준**: 운영점은 $\varepsilon\in[1,8]$ 범위에서 유틸리티 게이트를 통과하는 가장 작은 값으로 잡고, 지정한 공격 묶음의 AUROC 신뢰상한이 0.55 이하인지로 판정한다(3.4절). 경험 판정은 지정 공격에 대한 것이며 형식 보장을 대신하지 않는다. 그래서 출시 규칙은 원장 통과와 경험 확정을 둘 다 요구한다.

### 2.7 PyTorch 모듈 인터페이스

아래는 설계 인터페이스다. 텐서 shape과 계약만 규정하며 이 저장소에서는 실행하지 않았다.

```python
from dataclasses import dataclass
import torch
from torch import Tensor, nn
from torch.func import functional_call, grad, vmap


@dataclass
class OmicsBatch:
    x: dict[str, Tensor]        # modality -> [B, p_m], L0+L1 normalised
    mask: dict[str, Tensor]     # modality -> [B, p_m] bool, True = observed
    present: Tensor             # [B, M] bool, modality available for the row
    batch_id: Tensor            # [B] long, opaque batch code
    cond: Tensor                # [B, d_c] conditioning (subtype, stage, event/time bin)
    surv_bin: Tensor            # [B] long, discrete-time interval
    event: Tensor               # [B] bool


class ModalityEncoder(nn.Module):
    def forward(self, x: Tensor, mask: Tensor, batch_id: Tensor
                ) -> tuple[Tensor, Tensor, Tensor, Tensor]:
        """-> mu_s [B, d_s], log_prec_s [B, d_s], mu_p [B, d_p], log_var_p [B, d_p]"""


class SharedPrivateVAE(nn.Module):
    def product_of_experts(self, mu: Tensor, log_prec: Tensor, present: Tensor) -> tuple[Tensor, Tensor]:
        """mu, log_prec: [B, M, d_s]; absent experts get zero precision; prior precision is 1."""

    def encode(self, batch: OmicsBatch) -> dict[str, Tensor]: ...
    def decode(self, z_s: Tensor, z_p: dict[str, Tensor], batch_id: Tensor) -> dict[str, torch.distributions.Distribution]: ...
    def per_sample_loss(self, batch: OmicsBatch) -> Tensor:
        """[B]; only row-decomposable terms (section 1.3). No BatchNorm anywhere."""


class LatentDenoiser(nn.Module):
    def forward(self, z_t: Tensor, t: Tensor, cond: Tensor, cond_keep: Tensor) -> Tensor:
        """z_t [B, d], t [B], cond [B, d_c], cond_keep [B] bool -> eps_hat [B, d]"""


def diffusion_per_sample_loss(denoiser: LatentDenoiser, z0: Tensor, cond: Tensor, alpha_bar: Tensor,
                              multiplicity: int, p_drop: float, rng: torch.Generator) -> Tensor:
    """[B]; mean over `multiplicity` (t, eps) draws per row before clipping."""


class CoexpressionRegularizer(nn.Module):
    def __init__(self, c_ref: Tensor, pair_index: Tensor, eig_ref: Tensor, lam_eig: float): ...
    def forward(self, generated: Tensor) -> Tensor:
        """generated [B_g, p] decoded samples drawn from the model; scalar. Touches no private row."""


class RdpAccountant:
    def add_gaussian(self, code: str, sensitivity: float, sigma: float) -> None: ...
    def add_dpsgd(self, code: str, q: float, sigma: float, steps: int) -> None: ...
    def epsilon(self, delta: float) -> tuple[float, int]: ...


class DPSGDTrainer:
    def __init__(self, model: nn.Module, clip_norm: float, noise_multiplier: float, sampling_rate: float,
                 expected_batch: int, accountant: RdpAccountant, noise_rng: torch.Generator):
        """sampling_rate and expected_batch are public constants fixed before training;
        neither is derived from the number of private rows."""

    def per_sample_grads(self, params: dict[str, Tensor], batch: OmicsBatch) -> dict[str, Tensor]:
        def one(p, row):                      # row: single-unit view of the batch
            return self.loss_of_row(functional_call(self.model, p, (row,)))
        return vmap(grad(one), in_dims=(None, 0))(params, batch)

    def step(self, batch: OmicsBatch, public_regularizer: nn.Module | None = None) -> None:
        """Poisson-sampled batch (each unit kept with probability sampling_rate; may be empty) ->
        clip each unit's flat gradient to clip_norm -> sum (zero vector if empty) ->
        add N(0, (noise_multiplier * clip_norm)^2 I) on every coordinate -> divide by expected_batch ->
        add the gradient of the public regulariser -> optimiser step -> accountant.add_dpsgd."""


def sample(denoiser: LatentDenoiser, vae: SharedPrivateVAE, cond: Tensor, guidance: float,
           steps: int, reference_batch: int, rng: torch.Generator) -> dict[str, Tensor]:
    """-> native-typed synthetic table after type restoration; validated by the schema layer."""
```

---

## 3. 산출물 3 — 하류 예측 보존율과 프라이버시 감사 자동화 하네스

### 3.1 분할과 누수 차단

1. 분할은 학습 전에 고정한다. 프라이버시 단위와 배치(기관)가 분할을 넘지 않는다. TCGA-BRCA는 고정된 기관 단위 372/124/125 분할을 쓴다.
2. 생성기·전처리·하류 학습기의 적합은 학습 분할에서만 한다. 시험 분할은 TSTR과 TRTR 모델이 모두 동결된 뒤에만 정답과 결합한다.
3. 하류 학습기는 구조와 초매개변수를 사전 고정한다(이 하네스: 수축 LDA, ridge Cox, 일원분산분석 F). 두 팔은 같은 학습기, 같은 시험 분할, 같은 특징 공간을 쓴다.
4. 합성 표는 출시될 형태(원 단위, 자료형 복원, 스키마 통과)로 만든 뒤 다시 인코딩해 평가한다. 후처리의 손실이 점수에 반영된다.
5. 멤버십 감사의 비멤버는 같은 모집단의 보류 분할이며 멤버와 같은 수로 맞춘다.

### 3.2 종점 정의

- **생존(C-index)**: 위험 점수 $r$에 대해 비교 가능 쌍 $\mathcal P=\{(i,j):e_i=1,\ t_i<t_j\}$에서 $C=|\mathcal P|^{-1}\sum_{(i,j)\in\mathcal P}\big(\mathbb 1[r_i>r_j]+\tfrac12\mathbb 1[r_i=r_j]\big)$. 우연 수준 $c=0.5$.
- **아형 분류(Macro-F1)**: $\frac1K\sum_k\frac{2\,\mathrm{TP}_k}{2\,\mathrm{TP}_k+\mathrm{FP}_k+\mathrm{FN}_k}$. 사전 비율 무작위 분류기의 기댓값 $c=1/K$.
- **아형 분류(AUROC)**: 클래스별 one-vs-rest AUROC(동점 1/2)의 평균. $c=0.5$.
- **바이오마커 순위 일치도(Spearman $\rho$)**: 기준 순위는 실자료 시험 분할에서 계산한 특징 중요도 $F^{\text{test}}$다. $\mathrm{TRTR}_\rho=\rho(F^{\text{train}},F^{\text{test}})$는 실자료 스스로의 재현 상한이고 $\mathrm{TSTR}_\rho=\rho(F^{\text{syn}},F^{\text{test}})$다. $c=0$. $p\gg n$에서는 대부분의 유전자가 무효라 전체 순위의 재현 상한 자체가 낮으므로 사전 등록한 패널 또는 기준 순위 상위 $k$로 범위를 고정하고 상위 $k$ Jaccard를 함께 보고한다.

시험 분할에 어떤 클래스가 없거나 비교 가능 쌍이 없으면 그 종점은 값이 아니라 `HOLD_UNDEFINED`다.

### 3.3 보존율 판정 규칙

원시 보존율 $P_m=\mathrm{TSTR}_m/\mathrm{TRTR}_m$만으로는 목표를 판정할 수 없다. $\mathrm{TRTR}=0.52$, $\mathrm{TSTR}=0.50$이면 두 모델 모두 우연 수준인데 $P=0.96$이다. 무작위 합성 표도 AUROC 종점에서 $0.5/\mathrm{TRTR}$를 얻는다. 그래서 우연 수준을 뺀 기술 보존율을 함께 요구한다.

$$P_m=\frac{\mathrm{TSTR}_m}{\mathrm{TRTR}_m},\qquad S_m=\frac{\mathrm{TSTR}_m-c_m}{\mathrm{TRTR}_m-c_m}$$

시험 분할을 $G=20$개 군으로 나눈 delete-a-group jackknife로 $\widehat{\mathrm{SE}}=\sqrt{\tfrac{G-1}{G}\sum_g(\hat\theta_{(-g)}-\bar\theta)^2}$를 구하고 단측 95% 하한 $\mathrm{LCB}=\hat\theta-t_{0.95,G-1}\widehat{\mathrm{SE}}$를 쓴다($t_{0.95,19}=1.729133$). 두 팔을 같은 삭제 표본에서 다시 계산하므로 비율의 짝지음이 유지된다.

| 순서 | 조건 | 상태 |
| ---: | --- | --- |
| 1 | TSTR 또는 TRTR이 정의되지 않음 | `HOLD_UNDEFINED` |
| 2 | $\mathrm{LCB}(\mathrm{TRTR}_m)\le c_m+0.05$ (기준 모델이 우연과 구분되지 않음) | `HOLD_UNINFORMATIVE` |
| 3 | $P_m<0.95$ | `FAIL_RATIO` |
| 4 | $S_m<0.90$ | `FAIL_SKILL` |
| 5 | $\mathrm{LCB}(P_m)\ge0.95$ | `PASS_CONFIRMED` |
| 6 | 그 밖 | `PASS_POINT` |

비교는 소수 여섯째 자리로 반올림한 값의 유리수 연산으로 한다(경계값 0.95가 부동소수점 오차로 뒤집히지 않는다). 네 종점 중 하나라도 `FAIL`이면 유틸리티 `FAIL`, `HOLD`가 있으면 `HOLD`, 모두 확정이면 `PASS_CONFIRMED`, 아니면 `PASS_POINT`다. 실자료 실행에서는 생성기 표집 시드 $R\ge5$개의 평균과 최솟값을 함께 보고한다. 고정 사례 12건(`RC01`–`RC12`)이 위 표의 각 분기와 경계를 덮는다.

**TCGA-BRCA 시험 분할의 통계적 해상도.** 양성 8명, 음성 117명에서 귀무가설하 AUROC 표준오차는 $\sqrt{(8+117+1)/(12\cdot8\cdot117)}\approx0.106$이다. 단일 시험 분할로는 95% 보존율을 확정(`PASS_CONFIRMED`)할 수 없다. 기관 단위 교차 적합(기관을 접는 grouped K-fold의 out-of-fold 점수를 모아 한 번 계산)과 생성기 반복 표집으로 분모를 늘리고, 그 설계를 실행 전에 고정한다.

### 3.4 프라이버시 게이트

모든 거리는 L1 표준화 공간의 Euclid 거리다. 학습 행 $T$, 같은 크기의 보류 행 $H$, 합성 행 $S$.

**DCR (Distance to Closest Record).** $d_T(s)=\min_{x\in T}\|s-x\|$, $d_H(s)=\min_{x\in H}\|s-x\|$.

| 통계 | 정의 | 통과 조건 |
| --- | --- | --- |
| 복제 수 | $\#\{s:d_T(s)\le10^{-6}\}$ | 0 |
| 학습 쪽 근접 비율 | $\hat\pi=\frac1m\#\{s:d_T(s)<d_H(s)\}$ (동점 1/2) | Clopper–Pearson 단측 95% 상한 $\le0.5+\eta_\pi$ |
| 근접 초과 비율 | $\hat r=\frac1m\#\{s:d_T(s)<q_{0.05}\}$, $q_{0.05}$는 실자료 $\{d_T(h)\}_{h\in H}$의 5% 분위수 | 상한 $\le0.05+\eta_r$ |
| 보고용 | $Q_{5}(d_T)/Q_{5}(d_H)$, 중앙값 비 | 판정에 쓰지 않음 |

허용오차는 합성 표를 보기 전에 실자료-대-실자료 귀무분포에서 정한다. 누출이 전혀 없는 생성기를 독립 재표집으로 흉내 내어 16개 탐침 시드에서 $\hat\pi$는 평균 0.510·표준편차 0.034, $\hat r$은 평균 0.047·표준편차 0.009였다(`evidence/synth8-calibration.json`). $\hat\pi$의 표본 간 산포가 이항 표준오차 0.020보다 크다는 점이 중요하다. 학습·보류 집합의 실현값에 따라 귀무 중심이 움직이므로, 이항 오차만 반영한 허용오차($\eta_\pi\approx0.07$)는 이 귀무분포에서 정규 근사로 정상 생성기의 약 24%를 탈락시킨다. "평균 + 2 표준편차 + Clopper–Pearson 반폭" 규칙으로 $\eta_\pi=0.115$, $\eta_r=0.035$를 동결했다.

**MIA.** 멤버 $T$, 비멤버 $H$의 각 행 $x$에 두 점수를 준다.

$$A_1(x)=-\min_{s\in S}\|x-s\|,\qquad A_2(x)=\log d_k(x;\mathrm{Pub})-\log d_k(x;S)\quad(k=5)$$

$A_1$은 최근접 합성 행까지의 거리, $A_2$는 공개 기준 집합 대비 합성 집합의 국소 밀도비다. 각 공격의 AUROC와 DeLong 표준오차로 단측 상한 $\mathrm{UCB}=\widehat{\mathrm{AUC}}+z_{1-0.05/A}\widehat{\mathrm{SE}}$($A$는 공격 수, Bonferroni)를 만든다.

| 조건 | 상태 |
| --- | --- |
| $\max_a\widehat{\mathrm{AUC}}_a>0.55$ | `FAIL` |
| $\max_a\mathrm{UCB}_a\le0.55$ | `PASS_CONFIRMED` |
| 그 밖 | `PASS_POINT` |

귀무 표준오차가 $\sqrt{1/(6N)}$이므로 참 AUROC가 0.5인 생성기를 검정력 90%로 확정하려면 멤버·비멤버가 각각 $N\ge\big(z_{0.975}+z_{0.90}\big)^2/\big(6\cdot0.05^2\big)=701$명 필요하다. TCGA-BRCA(학습 372명)는 이에 못 미치므로 생성기를 무작위 반분할에서 여러 번 학습해 행마다 멤버/비멤버 판정을 모으는 반복 반분할 감사를 쓴다. 감사용 학습은 공개되지 않으므로 원장에 들어가지 않는다. FPR 1%에서의 TPR도 함께 보고한다(부분 복제는 AUROC보다 이 값에 먼저 드러난다).

**원장 대조.** 공격 임계값 격자에서 $\hat\varepsilon_{\text{LB}}=\max\log\big((\mathrm{TPR}_{\text{lower}}-\delta)/\mathrm{FPR}_{\text{upper}}\big)$를 Clopper–Pearson 한계로 추정한다. $\hat\varepsilon_{\text{LB}}$가 원장의 $\varepsilon$을 넘으면 구현 또는 회계 오류의 신호이므로 `DP_AUDIT_CONTRADICTION`으로 차단한다.

### 3.5 출시 규칙

| 입력 | 값 |
| --- | --- |
| 유틸리티 | `PASS_CONFIRMED` / `PASS_POINT` / `HOLD` / `FAIL` |
| DCR | `PASS` / `FAIL` |
| MIA | `PASS_CONFIRMED` / `PASS_POINT` / `FAIL` |
| 형식(원장) | `OK` / `ABSENT` / `BUDGET_EXCEEDED` / `CONTRADICTION` |
| 스키마 | 위반 0건 여부 |

출시 가능은 "스키마 위반 0 ∧ 유틸리티 `PASS_*` ∧ DCR `PASS` ∧ MIA `PASS_CONFIRMED` ∧ 원장 `OK`"뿐이다. 유틸리티가 점추정 통과이면 `ELIGIBLE_POINT`, 확정이면 `ELIGIBLE_CONFIRMED`다. 나머지 190개 조합은 사유 코드와 함께 `BLOCKED`다. 프라이버시는 되돌릴 수 없으므로 확정을 요구하고, 유틸리티 부족은 되돌릴 수 있으므로 점추정 통과를 그 등급 그대로 표시한다. 192개 조합 전체를 실행기가 열거하고 감사기가 자기 규칙으로 다시 계산해 대조한다.

### 3.6 검증 코드 규격

| 모듈 | 내용 |
| --- | --- |
| `synth8/schema.py` | 행 검사기, L0/L1 변환과 역변환, EB 배치 보정, $\eta^2$ |
| `synth8/dp.py` | subsampled Gaussian RDP, zCDP, 원장, $\sigma$ 보정, AUROC 상한, 클립·잡음 집계, $\hat\varepsilon_{\text{LB}}$ |
| `synth8/generator.py` | 공개 기저, 클리핑 통계, G0 적합·표집 |
| `synth8/metrics.py` | LDA·Cox·ANOVA 학습기, 네 종점, jackknife, 판정 규칙 |
| `synth8/privacy.py` | 거리 일괄 계산, DCR, MIA, DeLong, 필요 표본 수 |
| `synth8/t81.py` | 가상 세계 → 다섯 생성기 → 판정, 출시 규칙 진리표 |
| `synth8/audit.py` | 솔버를 import하지 않는 독립 재계산과 G1–G4 판정 |
| `synth8/calibrate.py` | DCR 귀무 보정과 G0 구조 상한 탐침(동결 실행과 분리) |

```sh
python3 -B -m synth8.orchestrate --output evidence/synth8-run.json
python3 -B -m synth8.audit --run evidence/synth8-run.json --output evidence/synth8-audit.json
python3 -B -m synth8.calibrate --output evidence/synth8-calibration.json
python3 -B -m unittest discover -s tests -p test_synth8.py -v
```

증거 문서는 입력 잠금 해시, 판정에 쓰인 점수·거리·라벨 배열과 시험 분할의 인코딩 특징(기준 순위 재계산용, 모두 소수 6자리), 종점별 값과 상태, 원장, 출시 판정, 본문 SHA-256을 담는다. 문자열은 코드 토큰만 허용하고 원 단위 행은 싣지 않는다. 실자료 실행에서는 시험 특징과 점수·거리 배열이 그대로 비공개 자료이자 멤버십 정보이므로 증거 문서를 접근 통제 구역에 두고 집계만 밖으로 낸다.

| 관문 | 감사기가 하는 일 | 검사 수 |
| --- | --- | ---: |
| G1 동결 입력과 구조 | 픽스처 잠금, 범위 표지, 본문 해시, 자유 텍스트 부재 | 5 |
| G2 스키마·원장·규칙표 | 스키마 15건, 보존율 사례 12건, 출시 진리표 192행, 원장의 민감도·$\rho$·$\varepsilon$, DP-SGD 계획의 RDP를 구적으로 재계산, 빈 Poisson 배치의 잡음, 감사 표본 수, 배치 계층 효과 | 535 |
| G3 지표·상한의 독립 재계산 | 이분 탐색 쌍 세기 AUROC, placement 값 DeLong, 시간 정렬 C-index, 정밀도·재현율 F1, 세기 순위 Spearman, 제곱합 ANOVA, 불완전 베타 함수 Clopper–Pearson, jackknife 하한, 유리수 판정 | 292 |
| G4 정답과 출시 판정 | 다섯 생성기의 알려진 결론, 원장 없는 출시 0건, 판정 재도출 | 28 |

감사는 실행 문서의 배열에서 출발한다. 생성기와 학습기의 재적합은 감사기가 아니라 실행기의 바이트 동일 재실행으로 확인한다. 테스트는 상태 뒤집기, 점수·거리 변조, 출시 위조, 원장 $\sigma$ 변조, 잡음 배수 축소 보고를 주입해 감사기가 각각 지목하는지 확인한다(34개 테스트).

### 3.7 가상 자료 실측

가상 세계는 아형 3개, 공유 요인 4개, 모달리티별 사적 요인, 3개 배치의 위치·척도 효과, 결측이 있는 임상 변수 4개, 지수 생존시간을 갖는다. 학습 720, 보류 720(그중 시험 240), 공개 600, 합성 600행, 인코딩 특징 26개. 실자료 기준 모델(TRTR): AUROC 0.908, C-index 0.721, Macro-F1 0.733, Spearman 0.958.

| 생성기 | 설계상 정답 | C-index $P$ | Macro-F1 $P$ | AUROC $P$ | Spearman $P$ | 유틸리티 | DCR (복제 / $\hat\pi$ / $\hat r$) | MIA 최대 AUROC (상한) | 출시 |
| --- | --- | ---: | ---: | ---: | ---: | --- | --- | --- | --- |
| `S_ORACLE` 독립 재표집 | 유틸리티·프라이버시 통과, 원장 없음 | 1.016 | 0.987 | 1.000 | 0.971 | `PASS_POINT` | 0 / 0.497 / 0.045 → `PASS` | 0.520 (0.5503) `PASS_POINT` | `BLOCKED` (미확정, 원장 없음) |
| `S_COPY` 학습 행 복사 | 프라이버시 실패 | 1.008 | 1.005 | 0.997 | 0.999 | `PASS_CONFIRMED` | 573 / 1.000 / 1.000 → `FAIL` | 0.920 (0.936) `FAIL` | `BLOCKED` |
| `S_MIX` 15% 복사 | 프라이버시 실패 | 0.989 | 1.023 | 1.001 | 0.974 | `PASS_POINT` | 81 / 0.567 / 0.183 → `FAIL` | 0.557 (0.587) `FAIL`, TPR@FPR1% 13.2% | `BLOCKED` |
| `S_MARGINAL` 독립 주변분포 | 유틸리티 실패 | 0.740 | 0.348 | 0.469 | −0.039 | `FAIL` | 0 / 0.522 / 0.005 → `PASS` | 0.523 (0.553) `PASS_POINT` | `BLOCKED` |
| `S_DP` G0, $\varepsilon=2$, $\delta=10^{-5}$ | 측정 대상 | 1.001 | 0.992 | 0.974 | **0.914** | `FAIL` | 0 / 0.462 / 0.000 → `PASS` | 0.508 (0.538) `PASS_CONFIRMED` | `BLOCKED` (`UTILITY_FAIL`) |

- 판정 장치는 네 개의 정답 사례를 모두 옳게 갈랐다. 15%만 복사한 표는 유틸리티가 통과하지만 복제 81건, 근접 초과 18.3%, MIA 0.557로 걸린다. 독립 재표집은 경험 지표를 통과해도 원장이 없어 출시되지 않는다.
- G0는 $\varepsilon=2$(형식 AUROC 상한 0.881)에서 세 종점을 95% 이상 보존하고 프라이버시를 확정 통과했다. 바이오마커 순위 보존율 0.914와 공발현 간선 순위 상관 0.887(독립 재표집 0.977)이 남은 격차다.
- G0의 $\varepsilon$ 곡선(시드 2개 평균): $\varepsilon=1$에서 AUROC 보존율 0.747, 4에서 0.969, 8에서 0.985. Macro-F1은 8과 16에서 0.948, Spearman은 0.925와 0.914로 95% 바로 아래에서 멈춘다. 잡음을 사실상 없앤 G0($\varepsilon=1000$, 탐침 시드 4개, 보정 문서의 `g0Ceiling`)의 보존율은 평균 C-index 0.948, Macro-F1 0.962, AUROC 0.986, Spearman 0.963이고 시드별 최솟값은 0.938, 0.929, 0.975, 0.928이었다. 높은 $\varepsilon$에서 G0를 95% 근처에 묶는 것은 잡음이 아니라 구조(공개 저랭크 기저, 공통 공분산, 공개 잔차 척도)다. G1의 채택 기준은 같은 $\varepsilon$에서 이 두 종점을 0.95 위로 올리는 것이다.

---

## 4. 가정, 잔여 위험, 다음 실행

| 항목 | 내용 | 대응 |
| --- | --- | --- |
| 실자료 미실행 | TCGA·GEO·MIMIC-IV에서의 보존율과 MIA는 측정하지 않았다 | 고정된 TCGA-BRCA 분할에서 G0 → G1 순으로 같은 하네스를 실행. GPU 환경에서 2.7절 인터페이스 구현 |
| G1 미학습 | 잠재 확산·계층 VAE의 성능은 설계상 주장이다 | 채택 기준: 같은 $\varepsilon$에서 G0 대비 네 종점 모두 개선, 출시 규칙 통과 |
| 경험 MIA의 범위 | 두 공격은 지정 공격이다. 더 강한 공격의 부재를 뜻하지 않는다 | 원장 통과를 출시의 필요조건으로 유지. 공격 묶음에 shadow-model 계열을 추가할 때 Bonferroni 수와 필요 표본 수를 다시 계산 |
| 소표본 | TCGA-BRCA 시험 양성 8명, 감사 표본 372명 | 기관 단위 교차 적합, 반복 반분할 감사, 생성기 반복 표집 |
| 공개 자료 의존 | 기저·표준화·공발현 사전분포가 공개 코호트의 질에 묶인다 | 공개 코호트와 비공개 코호트의 분포 차를 L0 분위수 정렬 후 잠재 MMD로 보고 |
| 희귀 범주 | 작은 셀의 DP 통계는 잡음이 크다(2.2절 표) | 사전 규칙으로 셀 병합, 하한 미만 셀은 조건에서 제외하고 표시 |
| 독립성 | 감사기는 같은 픽스처와 배열을 읽는다. 정답을 숨긴 블라인드 환경은 아니다 | 실자료 단계에서 평가기를 별도 실행 환경으로 분리 |

재현 정보: 픽스처 SHA-256 `96b4994f79d6dee69afa88d405036d01c6d90d22dee9459c10ace0ae6cf8fce0`, 입력 잠금 `46e9410b44801c2436fb5f3adea3b59fef6e1458df40ae369a5b3db9c0e943b8`, 실행 문서 `0ef973728bff9305e54d040b3bd904120c4e0046aca0a66709bef13cab7b82e8`, 감사 문서 `005a03124a066622193732c1756b9a8f23ce4dd64f9882a2f32b8663e494ad5c`, 보정 문서 `c68c620e19c3e435aa15a10739e0b0864ff2ddf5b77bd015bd2e4baf26466056`.

참고 방법: DP-SGD(Abadi 외 2016), Rényi DP(Mironov 2017)와 sampled Gaussian의 RDP(Mironov·Talwar·Zhang 2019), zCDP(Bun·Steinke 2016), DP의 가설검정 영역(Kairouz·Oh·Viswanath 2015), ComBat(Johnson·Li·Rabinovic 2007), multimodal VAE의 Product-of-Experts(Wu·Goodman 2018), DP 확산 모형의 noise multiplicity(Dockhorn 외 2023), 밀도비 기반 합성자료 MIA(van Breugel 외 2023), AUROC 분산(DeLong 외 1988).
