본문으로 건너뛰기
Kreath Archive
TechProjectsBooksAbout
TechProjectsBooksAbout

내비게이션

  • Tech
  • Projects
  • Books
  • About
  • Tags

카테고리

  • AI / ML
  • 웹 개발
  • 프로그래밍
  • 개발 도구

연결

  • GitHub
  • Email
  • RSS
© 2026 Kreath Archive. All rights reserved.Built with Next.js + MDX
홈TechProjectsBooksAbout
//
  1. 홈
  2. 테크
  3. 7장: 프라이버시 보존 합성 데이터
2026년 4월 2일·AI / ML·

7장: 프라이버시 보존 합성 데이터

차등 프라이버시, PII 마스킹, 멤버십 추론 공격 방어, 유사도 필터, 규제 대응 전략과 프라이버시-유용성 트레이드오프를 다룹니다.

20분839자9개 섹션
synthetic-dataaidata-engineeringllmmlops
공유
synthetic-data7 / 10
12345678910
이전6장: 데이터 증강 기법다음8장: 도메인 특화 데이터셋 구축

이 장에서 배우는 것

  • 차등 프라이버시(Differential Privacy)의 수학적 원리와 실전 적용
  • PII(개인 식별 정보) 탐지와 마스킹 파이프라인
  • 멤버십 추론 공격(Membership Inference Attack)과 방어
  • 유사도 기반 아웃라이어 필터링
  • GDPR, HIPAA, 개인정보보호법 등 규제 대응 전략
  • 프라이버시와 유용성 간 트레이드오프 관리

왜 합성 데이터에 프라이버시가 중요한가

합성 데이터의 가장 큰 약속 중 하나는 프라이버시 보호입니다. 그러나 합성 데이터라고 해서 자동으로 프라이버시가 보장되는 것은 아닙니다. 생성 모델이 원본 데이터의 특정 레코드를 "기억"하고 그대로 재현할 수 있기 때문입니다. 이를 기억 현상(Memorization)이라 합니다.

Warning

"합성 데이터 = 프라이버시 안전"이라는 가정은 위험합니다. 프라이버시 보장은 자동으로 주어지는 것이 아니라, 적극적으로 설계하고 검증해야 하는 속성입니다.


차등 프라이버시(Differential Privacy)

차등 프라이버시(DP)는 데이터 프라이버시에 대한 수학적 보장을 제공하는 프레임워크입니다. 핵심 아이디어는 단순합니다: 데이터셋에 특정 개인이 포함되었는지 여부와 관계없이, 분석 결과가 거의 동일해야 한다는 것입니다.

수학적 정의

차등 프라이버시의 공식 정의는 다음과 같습니다. 랜덤화된 메커니즘 M이 epsilon-차등 프라이버시를 만족한다는 것은, 최대 한 개의 레코드가 다른 임의의 두 인접 데이터셋 D1, D2에 대해 다음이 성립하는 것입니다:

Pr[M(D1) in S] <= exp(epsilon) * Pr[M(D2) in S]

여기서 epsilon은 프라이버시 예산(Privacy Budget)이라 불리며, 값이 작을수록 프라이버시 보호가 강력합니다.

epsilon 값프라이버시 수준유용성일반적 용도
0.1~1.0매우 강함낮음민감한 의료/금융 데이터
1.0~5.0강함중간일반적인 프라이버시 보호
5.0~10.0보통높음덜 민감한 데이터
10.0+약함매우 높음형식적 보호

DP-SGD를 활용한 합성 데이터 생성

DP-SGD(Differentially Private Stochastic Gradient Descent)는 모델 학습 과정에서 차등 프라이버시를 적용하는 방법입니다. 그래디언트에 노이즈를 추가하여 개별 학습 샘플의 영향을 제한합니다.

dp_synthetic_generation.py
python
import numpy as np
from dataclasses import dataclass
 
 
@dataclass
class DPConfig:
    epsilon: float = 1.0         # 프라이버시 예산
    delta: float = 1e-5          # 실패 확률
    max_grad_norm: float = 1.0   # 그래디언트 클리핑 노름
    noise_multiplier: float = 1.1 # 노이즈 배수
    num_epochs: int = 50
    batch_size: int = 256
 
 
