k-익명성·l-다양성·t-근접성으로 설계하는 데이터 비식별화

k-익명성, l-다양성, t-근접성의 보호 범위와 파라미터 튜닝, 검증 자동화, 데이터 비식별화 운영 방식을 정리한다.

2026-08-14 · 최초 발행 2024-04-29

준식별자 그룹과 민감속성 분포를 함께 다루는 모델

데이터를 외부에 제공하거나 분석에 활용할 때 직접식별자를 삭제하는 것만으로는 충분하지 않다. 나이, 지역, 성별처럼 개별적으로는 식별자가 아니어도 조합하면 대상을 좁힐 수 있는 준식별자가 남기 때문이다.

k-익명성은 같은 준식별자 조합을 가진 레코드가 최소 k개 이상이 되도록 일반화와 억제를 적용하는 방식이다. 다만 배경지식 공격에는 취약할 수 있고, 민감속성의 분포 자체를 보호하지는 못한다.

l-다양성은 각 동질집합(equivalence class)에 민감속성 값이 최소 l개 이상의 충분한 다양성을 갖도록 요구한다. 동질성 및 유사 분포 문제를 완화하지만, 희소하거나 스큐된 분포에서는 성능이 낮아질 수 있다.

t-근접성은 각 동질집합의 민감속성 분포와 전체 데이터 분포 사이의 거리를 t 이하로 제한한다. 분포 보호는 더 강해지지만 계산 비용과 데이터 유용성 손실이 늘어날 수 있다.

이 모델들은 준식별자 식별, 우편번호를 구·시 단위로 바꾸는 계층형 일반화, 억제(suppression), 버킷화(bucketization), 정보손실과 위험 간의 균형을 전제로 한다.

속성 분류에서 릴리스 검증까지

먼저 이름과 주민번호 같은 직접식별자는 제거한다. 나이·지역·성별 같은 준식별자는 일반화 대상으로 정하고, 질병·소득처럼 보호할 값은 민감속성으로 분리한다. 일반화 계층 트리는 나이에서 연령대, 대 단위로 이어지도록 설계할 수 있으며, 정량적 정보손실(metric)도 미리 정해 둔다.

k를 보장하려면 그룹 크기를 키우고, l을 충족하려면 민감속성의 다양성을 확보해야 한다. t는 그룹별 분포가 전체 분포에서 지나치게 멀어지지 않도록 제한한다. 파라미터는 k=520, l=25, t는 분포 거리 지표와 데이터 특성에 따라 0.1~0.3 범위를 시도하며 유틸리티와 위험의 트레이드오프로 조정한다.

검증 시에는 평균 일반화 깊이, 셀 크기, 분류·회귀 성능 변화율, 정보손실(ILoss)을 유틸리티 지표로 본다. 위험 측면에서는 최소 그룹 크기와 평균 위험으로 재식별 위험을 추정하고, l-다양성 충족률 및 EMD/Wasserstein, KL/TV distance 같은 분포 거리를 확인한다.

파라미터와 규칙은 버전 관리하고, 릴리스마다 검증 리포트를 자동 생성한다. 기준에 미달하면 자동 롤백한 뒤 일반화 단계를 높이거나 민감속성 버킷을 다시 설계한다.

비식별화 처리에서 검증이 돌아가는 위치

YesNo에러입력: 원본 PII 데이터셋프로파일링:식별자/준식별자/민감속성분류파라미터 설정: k,l,t 일반화계층 로딩BEGIN TRANSACTION원본 테이블 READ LOCK변환: 일반화/억제/버킷화 적용검증1: k-익명성 최소 그룹 크기검사검증2:l-다양성(고유값/엔트로피)검사검증3: t-근접성(분포 거리)검사모든 기준 충족?COMMIT 해제출력: 비식별 데이터 릴리스 +리포트ROLLBACK 해제튜닝: 계층 상향/억제비율증가/버킷 재설계

모델별 운영상 차이

모델 성능 확장성 일관성(기준 준수 안정성) 안정성(공격 내성) 운영 편의
k-Anonymity 높음 높음 중간 낮음~중간 높음
l-Diversity 중간 중간 중간~높음 중간 중간
t-Closeness 낮음 중간 높음 높음 낮음

성능은 동일 자원 대비 처리량 기준이며, 안정성은 배경지식·동질성·스큐 공격에 대한 내성을 뜻한다.

데이터 사용 목적에 따른 설정 사례

외부 연구용 의료 데이터셋을 릴리스할 때는 질병코드를 민감속성으로, 나이·지역·성별을 준식별자로 지정할 수 있다. k=10, l=3, t=0.2로 설정하고 드문 질병코드는 희소 항목을 Other로 병합하는 버킷화로 다룬 뒤 임상 통계가 유지되는지 검증한다.

