수학 개념 지도
정보 이론

허프만 부호(Huffman coding)

가장 드문 두 기호를 묶어 트리⁠(tree)⁠를 쌓아 올려, 자주 나오는 기호에 짧은 부호를 주는 접두 부호(어떤 부호어⁠(codeword)⁠도 다른 부호어의 앞부분이 되지 않는 부호). 기호의 확률⁠(probability)⁠을 알 때, 기호마다 부호어 하나를 정해 두고 이어 붙여도 되살릴 수 있는 부호 가운데 평균⁠(mean)⁠ 길이가 가장 짧다.

L=∑ipi ℓi,H(p)≤LHuffman<H(p)+1L = \sum_i p_i\,\ell_i, \qquad H(p) \le L_{\text{Huffman}} < H(p) + 1
먼저 보면 좋은 개념정보 엔트로피트리

글자를 0과 1로 적을 때 모든 글자에 같은 길이를 줄 필요는 없습니다. 새뮤얼 모스의 모스 부호⁠(Morse code)⁠가 영어에서 가장 흔한 E에 점 하나를 준 것처럼, 자주 나오는 글자에 짧은 부호를, 드문 글자에 긴 부호를 주면 전체가 짧아집니다. 다만 부호를 이어 붙인 비트열을 거꾸로 끊어 읽을 수 있어야 합니다. 가장 깔끔한 방법은 어떤 부호도 다른 부호의 앞부분이 되지 않게 하는 것(접두 부호⁠, prefix code⁠)입니다. 접두 부호는 잎⁠(leaf)⁠마다 글자를 단 이진 트리와 같습니다. 뿌리에서 왼쪽 가지는 0, 오른쪽 가지는 1로 읽으며 내려가다 잎에 닿으면 한 글자가 끝납니다. 글자 i가 나올 확률이 pip_i, 부호 길이가 ℓi\ell_i이면 한 글자에 드는 평균 비트 수는 기댓값⁠(expected value)⁠ ∑piℓi\sum p_i \ell_i입니다.

이 평균을 가장 작게 하는 트리를 만드는 법은 MIT 대학원생이던 데이비드 허프만이 1951년 수업의 기말 보고서로 찾아 1952년 논문으로 발표했습니다. 글자마다 나온 횟수를 무게로 한 작은 트리 하나씩에서 시작해, 가장 가벼운 두 트리를 한 뿌리 아래로 묶는 일을 한 그루가 남을 때까지 되풀이합니다. 글: .

마디 안의 수는 무게(나온 횟수)입니다. 노란 마디가 방금 묶은 두 트리와 새 뿌리입니다. 다 묶으면 잎 아래에 부호가 나타납니다.

다 묶은 뒤의 부호는 입니다. 글 전체를 적으면 입니다(띄어 쓴 곳이 글자 경계이지만, 접두 부호라 띄어 쓰지 않아도 읽힙니다).

왜 가장 좋을까요? 최적의 트리에서 가장 드문 두 글자는 가장 깊은 곳에 형제로 놓여 있다고 해도 됩니다. 더 드문 글자가 더 흔한 글자보다 얕은 곳에 있다면, 둘을 맞바꿔도 평균은 줄거나 그대로이기 때문입니다. 또 최적의 트리에는 자식이 하나뿐인 마디가 없으니(있다면 그 마디를 없애 부호를 줄일 수 있습니다), 가장 깊은 잎에는 늘 형제 잎이 있습니다. 그 두 글자를 무게가 합쳐진 한 글자로 보면 글자가 하나 적은 같은 문제가 남고, 수학적 귀납법⁠(mathematical induction)⁠으로 매번 가장 가벼운 둘을 묶는 것이 최적임이 따라 나옵니다. 매 순간 가장 좋아 보이는 선택을 하는 욕심쟁이 알고리즘⁠(greedy algorithm)⁠이 정확한 답을 주는 드문 예입니다. 가장 가벼운 둘을 꺼내는 데 우선순위 큐⁠(priority queue)⁠를 쓰면 글자가 k가지일 때 O(klog⁡k)O(k \log k)에 끝납니다.