def add_dp_noise(
    gradients: np.ndarray,
    config: DPConfig,
) -> np.ndarray:
    """그래디언트에 차등 프라이버시 노이즈를 추가합니다."""
    # 1단계: 그래디언트 클리핑
    grad_norm = np.linalg.norm(gradients)
    if grad_norm > config.max_grad_norm:
        gradients = gradients * (config.max_grad_norm / grad_norm)
 
    # 2단계: 가우시안 노이즈 추가
    noise_scale = config.noise_multiplier * config.max_grad_norm
    noise = np.random.normal(0, noise_scale, gradients.shape)
 
    return gradients + noise
 
 
def compute_privacy_budget(
    noise_multiplier: float,
    num_steps: int,
    batch_size: int,
    dataset_size: int,
    delta: float = 1e-5,
) -> float:
    """Renyi DP 기반 프라이버시 예산을 계산합니다."""
    # 실제 구현에서는 opacus 또는 dp-accounting 라이브러리 사용
    sampling_rate = batch_size / dataset_size
    # 근사값 (정확한 계산은 라이브러리 필요)
    epsilon_estimate = (
        noise_multiplier
        * np.sqrt(2 * np.log(1.25 / delta))
        * sampling_rate
        * np.sqrt(num_steps)
    )
    return epsilon_estimate
Info

실전에서는 PyTorch의 Opacus 라이브러리를 활용하면 DP-SGD를 쉽게 적용할 수 있습니다. Opacus는 자동으로 그래디언트 클리핑, 노이즈 추가, 프라이버시 예산 추적을 수행합니다. 차등 프라이버시가 적용된 모델로 생성한 합성 데이터는 실제 데이터 대비 96.8% vs 97.2%의 정확도 차이만 보여줍니다.


PII 탐지와 마스킹

PII(Personally Identifiable Information)는 개인을 식별할 수 있는 모든 정보를 말합니다. 합성 데이터에 원본의 PII가 유출되면 프라이버시 보호의 의미가 없어집니다.

PII 탐지 파이프라인

pii_detection.py
python
import re
from dataclasses import dataclass
from enum import Enum
 
 
class PIIType(Enum):
    PHONE = "phone"
    EMAIL = "email"
    SSN = "ssn"             # 주민등록번호
    CREDIT_CARD = "credit_card"
    NAME = "name"
    ADDRESS = "address"
    IP_ADDRESS = "ip_address"
 
 
@dataclass
class PIIEntity:
    text: str
    pii_type: PIIType
    start: int
    end: int
    confidence: float
 
 
# 한국어 PII 패턴
PII_PATTERNS = {
    PIIType.PHONE: [
        r"01[016789]-?\d{3,4}-?\d{4}",
        r"02-?\d{3,4}-?\d{4}",
        r"0\d{1,2}-?\d{3,4}-?\d{4}",
    ],
    PIIType.EMAIL: [
        r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}",
    ],
    PIIType.SSN: [
        r"\d{6}-?[1-4]\d{6}",
    ],
    PIIType.CREDIT_CARD: [
        r"\d{4}-?\d{4}-?\d{4}-?\d{4}",
    ],
    PIIType.IP_ADDRESS: [
        r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}",
    ],
}
 
 
def detect_pii_regex(text: str) -> list[PIIEntity]:
    """정규식 기반으로 PII를 탐지합니다."""
    entities = []
 
    for pii_type, patterns in PII_PATTERNS.items():
        for pattern in patterns:
            for match in re.finditer(pattern, text):
                entities.append(PIIEntity(
                    text=match.group(),
                    pii_type=pii_type,
                    start=match.start(),
                    end=match.end(),
                    confidence=0.9,
                ))
 
    return entities
 
 
def mask_pii(text: str, entities: list[PIIEntity]) -> str:
    """탐지된 PII를 마스킹합니다."""
    # 뒤에서부터 치환하여 인덱스 밀림 방지
    sorted_entities = sorted(entities, key=lambda e: e.start, reverse=True)
 
    masked = text
    for entity in sorted_entities:
        mask_token = f"[{entity.pii_type.value.upper()}]"
        masked = masked[:entity.start] + mask_token + masked[entity.end:]
 
    return masked