통신 로그를 사용 행태 분석 모델 학습에 활용한다면 위치는 5km 격자로 일반화하고 타임스탬프는 시간대 단위로 버킷화한다. 세션 단위 그룹은 k=20으로 구성하고 민감 카테고리의 l=2를 보장한다. 분포 왜도가 큰 카테고리에는 t-근접성을 우선 적용한다.

개발·QA 환경에 금융 테스트 데이터를 제공할 때는 원본과 같은 분포 유지가 중요하다. t=0.15를 중심에 두고 k=5로 최소 그룹 크기를 보장한다. 신용등급처럼 민감속성의 다양성이 부족하면 범주를 병합하고 합성 샘플을 추가한다.

튜닝 기준과 운영 통제

시작값은 k=10, l=3, t=0.2로 둘 수 있다. 데이터가 희소하거나 고스큐 분포라면 l↑ 또는 t↓ 조정을 검토한다. 모델 성능 손실은 ≤5~10%, 재식별 위험 평균은 ≤0.1을 목표로 둔다.

배치 전에는 k-최소 그룹 크기, 각 클래스의 l-고유값 또는 엔트로피 l, 분포 거리 ≤t를 확인한다. 실패하면 일반화 수준을 1단계 높이고, 억제 비율은 최대 5% 이내에서 늘리거나 민감속성 버킷을 재설계한다.

데이터 계보와 버전, 감사 로그를 관리하며 여러 릴리스의 조합 위험도 평가한다. 샘플링·링크 공격을 막기 위해 합성 데이터 혼합도 고려할 수 있다. t-Closeness를 강화할수록 분석 성능은 낮아질 수 있으므로, 목적 적합성을 기준으로 k/l/t를 혼합해야 한다.

검증 코드

전제조건: Python 3.10+, pandas>=2.0, numpy, scipy 설치 필요.

# pip install pandas numpy scipy
import pandas as pd
import numpy as np
from scipy.stats import entropy, wasserstein_distance

# df: 원본 또는 변환된 데이터프레임
# qids: 준식별자 컬럼 목록, sensitive: 민감속성 컬럼
def check_k_anonymity(df, qids, k=10):
    grp = df.groupby(qids).size()
    min_grp = grp.min()
    return min_grp >= k, int(min_grp)

def distinct_l_diversity(df, qids, sensitive, l=3):
    ok = True
    min_distinct = np.inf
    for _, g in df.groupby(qids):
        d = g[sensitive].nunique(dropna=True)
        min_distinct = min(min_distinct, d)
        if d < l:
            ok = False
    return ok, int(min_distinct if np.isfinite(min_distinct) else 0)

def entropy_l_diversity(df, qids, sensitive, l=2.0):
    ok = True
    min_ent = np.inf
    for _, g in df.groupby(qids):
        p = g[sensitive].value_counts(normalize=True)
        h = entropy(p, base=np.e)
        min_ent = min(min_ent, h)
        if h < np.log(l):  # 엔트로피 l-다양성 기준
            ok = False
    return ok, float(min_ent)

def t_closeness_numeric(df, qids, sensitive, t=0.2):
    ok = True
    # 전체 분포로부터 샘플 생성 필요 시 값 사용
    global_vals = df[sensitive].dropna().values
    max_dist = 0.0
    for _, g in df.groupby(qids):
        dist = wasserstein_distance(global_vals, g[sensitive].dropna().values)
        max_dist = max(max_dist, dist)
        if dist > t:
            ok = False
    return ok, float(max_dist)

# 사용 예시
# qids = ["age_band", "region", "gender"]; sensitive = "diagnosis_code"
# print(check_k_anonymity(df, qids, k=10))
# print(distinct_l_diversity(df, qids, sensitive, l=3))
# print(entropy_l_diversity(df, qids, sensitive, l=3))
# (연속형 민감속성에 대해서만) print(t_closeness_numeric(df, qids, "income", t=0.2))

SQL로 k-Anonymity 최소 그룹 크기 점검:

-- 전제: 준식별자 컬럼 age_band, region, gender
SELECT MIN(cnt) AS min_group_size
FROM (
  SELECT age_band, region, gender, COUNT(*) AS cnt
  FROM anonymized_table
  GROUP BY age_band, region, gender
) t;
-- 결과가 k 이상인지 확인

비식별화 체계가 남기는 운영 효과

재식별 위험 평균을 50% 이상 낮추고, 민감속성 누출 확률은 t 제한으로 상한 관리할 수 있다. 분석 모델 성능 저하는 5~10% 내에서 유지 가능하다.

반복 가능한 표준 프로세스가 자리 잡으면 외부 공유와 규제 대응에 대한 신뢰도를 높이고 데이터 거버넌스 성숙도를 끌어올릴 수 있다. 준식별자 일반화와 민감속성 분포 보호를 단계적으로 강화하되, 릴리스 간 조합 공격과 분포 왜도도 함께 인지해야 한다. 필요하면 차분 프라이버시와 합성 데이터를 결합한 하이브리드 아키텍처를 고려한다.

데이터 비식별화개인정보 보호k-익명성l-다양성t-근접성