평균 길이는 엔트로피⁠(entropy)⁠ H 밑으로 내려갈 수 없고(섀넌의 원천 부호화 정리⁠(source coding theorem)⁠), 허프만 부호는 언제나 H 이상 H+1 미만입니다. 부호 길이가 정수라서 생기는 이 1비트 미만의 손해는 '치우친 글'에서 잘 보입니다. a가 거의 전부라 엔트로피는 글자당 0.34비트쯤인데 부호는 글자당 1비트보다 짧아질 수 없습니다. 여러 글자를 묶어 한 기호로 부호화하거나, 글 전체를 수 하나로 적는 산술 부호화⁠(arithmetic coding)⁠를 쓰면 이 손해가 줄어듭니다. 또 허프만 부호는 글자의 빈도를 미리 알아야 합니다. 앞에 나온 문자열을 가리키는 렘펠–지브 압축⁠(Lempel–Ziv compression)⁠은 빈도를 몰라도 되고, zip과 PNG가 쓰는 DEFLATE는 렘펠–지브로 반복을 줄인 뒤 그 결과를 다시 허프만 부호로 적습니다. JPEG도 이산 코사인 변환⁠(discrete cosine transform)⁠으로 얻어 양자화⁠(quantization)⁠한 계수를 마지막에 허프만 부호로 줄입니다.

이어지는 곳. 고정 길이 부호는 k가지 글자에 ⌈log⁡2k⌉\lceil \log_2 k \rceil자리의 이진수를 주는 것입니다. '고른 글'처럼 8가지 글자가 똑같이 흔하면 허프만 부호도 글자마다 3비트라 둘이 같고, 빈도가 치우칠수록 허프만 부호가 유리해집니다. 실제 글에서는 흔한 낱말과 글자가 몹시 흔하고 드문 것은 몹시 드문데(지프의 법칙⁠, Zipf's law⁠), 그 치우침이 압축의 여지입니다. 빈도가 아니라 문자열 하나만 놓고 얼마나 줄일 수 있는지를 묻는 것은 콜모고로프 복잡도⁠(Kolmogorov complexity)⁠입니다. 빈도를 잘못 알면 손해를 봅니다. 빈도 q에 맞춘 이상적인 길이 −log⁡2qi-\log_2 q_i를 실제 빈도가 p인 글에 쓰면 글자당 평균이 쿨백–라이블러 발산⁠(Kullback–Leibler divergence)⁠ D(p ∥ q)D(p\,\|\,q)만큼 길어지고, 정수⁠(integer)⁠로 올린 허프만 부호표도 대략 그만큼 손해를 봅니다.

이 개념이 나오는 큰 생각근사와 오차가장 좋은 것 고르기

이 개념이 나오는 긴 글

알고리즘과 복잡도 줄 세우기의 한계 카드 천 장을 가장 빨리 줄 세우는 방법은? 인구조사의 천공 카드에서 퀵정렬까지, 그리고 어떤 방법도 넘을 수 없는 n log n의 벽. 정보 이론과 압축 짧게 보내기 모스 부호는 왜 E를 점 하나로 보낼까? 섀넌의 엔트로피가 정한 압축의 한계와, 허프만 부호에서 JPEG까지 그 한계에 다가간 방법들. 언어 모델 다음 단어를 맞히는 기계 다음 낱말을 짐작하는 일만으로 어디까지 갈 수 있을까? 마르코프의 글자 세기에서 섀넌의 추측 게임, 트랜스포머와 규모의 법칙, 사람의 선호까지. 밑바닥에는 확률의 곱셈 규칙과 로그 하나가 있고, 그 수학은 모델이 왜 그럴듯하게 틀리는지도 말해 준다. 압축과 과학 압축하는 것이 이해하는 것이다 튀코 브라헤가 20년 동안 적은 행성의 위치를 케플러는 법칙 세 줄로 줄였다. 짧게 적는 일과 이해하는 일은 정말 같은 일일까? 오컴의 면도날을 비트로 재는 법, 과적합을 압축의 실패로 읽는 법, 그리고 그 말이 정리인 곳과 철학인 곳.

이 개념 위에 세워진 것

이 개념을 언급하는 페이지

이 페이지가 가리키는 개념