NER 기반 PII 탐지

정규식으로 탐지할 수 없는 이름, 주소 등은 NER 모델을 활용합니다.

pii_ner_detection.py
python
def detect_pii_with_llm(text: str, model_fn) -> list[PIIEntity]:
    """LLM을 활용하여 PII를 탐지합니다."""
    prompt = f"""다음 텍스트에서 개인 식별 정보(PII)를 모두 찾아주세요.
 
PII 유형: 이름, 전화번호, 이메일, 주민등록번호, 주소,
         신용카드번호, IP 주소, 계좌번호
 
텍스트: {text}
 
JSON 형식으로 출력:
[{{"text": "탐지된 PII", "type": "PII 유형", "start": 시작위치, "end": 끝위치}}]"""
 
    result = model_fn(prompt)
    # 파싱 및 PIIEntity 변환
    return parse_pii_result(result)
Tip

PII 탐지는 "정규식 + NER + LLM"을 3계층으로 조합하는 것이 가장 효과적입니다. 정규식이 명확한 패턴을, NER이 고유명사를, LLM이 문맥 의존적 PII를 각각 담당합니다. 단일 기법의 재현율은 70~85% 수준이지만, 3계층 조합은 95% 이상을 달성할 수 있습니다.


멤버십 추론 공격과 방어

멤버십 추론 공격(Membership Inference Attack, MIA)은 특정 레코드가 모델의 학습 데이터에 포함되었는지를 판별하는 공격입니다. 합성 데이터의 프라이버시를 검증하는 핵심 도구이기도 합니다.

공격 원리

방어적 MIA 테스트

합성 데이터를 배포하기 전에, MIA를 자체적으로 수행하여 프라이버시 위험을 사전에 평가합니다.

membership_inference.py
python
import numpy as np
from sklearn.metrics import roc_auc_score
from sklearn.neighbors import NearestNeighbors
 
 
def membership_inference_test(
    synthetic_data: np.ndarray,
    training_data: np.ndarray,
    holdout_data: np.ndarray,
    k: int = 5,
) -> dict:
    """멤버십 추론 공격 시뮬레이션으로 프라이버시를 평가합니다."""
    nn_model = NearestNeighbors(n_neighbors=k, metric="euclidean")
    nn_model.fit(synthetic_data)
 
    # 학습 데이터(멤버)의 최근접 거리
    member_distances, _ = nn_model.kneighbors(training_data)
    member_avg_dist = member_distances.mean(axis=1)
 
    # 홀드아웃 데이터(비멤버)의 최근접 거리
    nonmember_distances, _ = nn_model.kneighbors(holdout_data)
    nonmember_avg_dist = nonmember_distances.mean(axis=1)
 
    # 라벨: 멤버=1, 비멤버=0
    labels = np.concatenate([
        np.ones(len(member_avg_dist)),
        np.zeros(len(nonmember_avg_dist)),
    ])
 
    # 거리가 짧을수록 멤버일 가능성이 높으므로 부호 반전
    scores = np.concatenate([
        -member_avg_dist,
        -nonmember_avg_dist,
    ])
 
    # AUC 계산: 0.5에 가까울수록 안전
    auc = roc_auc_score(labels, scores)
 
    return {
        "mia_auc": auc,
        "privacy_risk": "high" if auc > 0.6 else "low",
        "member_mean_distance": member_avg_dist.mean(),
        "nonmember_mean_distance": nonmember_avg_dist.mean(),
    }
Info

MIA AUC가 0.5에 가까울수록 공격자가 멤버와 비멤버를 구분할 수 없음을 의미하며, 프라이버시가 잘 보호되고 있다는 뜻입니다. 일반적으로 AUC가 0.55 이하이면 안전한 것으로 간주합니다. 0.6을 초과하면 프라이버시 위험을 재검토해야 합니다.


유사도 및 아웃라이어 필터

합성 데이터에서 원본과 지나치게 유사한 레코드를 사전에 제거하는 필터입니다.

