바서슈타인 거리(Wasserstein Distance)란? AI에서 분포의 차이를 이동 비용으로 재는 방법
TL;DR
바서슈타인 거리는 한 확률 분포의 질량을 다른 분포로 옮길 때 필요한 최소 이동 비용으로 두 분포의 차이를 재는 방법입니다. 이 글은 이동량에 거리를 곱하는 W1을 중심으로 설명합니다. 수치 입력의 분포가 얼마나 이동했는지 비교할 때 검토합니다. 값의 위치와 가중치를 구별하고 단위·비용 정의·정규화 조건을 맞춰야 합니다. 거리 하나가 모델의 성능 저하를 확정하지는 않습니다.[1][4]
핵심 3줄 요약
- 핵심 1
얼마나 멀리 옮기는지도 봅니다. 같은 양이 이동해도 가까운 값으로 이동한 경우와 먼 값으로 이동한 경우를 다르게 셉니다. - 핵심 2
위치와 비중은 다른 입력입니다. 측정값·구간 대표값을 위치로, 그 위치의 건수·확률을 가중치로 넣습니다. - 핵심 3
거리의 종류와 단위를 남깁니다. W1·W2·제곱 비용과 정규화된 근사 결과를 같은 숫자로 비교하지 않습니다.
이 글에서 다룰 내용
- 바서슈타인 거리의 한 문장 정의
- 소요 시간의 이동으로 보는 쉬운 계산
- 확률 질량·수송 계획·누적분포의 작동 원리
- SciPy의 위치·가중치·다차원 입력 계약
- JS 거리·에너지 거리·W2·Sinkhorn과의 차이
- 분포 점검의 사용처와 실전 체크리스트
- 단위·표본 수·범주 번호·계산 비용의 주의점
바서슈타인 거리를 한 문장으로 정의하면 무엇인가요?
바서슈타인 거리는 두 확률 분포를 연결하는 가능한 수송 계획 중, 질량을 옮기는 총비용의 최솟값으로 분포 차이를 나타내는 거리입니다.
영문명은 Wasserstein Distance이며 와서슈타인 거리라고도 표기합니다. SciPy의 W1 문서는 Earth mover’s distance라는 이름도 소개합니다. 흙더미를 옮기는 비유에서 질량은 데이터가 놓인 확률 비중이고 위치는 측정값입니다. 실제 파일이나 고객 정보를 다른 서버로 전송한다는 뜻은 아닙니다.[1]
W1에서 한 경로의 비용은 옮기는 확률량과 두 위치 사이 거리의 곱입니다. 여러 경로의 비용을 더해 가장 작은 수송을 찾습니다. 양쪽 분포는 총확률이 같도록 맞추며, 필요하면 한 위치의 질량을 여러 목적지로 나눕니다. 같은 번호의 표본만 일대일로 묶는 계산과 구별합니다.[2][4]
한 줄 정리: 확률이 얼마나 달라졌는지에 더해 그 질량을 어디에서 어디까지 옮겨야 하는지도 읽습니다. 먼저 위치 사이의 거리가 업무에서 의미 있는지 확인합니다.
쉬운 예시로 이해해 볼까요?
감자나라ai님이 AI 작업의 소요 시간을 비교한다고 가정해 보겠습니다. 기준 기간의 설명용 측정값은
[1, 3]
초이고 비교 기간은
[2, 4]
초입니다. 각 관측에 같은 확률 0.5를 줍니다. 실제 서비스에서 수집한 성능 자료는 아닙니다.
1초 위치의 0.5를 2초로, 3초 위치의 0.5를 4초로 옮기면 됩니다. 총비용은
0.5 × 1 + 0.5 × 1 = 1
초입니다. 이 경우 W1은 1초입니다. 배열의 같은 위치를 무조건 짝지은 것이 아니라 최소 수송을 찾았을 때 이 연결이 맞는 예시입니다.
한 점에 전부 몰린 분포도 생각해 보세요. 0초에서 1초로 확률 1을 옮기면 W1은 1초이고, 0초에서 10초로 옮기면 10초입니다. 양쪽이 서로 겹치지 않는다는 사실은 같아도 이동 거리는 다릅니다. 값이 초 단위이면 이 W1도 초 단위로 읽습니다.
같은 위치
[0, 1, 10]
에서 두 기간의 건수가
[1, 1, 0]
과
[1, 0, 1]
이라면 0초의 절반은 그대로 두고 1초의 절반만 10초로 옮깁니다. 따라서 W1은 4.5초입니다. 뒤에서 건수와 위치를 구분할 때 다시 사용할 예시입니다.
위 결과는 Python 표준 라이브러리의 Fraction으로 누적분포 사이 면적을 계산해 검산했습니다. SciPy·POT를 실행한 결과나 실제 AI의 속도 개선 실험은 아닙니다. 같은 입력·입력 교환·단위 변환·동일 비율의 건수 확대도 별도로 확인했습니다.
쉬운 예시: 분포를 같은 모양으로 바꾸는 데 필요한 최소 운반량과 이동 거리를 함께 셉니다. W1이 1초라는 말은 모든 요청이 정확히 1초씩 늦어졌다는 뜻은 아닙니다.
왜 AI에서 바서슈타인 거리가 중요한가요?
수치 입력의 이동 크기를 비교합니다
입력 길이·센서 측정값·작업 시간처럼 값 사이 간격이 의미 있는 자료에서 분포 변화의 크기를 검토합니다. 1칸 이동과 10칸 이동을 같은 변화로 처리하고 싶지 않을 때 후보가 됩니다. 이는 정의를 적용한 활용 예시이며 특정 감시 도구의 기본 지표라고 주장하는 것은 아닙니다.
평균만으로 놓치는 분포 차이를 살핍니다
기준 표본
[-1, 1]
과 비교 표본
[0, 0]
은 평균이 모두 0이지만 W1은 1입니다. 양끝의 확률을 중앙으로 옮겨야 하기 때문입니다. 평균이 같다는 이유로 분포까지 같다고 볼 수 없는 작은 예시이며 이 계산도 표준 라이브러리로 확인했습니다.
핵심 인사이트: 이동 비용을 정하는 기준이 곧 비교의 가정입니다. 범주 이름에 임의로 붙인 번호를 거리 좌표처럼 쓰면 그 가정부터 잘못됩니다.
바서슈타인 거리는 어떤 순서로 계산하나요?
1. 위치와 확률 질량을 준비합니다
원시 표본이면 각 측정값이 위치이고 보통 관측마다 같은 비중을 둡니다. 집계 자료라면 구간 대표값을 위치로, 해당 구간의 건수를 가중치로 둘 수 있습니다. 구간 폭이 다를 때 밀도 높이를 건수처럼 넣지 않으며 집계가 원자료를 얼마나 근사하는지도 따로 적습니다.[1]
2. 양쪽 비중을 지키는 수송 계획을 찾습니다
계획의 각 칸은 한 출발 위치에서 한 도착 위치로 옮기는 질량입니다. 한 출발 위치에서 나가는 합은 그 위치의 확률과 같고, 한 도착 위치로 들어오는 합은 목표 확률과 같아야 합니다. 이 조건을 지키면서 경로별 질량과 거리의 곱을 더한 비용을 최소화합니다.[2]
3. 일차원에서는 누적분포의 차이를 더합니다
실수 한 축의 W1은 두 누적분포 함수 사이 세로 간격의 절댓값을 가로축 전체에서 적분한 값과 같습니다. 이산 예시에서는 연속한 위치 사이 구간마다 누적확률 차이에 구간 폭을 곱해 더합니다. 확인한 SciPy 1.18.0 구현도 정렬과 누적 가중치를 이용합니다.[1][6]
앞의 1·3초와 2·4초를 비교하면 1~2초 구간의 누적확률 차이는 0.5, 2~3초는 0, 3~4초는 0.5입니다. 각 구간 폭 1초를 곱해 더하면 1초입니다. 가장 큰 세로 차이만 고르는 통계나 원래 두 배열의 원소별 오차 합과는 계산이 다릅니다.
실전 팁: 원자료의 단위, 위치 배열, 가중치 배열을 함께 저장하세요. 가중치 목록만 남기면 서로 가까운 구간과 먼 구간을 나중에 구별하지 못합니다.
주요 설정과 반환값은 어떻게 읽나요?
values는 위치이고 weights는 그 위치의 비중입니다
SciPy의
u_values
와
v_values
에는 원시 관측값 또는 확률이 놓이는 위치를 넣습니다.
u_weights
와
v_weights
는 각각 자기 위치 배열과 길이가 같아야 합니다. 가중치를 생략하면 각 관측에 같은 비중을 주며 두 표본의 관측 수는 달라도 됩니다.[1][6]
앞의 건수
[1, 1, 0]
과
[1, 0, 1]
만 위치 인자로 넣으면 두 목록 모두 0 하나와 1 두 개를 가진 같은 경험분포입니다. 계산 결과는 0입니다. 실제 위치
[0, 1, 10]
를 넣고 건수는 가중치로 전달해야 앞의 4.5초 비교가 됩니다. 이 잘못된 입력 예시도 직접 검산했습니다.
가중치 정규화는 전체 건수 차이를 없앱니다
확인한 구현은 가중치가 음수가 아닌지, 합이 양수이고 유한한지 검사하고 각 분포의 합으로 나눕니다. 총합이 처음부터 1일 필요는 없습니다. 건수가 같은 비율로 늘면 정규화된 분포와 거리는 그대로이므로 총요청량·표본 수는 별도 열로 남깁니다.[6]
다차원 함수도 W1을 반환합니다
SciPy의
wasserstein_distance_nd
는 문서상 각 행을 한 관측 벡터, 각 열을 좌표로 받습니다. 두 입력은 같은 좌표 수를 사용하고 가중치는 행별 비중입니다. 위치 사이 유클리드 거리를 비용으로 쓰는 W1이며 반환값은 수송 계획 행렬이 아닌 실수 거리입니다. 이름의 nd를 W2 선택으로 읽지 않습니다.[2]
각 열의 분포를 따로 비교한 값들을 평균하는 것과 결합분포의 수송 거리는 다릅니다. 설명용 두 점 집합
[(-1,-1), (1,1)]
과
[(-1,1), (1,-1)]
은 두 열 각각의 분포가 같지만 결합분포의 유클리드 W1은 2입니다. 균등한 두 점의 가능한 짝을 직접 나열해 확인한 산술이며 SciPy 실행값은 아닙니다.
POT는 계획과 비용을 다른 함수로 돌려줍니다
POT의
ot.emd
는 수송 계획을,
ot.emd2(a, b, M)
는 주어진 비용 행렬 M에서 최소 수송 비용을 반환합니다. 함수 이름의 2만 보고 언제나 W2 거리라고 해석하지 않습니다. 공식 가이드는 비용 행렬의 정의와 필요할 때의 제곱근을 함께 확인하도록 설명합니다.[3][4]
바서슈타인 거리와 헷갈리는 용어는 무엇이 다른가요?
젠슨–섀넌 거리는 좌표 사이 이동 비용을 쓰지 않습니다
젠슨–섀넌 거리는 같은 범주의 확률과 평균 분포를 이용한 비교입니다. 구간 사이 실제 간격은 직접 반영하지 않습니다. 바서슈타인은 그 간격을 비용에 반영하므로 가까운 구간으로 옮긴 분포와 먼 구간으로 옮긴 분포를 다르게 봅니다. 두 지표의 값이나 임계값을 그대로 교환하지 않습니다.
에너지 거리는 별도의 분포 거리입니다
SciPy의
energy_distance
도 원시 값과 가중치를 받지만 같은 W1 공식은 아닙니다. 공식 문서는 표본 간 기대 거리들의 조합과, 일차원에서 누적분포 차이의 제곱 적분을 이용한 정의를 설명합니다. 입력 모양이 비슷하다고 두 반환값이 일치하거나 같은 단위를 가진다고 가정하지 않습니다.[5]
W2와 제곱 수송 비용을 구분합니다
W2는 위치 거리의 제곱을 비용으로 최소화한 뒤 제곱근을 취합니다. POT의
ot.dist
는 기본적으로 제곱 유클리드 비용을 만들므로 이를 emd2에 넣은 값은 W2의 제곱에 해당합니다.
metric="euclidean"
으로 유클리드 비용을 만들면 해당 emd2 값은 W1입니다.[4]
위치가 각각 0과 3인 한 점 분포에서는 유클리드 수송 비용이 3, 제곱 비용이 9이고 W2는 제곱근인 3입니다. 이 한 점 예시에서 W1과 W2가 같아도 일반 분포에서 항상 같다는 뜻은 아닙니다. 값과 제곱값을 기록하는 열 이름부터 구분합니다.
Sinkhorn과 데이터 드리프트는 다른 층위입니다
Sinkhorn은 엔트로피 정규화를 더한 수송 문제를 푸는 데 쓰는 알고리즘입니다. POT의
ot.sinkhorn2
는 정규화된 계획에서 계산한 선형 수송 비용을 반환한다고 안내합니다. 정규화 항까지 합친 전체 목적함수나 원래 정확한 W1과 자동으로 같지 않습니다. 정규화 강도도 함께 기록합니다.[3][4]
데이터 드리프트는 입력 분포가 달라지는 현상이고 바서슈타인 거리는 분포 차이를 재는 도구입니다. 큰 거리의 원인이 정상적인 기간 변화인지, 수집 오류인지, 실제 모델 실패인지는 추가 확인이 필요합니다.
비교 정리: W1은 이동량과 거리, W2는 제곱 거리 비용의 제곱근을 봅니다. JS·에너지 거리는 다른 정의이고 Sinkhorn은 정규화된 수송 문제의 계산 절차입니다.
실전에서는 어디에 쓰이나요?
AI 입력과 운영 수치의 분포를 점검합니다
같은 전처리를 거친 문서 길이·센서값·소요 시간의 기준 기간과 현재 기간을 비교하는 설계가 가능합니다. 이 글의 사용 예시입니다. 거리와 함께 원래 분포, 중앙값과 꼬리 구간, 누락 건수를 살펴 어떤 변화가 비용에 반영됐는지 되짚습니다.
분포 비교와 대응 관계를 나누어 검토합니다
POT는 분포 차이의 최적값과 분포 사이의 대응을 별도 사용처로 안내합니다. 거리 한 개가 필요할 때와 실제 수송 계획을 살펴야 할 때의 산출물이 다릅니다. 수학적 계획의 연결을 실제로 같은 고객·문서라는 증거로 해석하거나 자동 병합에 바로 쓰지 않습니다.[4]
바서슈타인 거리를 적용할 때 어떤 순서로 확인하나요?
1. 비교 단위와 기준 자료를 고정합니다
하나의 관측이 무엇인지, 위치의 단위와 여러 좌표의 척도가 무엇인지 적습니다. 위치·가중치의 길이, 음수 가중치, 빈 입력, 누락·무한값을 확인합니다. 원래 측정값이 음수인 것과 확률 가중치가 음수인 것은 다르므로 구분해 검사합니다.
2. 작은 분포와 반환 척도를 검산합니다
같은 분포는 0인지, 입력을 바꿔도 같은지, 한 점 이동의 비용이 예상과 맞는지 확인합니다. 초를 밀리초로 바꾸면 앞의 W1 1은 1,000이 됩니다. 이 단위 변환도 직접 검산했습니다. 함수·비용 행렬·W1 또는 W2·제곱근 여부를 결과와 함께 적습니다.
3. 업무 지표와 계산 부담을 함께 남깁니다
정상 기간 사이 변동을 살피고 비교 기간·표본 수·분할 기준을 유지합니다. 모든 거리의 보편적인 합격선은 없습니다. 다차원의 일반 수송 문제는 표본 쌍별 비용 행렬의 저장 부담도 크므로, 일차원 정렬 경로의 비용을 그대로 일반화하지 않습니다. 작은 규모에서 시간과 메모리를 먼저 확인합니다.[4]
사용할 때 무엇을 주의해야 하나요?
첫째, 명목 범주의 임의 번호를 거리로 쓰지 않습니다. 배송·환불·제품 문의에 붙인 1·2·3은 물리적 간격이 아닙니다. 번호를 바꿀 때 결과까지 달라지는 비교라면 범주 관계의 근거가 있는지 먼저 검토합니다.
둘째, 총량과 확률 분포의 차이를 나눕니다. 각자 정규화하면 10건과 1만 건이 같은 비율인 경우 거리는 같습니다. 실제 업무량이나 작은 표본의 불확실성은 담기지 않습니다. 서로 다른 총질량을 다루는 비균형 수송은 별도 문제이며 기본 거리 함수가 대신하지 않습니다.[4][6]
셋째, 단위와 이상치의 영향을 확인합니다. 멀리 떨어진 작은 확률도 거리와 곱해 비용을 만듭니다. 수집 오류와 실제 극단값을 구분하고 임의로 잘라 점수를 낮추지 않습니다. 다차원에서는 큰 단위의 좌표가 비용을 지배하는지도 살핍니다.
넷째, 거리와 통계 검정·성능 판정을 혼동하지 않습니다. 설명한 함수의 실수 반환값 자체는 p값이나 신뢰구간이 아닙니다. 큰 거리를 변화 확률로 읽거나 작은 거리를 안전성 승인으로 쓰지 않습니다. 평가 표본과 실제 오류 검토를 별도로 남깁니다.
주의: 좋은 비용 정의, 정확한 계산, 업무에 유용한 판단은 각각 확인해야 합니다. 거리 계산의 성공만으로 AI의 정확도나 원인 분석까지 완료됐다고 보고하지 않습니다.
자주 묻는 질문
Q1. 거리가 낮을수록 두 분포가 비슷한가요?
정한 위치 공간과 비용 정의에서 그렇습니다. 같은 분포의 거리는 0입니다. 다만 단위·전처리·차원이 다른 수치를 같은 눈금으로 비교하지 않으며 모델의 정확도 점수로 읽지 않습니다.
Q2. 두 기간의 표본 수가 달라도 되나요?
가능합니다. 각 표본에 같은 비중을 주거나 유효한 가중치를 지정해 두 경험분포를 비교합니다. 위치 배열과 자기 가중치 배열의 길이는 맞아야 합니다. 서로 다른 표본 수에 따른 해석의 불확실성은 별도로 검토합니다.[1][6]
Q3. 히스토그램의 건수만 두 배열로 넣으면 되나요?
아닙니다. 위치 인자에 건수를 넣으면 건수 자체의 경험분포를 비교합니다. 구간 위치를 값으로, 해당 구간 건수를 가중치로 전달합니다. 구간 대표값 사용에 따른 근사도 기록합니다.
Q4. 0인 가중치와 전부 0인 가중치는 같은가요?
일부 위치의 가중치 0은 허용되지만 전체 합은 양수이고 유한해야 합니다. 전부 0인 목록은 비교할 확률 분포가 아닙니다. 누락을 감추려고 임의의 작은 값을 더하지 않습니다.[6]
Q5. emd2라는 이름이면 언제나 W2인가요?
주어진 비용 행렬에서 최소 수송 비용을 반환하는 함수입니다. 유클리드 비용인지 제곱 비용인지 확인하고, W2를 원하면 제곱 비용을 최소화한 값에 제곱근을 취합니다. 함수 이름만으로 결과의 정의를 정하지 않습니다.[4]
Q6. 다차원 W1은 열별 W1의 평균인가요?
일반적으로 다릅니다. 열별 비교는 변수 사이 결합 관계를 잃습니다. 이 글의 두 점 예시도 각 열의 거리는 0이지만 결합분포의 거리는 2였습니다. 행·열의 의미와 사용하는 공간을 함께 기록합니다.
출처
마무리
바서슈타인 거리는 분포의 확률 질량을 옮기는 최소 비용으로 차이를 잽니다. W1의 이동량과 거리, 위치와 가중치, W2와 제곱 비용을 나누어 읽으면 겉보기에는 같은 배열이나 함수 이름에서도 다른 결과가 나오는 이유를 이해할 수 있습니다.
처음에는 두 표본과 한 점 이동부터 확인해 보세요. 실제 AI 자료에서는 단위·기준 기간·표본 수와 비용 정의를 남깁니다. 같은 조건으로 분포 변화를 비교한 뒤 원래 기록과 실제 업무 오류를 함께 검토하는 것이 마지막 점검입니다.
