젠슨–섀넌 거리(Jensen–Shannon Distance)란? AI에서 확률 분포의 차이를 대칭으로 재는 방법
TL;DR
젠슨–섀넌 거리는 같은 항목으로 표현한 두 확률 분포가 얼마나 다른지를 대칭으로 재는 지표입니다. 두 분포의 평균을 만든 뒤 각각의 KL 발산을 평균하고 제곱근을 취합니다. SciPy의 jensenshannon은 발산이 아닌 거리를 반환합니다. 범주 비율이나 히스토그램을 비교할 때 검토합니다. 표본 수·범주 순서·로그 밑이 다르면 점수를 그대로 비교하지 않습니다.[1][2]
핵심 3줄 요약
- 핵심 1
작을수록 분포가 가깝습니다. 입력 순서를 바꿔도 같은 값이며 동일한 분포의 거리는 0입니다. - 핵심 2
발산과 거리를 구분합니다. 두 KL 발산의 평균은 JS 발산이고, 그 제곱근이 JS 거리입니다. - 핵심 3
같은 항목·같은 설정으로 비교합니다. 확률을 붙인 범주의 순서와 로그 밑을 고정하고 원래 표본 수도 따로 남깁니다.
이 글에서 다룰 내용
- 젠슨–섀넌 거리의 한 문장 정의
- 두 문의 유형의 비율로 계산하는 쉬운 예시
- 평균 분포·KL 발산·제곱근의 작동 순서
- 로그 밑·정규화·배열 축과 반환값
- 코사인 유사도·자카드·데이터 드리프트와의 차이
- 분포 비교의 사용처와 실전 체크리스트
- 0 확률·히스토그램·점수 해석의 주의점
젠슨–섀넌 거리를 한 문장으로 정의하면 무엇인가요?
젠슨–섀넌 거리는 두 확률 분포와 그 평균 분포 사이의 KL 발산을 평균한 뒤 제곱근을 취한 거리입니다.
영문명은 Jensen–Shannon Distance이며 젠센–섀넌 거리라고도 표기합니다. JS 발산과 함께 등장하므로 줄임말 JSD만 보고 어느 값을 뜻하는지 판단하지 않습니다. 이 글에서는 두 분포를 같은 비중으로 섞는 정의를 따릅니다.[1]
입력은 같은 사건이나 범주에 붙인 확률 목록입니다. 배송·환불 순서라면 양쪽 모두 그 순서를 따릅니다. 숫자 배열의 길이가 같아도 한쪽 첫 칸은 배송이고 다른 쪽 첫 칸은 환불이면 엉뚱한 사건을 서로 비교하게 됩니다.
한 줄 정리: 같은 항목에 나눠 놓은 확률의 모양이 얼마나 다른지 재며, 분포를 담은 원래 기록의 건수를 직접 재지는 않습니다.
쉬운 예시로 이해해 볼까요?
감자나라ai님이 두 기간의 문의 유형을 배송·환불 순서로 비교한다고 가정해 보겠습니다. 첫 기간은 100건 중 배송 75건·환불 25건이고, 둘째 기간은 배송 25건·환불 75건입니다. 확률로 적으면
[0.75, 0.25]
와
[0.25, 0.75]
입니다.
두 목록을 칸별로 평균하면
[0.5, 0.5]
가 됩니다. 밑 2의 로그로 첫 분포에서 평균 분포를 향한 KL 발산을 계산하면 약 0.188722입니다. 둘째 분포도 대칭인 예시라 같은 값이므로 JS 발산은 약 0.188722, 제곱근인 JS 거리는 약 0.434421입니다.
비율이 그대로인 두 기간을 비교하면 거리는 0입니다. 한 기간이 전부 배송이고 다른 기간이 전부 환불인
[1, 0]
과
[0, 1]
은 밑 2에서 거리 1이 됩니다. 이는 이 예시에서 겹치지 않는 확률 질량을 비교한 결과이며 오류율 100%라는 뜻이 아닙니다.[1]
위 수치는 Python 표준 라이브러리로 정의를 직접 계산해 확인한 설명용 결과입니다. SciPy 함수를 실행하거나 실제 문의를 분류한 실험이 아닙니다. 확률로 바꾸기 전의 건수도 남겨야 적은 기록에서 우연히 생긴 차이와 지속적인 변화를 구별할 수 있습니다.
쉬운 예시: 문의 유형은 같고 그 비중이 달라졌습니다. JS 거리는 이 비중 차이를 하나의 숫자로 요약하며, 어떤 업무 변경 때문에 달라졌는지까지 설명하지는 않습니다.
왜 AI에서 젠슨–섀넌 거리가 중요한가요?
입력과 예측을 같은 범주의 비율로 비교합니다
AI 운영에서 문의 언어·파일 유형 같은 입력 범주나 분류 모델이 출력한 클래스의 비율을 기간별로 점검할 때 분포 비교를 검토합니다. 원문을 그대로 비교하는 대신 공통 범주별 확률 목록을 먼저 만듭니다. 이는 정의를 적용한 사용 예시이며, 특정 서비스가 기본 감시 지표로 쓴다고 주장하는 것은 아닙니다.
방향을 정하지 않은 분포 차이를 읽습니다
KL 발산은 어느 분포를 먼저 놓는지가 중요하지만 JS 거리는 두 쪽을 같은 비중으로 다룹니다. 두 집계의 차이를 대칭으로 표시하려는 작업에 맞습니다. 다만 대칭이라는 수학적 성질과 기준 기간을 올바르게 골랐다는 운영 판단은 별개입니다.[1][2]
핵심 인사이트: 거리의 장점은 서로 다른 확률 배분을 일정한 규칙으로 비교하는 데 있습니다. 분류의 정확도나 답변의 사실성을 평가하는 지표로 바꿔 읽지 않습니다.
젠슨–섀넌 거리는 어떤 순서로 작동하나요?
1. 유효한 두 확률 분포를 준비합니다
원소가 음수가 아니고 합이 양수인 목록을 각자 합으로 나눕니다. SciPy는 입력 합이 1이 아니면 정규화한다고 안내합니다. 예를 들어 건수
[75, 25]
와 비율
[0.75, 0.25]
는 같은 분포입니다. 음수나 합이 0인 목록을 확률 분포로 취급해서는 안 됩니다.[1]
2. 평균 분포를 기준으로 두 KL 발산을 구합니다
평균 분포의 각 칸은
(p_i + q_i) / 2
입니다. 각 원소의 상대 엔트로피는 양수끼리라면
x * log(x / y)
로 계산하고 이를 더해 KL 발산을 구합니다. SciPy의 rel_entr 문서는 원소별 계산이며 entropy 문서는 분포 전체의 상대 엔트로피 계산임을 구분합니다.[2][3]
한쪽 확률이 양수이면 평균 분포의 같은 칸도 양수입니다. 양쪽 모두 0인 칸은 상대 엔트로피의 0 처리 규칙에 따라 기여가 0입니다. 유효한 분포에서 한쪽에 0이 있다는 이유만으로 무한대가 되는 직접 KL 비교와 다른 부분입니다.[1][3]
3. 평균 발산에 제곱근을 취합니다
두 KL 발산을 더해 2로 나누면 JS 발산입니다. 그 값에 제곱근을 취하면 JS 거리입니다. SciPy jensenshannon도 이 거리를 반환합니다. 발산과 거리는 같은 순서를 줄 수 있어도 수치가 다르므로 기존 알림 기준을 그대로 공유하지 않습니다.[1]
실전 팁: 결과 열 이름에 거리인지 발산인지 표시하고 로그 밑도 함께 기록하세요. 같은 JS라는 이름으로 저장된 두 열이 실제로 같은 계산인지부터 확인합니다.
주요 설정과 결과는 어떻게 읽나요?
base는 로그의 밑을 정합니다
jensenshannon의
base=None
은 entropy의 기본 로그 밑을 따르며 entropy 문서는 자연로그를 기본으로 안내합니다. 밑 2의 값과 자연로그의 값을 같은 눈금으로 섞지 않습니다. 같은 분포 쌍도 로그 밑을 바꾸면 거리의 크기가 바뀝니다.[1][2]
정의에서 밑 2의 JS 발산과 거리는 모두 0부터 1 사이입니다. 자연로그에서는 발산의 상한이 약 0.693147이고 거리의 상한은 약 0.832555입니다. 이 범위는 유효한 두 분포를 같은 비중으로 섞은 경우의 계산 성질입니다. 밑을 생략한 점수에 무조건 상한 1을 붙여 정규화된 점수라고 보고하지 않습니다.
axis와 keepdims는 비교 방향과 결과 모양을 정합니다
SciPy jensenshannon의 기본값은
axis=0
입니다. 각 행이 하나의 분포인 두 배열을 행별로 비교하려면
axis=1
을 지정합니다. 기본값에 맡기면 의도한 각 행 대신 열 방향으로 계산할 수 있습니다. 배열의 행과 열이 무엇인지 먼저 적습니다.[1]
keepdims=True
는 계산으로 줄어든 축을 길이 1로 남깁니다. 거리의 정의를 바꾸거나 여러 분포를 한꺼번에 평균하는 옵션이 아닙니다. 후속 연산이 기대한 결과 모양을 받는지 확인하는 설정입니다.[1]
pdist는 모든 행 쌍의 거리를 압축해 반환합니다
SciPy의
pdist
는 관측치를 행으로 받으며
metric="jensenshannon"
을 지원합니다. 분포가 3행이면 서로 다른 행의 쌍은 3개이고 반환값은 그 거리들을 담은 압축된 1차원 배열입니다. 대각선과 반대쪽 중복 항목을 담은 정사각형 행렬로 착각하지 않습니다.[4]
단일 함수의 선택 인자가 모든 일괄 계산 경로에 그대로 전달된다고 가정하지 않습니다. 사용하는 경로의 지원 인자와 로그 밑을 확인하고, 작은 두 분포의 계산과 맞춰 봅니다. 표본을 하나 추가하면 쌍의 배열 위치가 달라질 수 있으므로 행의 식별자와 반환 순서도 함께 관리합니다.[4]
젠슨–섀넌 거리와 헷갈리는 용어는 무엇이 다른가요?
KL 발산과의 차이
KL 발산은 한 분포를 다른 분포와 직접 비교하며 일반적으로 대칭이 아닙니다. 한쪽에만 양의 확률이 있는 사건에서는 방향에 따라 무한대가 됩니다. JS는 두 입력을 직접 맞대는 대신 공통 평균을 놓고 각각의 KL 발산을 계산합니다. 그 뒤 제곱근을 취한 거리와 KL 발산의 원래 값을 구별합니다.[1][2][3]
코사인 유사도와의 차이
코사인 유사도는 벡터 방향을 비교합니다. JS 거리는 같은 사건에 배분한 확률을 비교합니다. 음수도 있는 일반 임베딩을 확률 목록처럼 넣지 않습니다. JS 거리가 작다는 사실만으로 원문 두 개의 뜻이 같다고 결론 내릴 수 없습니다.
자카드 유사도와의 차이
자카드 유사도의 기본 집합 비교는 어떤 원소가 함께 존재하는지를 봅니다. 두 문의 집계에 배송과 환불이 모두 있으면 종류의 집합은 같아도 비중은 달라질 수 있습니다. JS 거리는 이 확률 배분의 차이를 다루므로 출현 여부만 비교한 결과와 구별합니다.
데이터 드리프트와의 차이
데이터 드리프트는 기준과 현재 입력의 분포가 달라지는 현상입니다. JS 거리는 그 차이를 재는 데 검토할 수 있는 계산 규칙입니다. 현상을 뜻하는 용어와 측정 도구를 구분하며, 거리 하나를 얻었다고 변화의 원인이나 성능 저하를 단정하지 않습니다.
비교 정리: KL은 방향 있는 발산, JS는 평균 분포를 이용한 대칭 비교, 코사인은 벡터 방향, 자카드는 집합의 겹침을 다룹니다. 데이터 드리프트는 관찰하려는 변화 현상입니다.
실전에서는 어디에 쓰이나요?
기간별 범주 구성의 변화를 점검합니다
분류 모델이 출력한 클래스 비율이나 입력 언어 비율을 비교하는 작은 점검에 적용해 볼 수 있습니다. 이는 실무 적용 예시입니다. 원래 건수·누락 건수·집계 기간을 함께 저장하고, 새 범주가 생기면 양쪽에 같은 칸을 둔 뒤 비교합니다.
같은 구간으로 만든 히스토그램을 비교합니다
입력 길이나 측정값을 공통 구간으로 나눈 뒤 구간별 건수를 확률로 바꾸어 비교할 수 있습니다. 구간 경계를 각각 새로 만들면 같은 칸이 다른 값 범위를 뜻하므로 경계를 고정합니다. 연속값의 밀도 높이와 구간에 담긴 확률 질량도 구별합니다. 구간 폭이 다르면 높이를 그대로 정규화한 목록이 원하는 확률이 아닐 수 있습니다.
실전 팁: 점수 옆에 범주별 비율도 남기세요. 차이가 커진 칸을 원래 기록으로 되짚어야 집계 오류와 실제 구성 변화를 가려낼 수 있습니다.
젠슨–섀넌 거리를 적용할 때 어떤 순서로 확인하나요?
1. 비교할 사건 목록과 기준 집계를 고정합니다
범주의 이름과 순서, 히스토그램의 경계, 누락값과 기타 범주의 처리 규칙을 맞춥니다. 각 집계가 비어 있지 않은지 확인하고 원래 건수를 기록합니다. 라이브러리가 자동 정규화한다는 이유로 단위나 집계 조건의 차이를 생략하지 않습니다.
2. 작은 분포로 수치와 반환 형태를 시험합니다
동일 분포는 0인지, 입력을 바꿔도 같은지, 밑 2의 겹치지 않는 분포는 1인지 확인합니다. 행별 비교라면 축을 명시하고 결과 개수도 봅니다. 이 글의 설명용 검산은 표준 라이브러리 계산으로 이 성질을 확인했으며 설치된 SciPy의 실행 시험을 대신한 것으로 보고하지 않습니다.
3. 업무 기준과 함께 결과를 보관합니다
거리인지 발산인지, 로그 밑과 사용 함수, 라이브러리 버전, 비교한 기간과 사건 목록을 저장합니다. 정상적인 기간 사이의 변동도 살펴 알림 기준을 정합니다. 보편적인 합격선은 없으므로 다른 팀의 점수 하나를 내 데이터의 임계값으로 그대로 옮기지 않습니다.
사용할 때 무엇을 주의해야 하나요?
첫째, 0 확률과 빈 집계를 구분합니다. 특정 범주의 확률 0은 유효할 수 있지만 모든 칸이 0인 집계는 확률 분포가 아닙니다. 음수·무한대·누락값도 별도로 검사합니다. 반환값이 나왔다는 이유로 입력 검증을 마친 것으로 보지 않습니다.[1][3]
둘째, 임의의 작은 수를 더하면 비교 대상이 바뀝니다. 유효한 두 분포에서 0이 나왔다는 이유만으로 평활화를 강제하지 않습니다. 평활화가 필요한 업무라면 추가한 값과 재정규화 규칙을 기록하고 작은 범주의 차이가 얼마나 줄었는지 확인합니다.
셋째, 거리에 표본 수나 신뢰구간이 들어 있지 않습니다. 같은 비율이면 집계 건수가 달라도 JS 거리는 같습니다. 작은 표본의 흔들림과 실제 변화를 구별하는 통계 검토는 별도로 설계합니다. 거리가 0.4라는 숫자를 변화 확률 40%로 바꿔 읽지 않습니다.
넷째, 구간 사이의 실제 거리를 재지 않습니다. 히스토그램의 이웃 구간으로 확률이 옮겨졌는지 멀리 떨어진 구간으로 옮겨졌는지는 좌표 간격 자체로 반영되지 않습니다. 값의 이동 거리가 필요한 업무에는 이 점이 맞는지 따로 검토합니다.
주의: 분포가 비슷해도 모델의 정답률이나 공정성이 같다는 보장은 없습니다. 반대로 분포가 달라도 정상적인 업무 변화일 수 있습니다. 원래 기록과 실제 결과를 함께 확인합니다.
자주 묻는 질문
Q1. JS 발산과 JS 거리는 같은 값인가요?
같지 않습니다. 같은 비중의 두 KL 발산을 평균한 값이 발산이고 그 제곱근이 거리입니다. SciPy jensenshannon은 거리를 반환하므로 이름과 반환 정의를 함께 확인합니다.[1]
Q2. 결과가 0.3이면 30%가 달라졌다는 뜻인가요?
아닙니다. 로그를 이용한 분포 비교 수치이며 오류 비율이나 변화 확률이 아닙니다. 로그 밑과 거리·발산 구분도 알아야 해석할 수 있습니다.
Q3. 한 범주의 확률이 0이면 반드시 평활화해야 하나요?
유효한 분포의 일부 0은 평균 분포를 이용한 계산에서 다룰 수 있습니다. 모든 칸이 0인 빈 집계와 구별하며 0이 있다는 이유만으로 임의의 값을 더하지 않습니다.[1][3]
Q4. 원래 건수를 그대로 넣어도 되나요?
SciPy는 합이 1이 아니면 정규화한다고 안내합니다. 다만 각 집계의 합은 양수이고 항목은 음수가 아니어야 합니다. 건수를 정규화하면 총량 정보가 빠지므로 원래 합계도 따로 보관합니다.[1]
Q5. 모든 임베딩 벡터에 JS 거리를 쓰면 되나요?
아닙니다. 이 정의의 입력은 같은 사건에 대한 확률 분포입니다. 일반 임베딩의 음수 원소를 잘라 확률로 바꾸면 원래 표현의 뜻이 달라질 수 있으므로 비교 목적에 맞는 지표를 고릅니다.
Q6. JS 거리가 작으면 데이터 드리프트가 없나요?
정해 둔 범주나 구간의 비율이 비슷하다는 제한된 관찰입니다. 구간 안쪽의 변화나 변수 사이 관계는 가려질 수 있습니다. 수집 오류와 실제 모델 성능을 별도로 확인합니다.
출처
마무리
젠슨–섀넌 거리는 두 확률 분포의 평균을 놓고 각각의 KL 발산을 평균한 뒤 제곱근을 취한 값입니다. 같은 범주의 확률 배분을 대칭으로 비교하며 거리와 발산, 로그 밑, 배열 축을 구분하면 점수의 뜻을 잘못 읽는 일을 줄일 수 있습니다.
처음에는 동일 분포와 두 범주의 작은 예시부터 확인해 보세요. 실제 데이터에서는 범주 순서와 집계 조건을 맞추고 원래 건수도 함께 남깁니다. 분포 차이의 크기와 업무의 품질 판정은 분리해서 살펴봅니다.