similarity_filter.py
python
import numpy as np
from sklearn.neighbors import NearestNeighbors
 
 
def similarity_filter(
    synthetic: np.ndarray,
    real: np.ndarray,
    min_distance: float = 0.1,
) -> tuple[np.ndarray, np.ndarray]:
    """원본과 너무 유사한 합성 데이터를 필터링합니다."""
    nn = NearestNeighbors(n_neighbors=1, metric="euclidean")
    nn.fit(real)
 
    distances, indices = nn.kneighbors(synthetic)
    distances = distances.flatten()
 
    # 최소 거리 이상인 데이터만 유지
    safe_mask = distances >= min_distance
    safe_synthetic = synthetic[safe_mask]
    filtered_synthetic = synthetic[~safe_mask]
 
    print(
        f"필터링 결과: {safe_mask.sum()}/{len(synthetic)} 유지 "
        f"({(~safe_mask).sum()}건 제거)"
    )
 
    return safe_synthetic, filtered_synthetic

규제 대응 전략

GDPR (EU 일반 데이터 보호 규정)

GDPR에서 합성 데이터의 법적 지위는 아직 완전히 확립되지 않았지만, 다음 원칙이 적용됩니다.

  • 합성 데이터가 개인을 식별할 수 없으면 GDPR의 적용 범위 밖으로 간주될 수 있습니다.
  • 그러나 원본 데이터 처리(합성 데이터 생성을 위한)는 여전히 GDPR의 적용을 받습니다.
  • "익명화"와 "가명화"의 법적 구분이 중요합니다. 합성 데이터는 적절한 기술 조치가 적용된 경우 익명화로 인정될 수 있습니다.

HIPAA (미국 건강보험 정보 보호법)

  • HIPAA는 18가지 유형의 식별자(identifiers) 제거를 요구합니다.
  • 합성 의료 데이터는 Expert Determination 또는 Safe Harbor 방식으로 비식별화를 인증받을 수 있습니다.

한국 개인정보보호법

  • 가명정보 처리는 통계 작성, 과학적 연구, 공익적 기록 보존 목적으로 허용됩니다.
  • 합성 데이터가 가명정보에 해당하는지, 익명정보에 해당하는지에 따라 법적 의무가 달라집니다.
  • 개인정보보호위원회의 가이드라인을 참조하여 비식별 조치의 적정성을 판단해야 합니다.
Warning

규제 대응에서 기술적 조치만으로는 충분하지 않습니다. 법적 검토, 프라이버시 영향 평가(PIA), 문서화가 반드시 동반되어야 합니다. 특히 의료, 금융 등 규제가 엄격한 도메인에서는 법무팀과의 긴밀한 협업이 필수입니다.


프라이버시-유용성 트레이드오프

프라이버시와 유용성은 본질적으로 트레이드오프 관계에 있습니다. 프라이버시 보호를 강화하면 데이터의 유용성이 감소하고, 유용성을 높이면 프라이버시 위험이 증가합니다.

트레이드오프 곡선

실전 최적화 전략

privacy_utility_optimization.py
python
from dataclasses import dataclass
 
 
@dataclass
class PrivacyUtilityResult:
    epsilon: float
    tstr_score: float
    mia_auc: float
    pii_leak_rate: float
 
 
def find_optimal_privacy_level(
    real_data,
    epsilon_candidates: list[float] = [0.1, 0.5, 1.0, 2.0, 5.0, 10.0],
    min_tstr_threshold: float = 0.90,
    max_mia_auc_threshold: float = 0.55,
) -> PrivacyUtilityResult | None:
    """최적의 프라이버시 수준을 탐색합니다."""
    results: list[PrivacyUtilityResult] = []
 
    for epsilon in epsilon_candidates:
        # 1. DP 적용 합성 데이터 생성
        synthetic = generate_dp_synthetic(real_data, epsilon)
 
        # 2. 유용성 평가
        tstr = evaluate_tstr(synthetic, real_data)
 
        # 3. 프라이버시 평가
        mia = membership_inference_test(synthetic, real_data)
        pii_rate = detect_pii_leak_rate(synthetic, real_data)
 
        results.append(PrivacyUtilityResult(
            epsilon=epsilon,
            tstr_score=tstr,
            mia_auc=mia["mia_auc"],
            pii_leak_rate=pii_rate,
        ))
 
    # 조건을 만족하는 결과 중 가장 강한 프라이버시 선택
    valid = [
        r for r in results
        if r.tstr_score >= min_tstr_threshold
        and r.mia_auc <= max_mia_auc_threshold
    ]
 
    if valid:
        return min(valid, key=lambda r: r.epsilon)
    return None
Tip

프라이버시-유용성 트레이드오프에서 "정답"은 없습니다. 중요한 것은 트레이드오프를 명시적으로 측정하고, 도메인의 규제 요구사항과 비즈니스 요구사항을 균형 있게 반영하는 것입니다. 의료 데이터라면 프라이버시를, A/B 테스트 데이터라면 유용성을 우선시하는 것이 합리적입니다.


정리

이 장에서는 합성 데이터의 프라이버시 보존 기법을 체계적으로 다루었습니다.

  • 차등 프라이버시: epsilon 파라미터로 수학적 프라이버시 보장을 제공하며, DP-SGD로 생성 모델에 적용합니다.
  • PII 탐지/마스킹: 정규식, NER, LLM 3계층 접근으로 95% 이상의 재현율을 달성합니다.
  • 멤버십 추론 방어: MIA 테스트로 프라이버시 위험을 사전 평가하며, AUC 0.55 이하가 안전 기준입니다.
  • 유사도 필터: 원본과 지나치게 유사한 합성 레코드를 배포 전에 제거합니다.
  • 규제 대응: GDPR, HIPAA, 개인정보보호법 각각에 맞는 기술적/법적 조치가 필요합니다.
  • 트레이드오프: 프라이버시와 유용성의 균형점은 도메인과 규제에 따라 달라지며, 명시적 측정이 핵심입니다.
Tip

다음 장에서는 도메인 특화 합성 데이터셋 구축을 다룹니다. 의료, 법률, 금융, 코드 등 각 전문 분야에서 합성 데이터를 효과적으로 만드는 고유한 전략과 실전 사례를 살펴봅니다.

이 글이 도움이 되셨나요?

관련 주제 더 보기

#synthetic-data#ai#data-engineering#llm#mlops

관련 글

AI / ML

8장: 도메인 특화 데이터셋 구축

의료, 법률, 금융, 코드 도메인별 합성 데이터 접근법, 전문가 시드 데이터 설계, InstructLab 택소노미 방식, 도메인 검증 전략을 다룹니다.

2026년 4월 4일·22분
AI / ML

6장: 데이터 증강 기법

전통적 텍스트 증강부터 LLM 기반 증강, 어려운 예제 생성, 엣지 케이스 증강, 증강 비율 최적화까지 실전 데이터 증강 기법을 다룹니다.

2026년 3월 31일·21분
AI / ML

9장: 합성 데이터 평가와 벤치마킹

TSTR 방법론, 다양성 메트릭, 분포 비교, 다운스트림 성능 측정, 합성 vs 실제 데이터 비교 실험, 벤치마크 설계 방법을 다룹니다.

2026년 4월 5일·21분
이전 글6장: 데이터 증강 기법
다음 글8장: 도메인 특화 데이터셋 구축

댓글

목차

약 20분 남음
  • 이 장에서 배우는 것
  • 왜 합성 데이터에 프라이버시가 중요한가
  • 차등 프라이버시(Differential Privacy)
    • 수학적 정의
    • DP-SGD를 활용한 합성 데이터 생성
  • PII 탐지와 마스킹
    • PII 탐지 파이프라인
    • NER 기반 PII 탐지
  • 멤버십 추론 공격과 방어
    • 공격 원리
    • 방어적 MIA 테스트
  • 유사도 및 아웃라이어 필터
  • 규제 대응 전략
    • GDPR (EU 일반 데이터 보호 규정)
    • HIPAA (미국 건강보험 정보 보호법)
    • 한국 개인정보보호법
  • 프라이버시-유용성 트레이드오프
    • 트레이드오프 곡선
    • 실전 최적화 전략
  • 정리