12.5 Lempel–Ziv 符号
ここまでの符号は,どれも 定義 12.1.1 の枠組みの中にあった.分布の族が与えられていて,そのどれが真かだけが分からない,という設定である.冗長度もミニマックス冗長度も,その族に対して定めた量だった.本節はその枠組みを離れる.前節の終わりに立てた問い,すなわち記憶のある情報源に対して,族を用意せずに1文字あたりの符号長をエントロピーレート(定義 3.2.1)まで下げる符号があるか,に答えるためである.定義 12.1.1 の族の分布はどれも1文字ずつの積なので,記憶のある情報源は,族をどう取り替えてもそこには入らない.そこで情報源の分布を持ち出さず,手元にある一本の系列だけを見て符号を作る.手がかりにするのは,系列の中で同じ並びが繰り返し現れることである.同じ並びが何度も出てくるなら,二度目からはその並びを指し示すだけで済む.どこがどう繰り返しているかは,分布を知らなくても系列そのものから読み取れる.
作り方はこうである.系列を先頭から読み,これまでに切り出した断片のどれとも違う並びが現れたところで区切り,その断片を辞書に加える.次からは辞書にある断片を足がかりにできるので,同じ並びが何度も出てくる系列では,断片がだんだん長くなり,本数が減っていく.断片の本数が減れば,それを書き並べるビット数も減る.これが 1978 年に提案された方式(LZ78 と呼ばれる)で,本書では Lempel–Ziv 符号 と呼ぶ.本節は分解の性質を三つ(フレーズが相異なること,長さの総和,本数の範囲)押さえ,そこから符号長を定めて評価する.
先に断りを一つ置く.本節が「符号長」と呼ぶのは,分解から決まるビット数のことである.12.2 節で述べた本章の方針では,長さの組が Kraft の不等式(定義 4.2.4)を満たすことを確かめたうえで,その長さをもつ符号の存在を 定理 4.2.2 に任せてきた.本節が定めるビット数については,その不等式を本書では確かめない.以下の評価はそのビット数についてのものであって,それを符号語長とする符号が読む側で復号できることまでは述べていない.
道具を一つ借りる.実数𝑡に対し,𝑡以下の最大の整数を⌊𝑡⌋と書き,床関数と呼ぶ.床関数について⌊𝑡⌋ ≤𝑡 <⌊𝑡⌋ +1が成り立つこと,および𝑠 ≤𝑡ならば⌊𝑠⌋ ≤⌊𝑡⌋であることを既知とする.当てる相手は,補題 12.5.6 の証明で対数の値を整数に切り下げるところ,定義 12.5.9 の符号長,定理 12.5.10 の証明で二つの床関数の値を比べるところ,そして 系 12.5.12 の証明で⌊𝑡⌋ ≤𝑡を使うところである.第14章 14.2 節 命題 14.2.3 の証明も,時分割の切れ目⌊𝜆𝑛⌋を評価するのにこの宣言を引く.ただしあちらが引くのは挟み撃ちの不等式のほうだけで,単調性は使わない.
系列を分解する
定義 12.5.1(最長一致の貪欲な分解). Xを空でない有限アルファベット,𝑥をXの文字を並べた有限列とする.辞書 を空の並び,区切り候補 を空列として始め,𝑥の文字を先頭から1つずつ読む.読んだ文字を区切り候補の末尾に足した列を𝑤とし,𝑤が辞書にあれば区切り候補を𝑤に置き換え,𝑤が辞書になければ𝑤を フレーズ として出力したうえで辞書の末尾に加え,区切り候補を空列に戻す.𝑥を読み終えた時点で区切り候補に残っているものは出力しない.出力されたフレーズを出力順に並べた列をS(𝑥) =(𝑠1,…,𝑠𝑘)と書き,その項数𝑘を|S(𝑥)|と書く.S(𝑥)を𝑥の 最長一致の貪欲な分解 と呼ぶ.
定義 12.5.1 の分岐をそのまま読むと,区切り候補は辞書にある列である限り伸び続け,辞書から外れた瞬間に区切られる.すなわち区切り候補は,つねに空列であるか辞書にある列であるかのどちらかで,出力されるフレーズは「辞書にある列(または空列)に1文字足したもの」である.最長一致という名前は,区切る前に候補をできるところまで伸ばす,というこの動きから来ている.読み終えたところで候補に残った切れ端を出力しないので,フレーズを全部つないでも𝑥に届かないことがある.そのぶんが 命題 12.5.4 の「以下」である.ただし,この切れ端も空列であるか辞書にある列であるかのどちらかだから,フレーズの並びに加えて,切れ端が辞書の何番目かを最後にもう一つ書き添えれば,𝑥全体が読み取れる.書き添えないと𝑥は決まらない.たとえば𝑥 =10と𝑥 =101は,どちらも分解が(1,0)で,違いは切れ端が空列か1かというところにしかないからである.
例 12.5.2(13文字の二値系列). X ={0,1},𝑥 =1011010100010(長さ13)とすると
S(𝑥)=(1,0,11,01,010,00,10)であり,|S(𝑥)| =7,フレーズの長さの総和は13である.
証明. 定義 12.5.1 の手続きを追う.辞書は空,候補は空列から始まる.第1の文字1で𝑤 =1となり,辞書は空だから1を出力して辞書に加える.第2の文字0で𝑤 =0となり,辞書には1しかないから0を出力して加える.第3の文字1で𝑤 =1となり,これは辞書にあるから候補が1になる.第4の文字1で𝑤 =11となり,辞書に無いから11を出力して加え,候補を空に戻す.以下同様に,第5・第6の文字0,1で01を,第7から第9の文字0,1,0で010を(0も01も辞書にあるので候補が二度伸びる),第10・第11の文字0,0で00を,第12・第13の文字1,0で10を出力する.出力は7本で,読み終えた時点の候補は空列だから,長さの総和は𝑥の長さ13に等しい.◼
例 12.5.2 では,7本のフレーズのうち5本が2文字以上である.辞書が育つほど候補が長く伸びられるようになる,というのが 定義 12.5.1 の仕掛けである.逆に,どのフレーズも短いままなら,長さの総和が同じでも本数が増える.本数と長さのこのやりとりが,次の三つの主張で押さえる分解の性質であり,符号長の評価をそのまま決める.
分解の性質
命題 12.5.3. Xを空でない有限アルファベット,𝑥をXの文字を並べた有限列とすると,S(𝑥)(定義 12.5.1)のフレーズはどの二つも相異なる.
証明(読んだ文字数についての数学的帰納法). 「辞書は,そこまでに出力したフレーズを出力順に並べたものに一致する」という不変量を示す.0文字読んだ時点では辞書も出力も空であり,定義 12.5.1 の二つの分岐のどちらでも保たれる(第1の分岐は辞書も出力も変えず,第2の分岐は同じ列𝑤を両方の末尾に同時に加える).
フレーズが出力されるのは𝑤が辞書に無いときだけで,そのとき辞書はそれまでに出力したフレーズの全体だから,出力されるフレーズはそれ以前のどのフレーズとも異なる.出力の順に見れば,どの二つのフレーズも相異なる.◼
命題 12.5.4. Xを空でない有限アルファベット,𝑥をXの文字を並べた有限列とする.S(𝑥)(定義 12.5.1)のフレーズはどれも空列でなく,それらを出力順に連結した列は𝑥の語頭(定義 4.1.2)であり,フレーズの長さの総和は𝑥の長さ以下である.
証明(読んだ文字数についての数学的帰納法). フレーズが空列でないことは,出力されるのが区切り候補に読んだ文字を1つ足した列だからである.
残りの二つには,「そこまでに出力したフレーズを出力順に連結した列に,その時点の区切り候補をつないだものは,そこまでに読んだ文字を順に並べた列に等しい」という不変量を立てる.0文字読んだ時点では三つとも空列であり,読んだ文字を𝑎とすると,定義 12.5.1 の二つの分岐のどちらでも保たれる(第1の分岐は候補の末尾に𝑎を足し,第2の分岐は候補に𝑎を足した列を出力へ移して候補を空列に戻すので,どちらもつないだ列の末尾に𝑎を足す).
𝑥を読み終えた時点で不変量を読むと,フレーズを連結した列に最後の区切り候補をつないだものが𝑥に等しい.よって連結した列は𝑥の語頭であり,その長さ,すなわちフレーズの長さの総和は𝑥の長さ以下である.◼
系 12.5.5. Xを空でない有限アルファベット,𝑥をXの文字を並べた長さ𝑛の有限列とすると|S(𝑥)| ≤𝑛であり,さらに𝑛 ≥1ならば|S(𝑥)| ≥1である(S(𝑥)は 定義 12.5.1 の貪欲な分解).
証明. 上界から見る.命題 12.5.4 よりフレーズはどれも空列でないから,長さはどれも1以上であり,本数は長さの総和以下である.同じ命題より長さの総和は𝑛以下だから,本数も𝑛以下である.
下界に移る.𝑛 ≥1だから,定義 12.5.1 で最初の文字を読んだ時点で𝑤は1文字の列になり,そのときの辞書は空だから𝑤は出力される.よってフレーズは少なくとも1本ある.◼
系 12.5.5 の上界は,どのフレーズも1文字のままだった場合,つまり分解が何も学ばなかった場合の勘定である(実際には 命題 12.5.3 よりフレーズは相異なるので,1文字のフレーズは高々|X|本しかなく,𝑛が|X|を超えるとこの上界は達成されない.二値なら𝑛 ≥3で達成されない).命題 12.5.4 より長さの総和は𝑛を超えないから,フレーズが長くなればそのぶん本数は減る.次はその減り方を,系列の中身によらない形で押さえる.効くのは 命題 12.5.3 の「相異なる」と,命題 12.5.4 の「空列でない」「長さの総和が𝑛以下」の三つだけで,どんな並びであろうと,相異なる列を何本もそろえるには文字数が要る,という一点に帰する.
フレーズは何本まで作れるか
補題 12.5.6(相異なる列の詰め込み). Xを空でない有限アルファベット,𝑘 ≥1とし,𝑠1,…,𝑠𝑘をXの文字を並べた空でない有限列で,どの二つも相異なるものとすると
𝑘log2𝑘≤3log2(|X|+1)𝑘∑𝑗=1|𝑠𝑗|である.
証明. 𝑇 :=∑𝑘𝑗=1|𝑠𝑗|と置く.Xは空でないから|X| +1 ≥2であり,log2(|X| +1) ≥1である.また各|𝑠𝑗|は1以上だから𝑘 ≤𝑇である.𝑘 =1のときは左辺が0で右辺は0以上だから,以下𝑘 ≥2とする.
まず詰め込みを数える.𝑚を0以上の整数とすると,Xの文字を並べた長さ𝑚以下の列は高々(|X| +1)𝑚本しかない.実際,Xに属さない記号∗を一つ用意し,長さ𝑚以下の列に,末尾に∗を足して長さちょうど𝑚にそろえた組を対応させる.もとの列に∗は現れないから,組の最初の∗の手前までを読めばもとの列が復元でき,この対応は単射である.行き先はXに∗を足した|X| +1個の記号を𝑚個並べた組の全体で,その個数は(|X| +1)𝑚である.
次に長さで分ける.
𝑚0:=⌊log2(𝑘/2)log2(|X|+1)⌋と置く.𝑘 ≥2よりlog2(𝑘/2) ≥0だから𝑚0は0以上の整数であり,床関数の性質とlog2(|X| +1) >0から𝑚0log2(|X| +1) ≤log2(𝑘/2),すなわち(|X| +1)𝑚0 ≤𝑘/2である.前段より長さ𝑚0以下の𝑠𝑗は高々(|X| +1)𝑚0本,すなわち𝑘/2本以下だから,長さ𝑚0 +1以上の𝑠𝑗が𝑘/2本以上ある.長さは非負だから
𝑇≥(𝑚0+1)⋅𝑘2である.床関数の性質log2(𝑘/2) <(𝑚0 +1)log2(|X| +1)を入れ,2log2(|X| +1) >0を掛けると
2𝑇log2(|X|+1)>𝑘(log2𝑘−1)となる.
最後にまとめる.log2(|X| +1) ≥1と𝑘 ≤𝑇から𝑘 ≤𝑇log2(|X| +1)である.前段の不等式に足して𝑘log2𝑘 <3 𝑇log2(|X| +1)を得る.◻
補題 12.5.6 の読み方は素直である.長さをある値以下に抑えた列は,その値で決まる本数しかないので,相異なる列を多く用意するほど,そのうち長いものの割合が増え,文字数の合計が膨らむ.裏返せば,文字数の合計が𝑛しかないところに詰め込める相異なる列の本数には限りがある.次の定理はこれを分解に当てる.
定理 12.5.7(貪欲な分解のフレーズ数). Xを空でない有限アルファベット,𝑛 ≥1,𝑥 ∈X𝑛とすると
|S(𝑥)|log2|S(𝑥)|≤3log2(|X|+1)𝑛である(S(𝑥)は 定義 12.5.1 の貪欲な分解).
系 12.5.8. Xを空でない有限アルファベット,𝑛 ≥2,𝑥 ∈X𝑛とすると
|S(𝑥)|≤6log2(|X|+1)𝑛log2𝑛である(S(𝑥)は 定義 12.5.1 の貪欲な分解).右辺の係数はXだけで決まり,𝑛にも𝑥にも依らない.
証明. 𝑘 :=|S(𝑥)|と置く.𝑛 ≥2よりlog2𝑛 ≥1 >0であり,|X| ≥1より3log2(|X| +1) ≥3である.定理 12.5.7 より𝑘log2𝑘 ≤3log2(|X| +1) 𝑛である.𝑘と√𝑛の大小で二つに分ける.
𝑘 ≥√𝑛の場合を見る.𝑘は整数で√𝑛 >1だから𝑘 ≥2であり,log2𝑘 ≥12log2𝑛 >0である.𝑘log2𝑘 ≤3log2(|X| +1) 𝑛の両辺をlog2𝑘で割ると
𝑘≤3log2(|X|+1)𝑛log2𝑘≤6log2(|X|+1)𝑛log2𝑛である.
𝑘 <√𝑛の場合に移る.補題 1.1.7 の対数不等式log𝑡 ≤(𝑡 −1)log𝑒を底2のもとで𝑡 :=√𝑛に当てると12log2𝑛 ≤(√𝑛 −1)log2𝑒 ≤√𝑛 log2𝑒である.ここで2log2𝑒 =2.885…であり,|X| ≥1より6log2(|X| +1) ≥6だから,log2𝑛 ≤2log2𝑒 √𝑛 ≤6log2(|X| +1)√𝑛である.両辺に√𝑛 >0を掛けてlog2𝑛 >0で割ると√𝑛 ≤6log2(|X| +1) 𝑛/log2𝑛を得る.𝑘 <√𝑛と合わせて主張が従う.◼
系 12.5.8 が言っているのは,分解のフレーズ数が長さに比べて小さい,ということである.系 12.5.5 の𝑛本という上界に対し,𝑛が大きいところではlog2𝑛分の1の水準までしか作れない(短い系列では 系 12.5.5 のほうが小さい.|X| =2なら 系 12.5.8 の右辺が𝑛を下回るのは𝑛 ≥730からで,例 12.5.2 の𝑛 =13では33.4…対13である).しかもこれは系列の中身によらず,どんな並びに対しても成り立つ.この差がそのまま符号長に効く.フレーズ1本を書くのに要するビット数は,次の定義で見るとおりlog2𝑛の水準だからである.次はその勘定を最後まで書き下す.
符号長
定義 12.5.9(Lempel–Ziv 符号長). Xを空でない有限アルファベット,𝑛 ≥0,𝑥 ∈X𝑛とし,𝑘 :=|S(𝑥)|(定義 12.5.1)と置く.𝑥の Lempel–Ziv 符号長 を
ℓLZ𝑛(𝑥):=𝑘(⌊log2(𝑘+1)⌋+⌊log2|X|⌋+2)で定める.
括弧の中は,フレーズ1本を書くのに割り当てるビット数である.内訳はこうである.定義 12.5.1 の分岐から読んだとおり,各フレーズは辞書にある列(または空列)に1文字足したものだった.そこで各フレーズを,足す前の列が辞書の何番目かという番号と,足した1文字との対で書く.番号のほうは,空列の場合を合わせて𝑘 +1通りを区別すればよいので⌊log2(𝑘 +1)⌋ +1ビット,文字のほうは|X|通りだから⌊log2|X|⌋ +1ビットである.二つを足したものが括弧の中で,どのフレーズにも同じだけ割り当てる(辞書が小さいうちは番号がもっと短く書けるが,本数を掛けたときの見積もりを簡単にするため,最後の大きさにそろえておく).対の並びを先頭から読めば,番号の指す列に文字を足してフレーズが一本ずつ決まり,辞書もそのつど組み直せるから,フレーズの列はここから復元できる.定義 12.5.1 の直後に見たとおり,𝑥に戻るにはさらに,読み残した切れ端が辞書の何番目かを書き足す必要がある.そのぶんは番号だけで足りるので,フレーズ1本に割り当てるビット数より少ないが,定義 12.5.9 はこの1本を数えていない.本節のはじめに断ったとおり,本書はこれらを主張として述べず,証明もしない.以下の評価は,定義 12.5.9 の右辺について述べたものである.
定理 12.5.10. Xを空でない有限アルファベット,𝑛 ≥0,𝑥 ∈X𝑛とすると
ℓLZ𝑛(𝑥)≤𝑛(⌊log2(𝑛+1)⌋+⌊log2|X|⌋+2)である(ℓLZ𝑛は 定義 12.5.9 の符号長).
証明. 𝑘 :=|S(𝑥)|と置くと 系 12.5.5 より𝑘 ≤𝑛である.log2は狭義単調増加で,床関数は𝑠 ≤𝑡ならば⌊𝑠⌋ ≤⌊𝑡⌋を満たすから⌊log2(𝑘 +1)⌋ ≤⌊log2(𝑛 +1)⌋であり,括弧の中は𝑘を𝑛に取り替えても減らない.括弧の中は正だから,𝑘 ≤𝑛と合わせて,二つの因子をそれぞれ大きくして主張を得る.◼
系 12.5.11. Xを空でない有限アルファベット,𝑛 ≥1,𝑥 ∈X𝑛とすると
ℓLZ𝑛(𝑥)𝑛≤⌊log2(𝑛+1)⌋+⌊log2|X|⌋+2である(ℓLZ𝑛は 定義 12.5.9 の符号長).
系 12.5.11 の右辺は𝑛とともに増えるので,これだけでは1文字あたりの符号長が定数で抑えられたことにならない.𝑘 ≤𝑛で済ませたのが,定数で抑えるという目的には粗すぎたのである(もっとも,短い系列では 系 12.5.11 の右辺のほうが小さい.|X| =2なら,次の 系 12.5.12 の右辺を下回るのは𝑛 ≤62の範囲で,例 12.5.13 の𝑛 =13では6対8.754…である).定理 12.5.10 と 系 12.5.11 をここに置いたのは,フレーズ数の抑えを使わずに 系 12.5.5 だけでどこまで言えるかを先に出しておくためで,次はその一段だけを取り替える.定理 12.5.7 のフレーズ数の抑えを 定義 12.5.9 に入れ直せば,増える項が消える.
系 12.5.12. Xを空でない有限アルファベット,𝑛 ≥1,𝑥 ∈X𝑛とすると
ℓLZ𝑛(𝑥)𝑛≤3log2(|X|+1)+⌊log2|X|⌋+3である(ℓLZ𝑛は 定義 12.5.9 の符号長).右辺はXだけで決まり,𝑛にも𝑥にも依らない.
証明. 𝑘 :=|S(𝑥)|と置くと,𝑛 ≥1だから 系 12.5.5 より𝑘 ≥1であり,𝑘 +1 ≤2𝑘からlog2(𝑘 +1) ≤log2𝑘 +1である.床関数の性質⌊𝑡⌋ ≤𝑡と合わせると
ℓLZ𝑛(𝑥)≤𝑘log2𝑘+𝑘(⌊log2|X|⌋+3)である.定理 12.5.7 より第1項は3log2(|X| +1) 𝑛以下,系 12.5.5 より第2項の𝑘は𝑛以下だから,両辺を𝑛 >0で割れば主張を得る.◼
例 12.5.13(13文字の二値系列の符号長). 例 12.5.2 の𝑥 =1011010100010(X ={0,1},𝑛 =13)に対しℓLZ13(𝑥) =42ビットである(ℓLZ𝑛は 定義 12.5.9 の符号長).
証明. 例 12.5.2 より𝑘 =|S(𝑥)| =7である.⌊log28⌋ =3であり,|X| =2だから⌊log22⌋ =1である.よってフレーズ1本あたりのビット数は3 +1 +2 =6で,ℓLZ13(𝑥) =7 ×6 =42である.◼
13文字を1文字1ビットで書き写せば13ビットで済むから,この系列では Lempel–Ziv 符号のほうが3倍以上長い.フレーズ1本に6ビットを払って,覆えているのは平均13/7文字だからである.短い系列で膨らむのはこのためで,縮むとすれば,辞書が育ってフレーズ1本の覆う文字数が増えてからである.その育ち方を,同じ文字が続くだけの系列で見ておく.
例 12.5.14(0だけを並べた二値系列). X ={0,1},𝑛 ≥1とし,𝑥を0を𝑛個並べた列とする.𝑘(𝑘 +1)/2 ≤𝑛を満たす最大の整数を𝑘とすると,S(𝑥)(定義 12.5.1)は0を1個,2個,…,𝑘個並べた列をこの順に並べたもので,|S(𝑥)| =𝑘であり
ℓLZ𝑛(𝑥)=𝑘(⌊log2(𝑘+1)⌋+3)である(ℓLZ𝑛は 定義 12.5.9 の符号長).とくに𝑛 =21では𝑘 =6で30ビット,𝑛 =54では𝑘 =9で54ビット,𝑛 =61では𝑘 =10で60ビットである.
証明. 分解から見る.定義 12.5.1 の手続きを追うと,辞書が0を1個から𝑗個まで並べた列からなる状態では,区切り候補は0を𝑗個読むまで伸び,𝑗 +1個目の0で辞書から外れて出力される.よって出力は0を1個,2個,…と並べた列がこの順に現れ,𝑗個の列まで出し終えた時点で読んだ文字数は1 +2 +⋯ +𝑗 =𝑗(𝑗 +1)/2である.𝑘のとり方より𝑘(𝑘 +1)/2 ≤𝑛だから0を𝑘個並べた列までは出力される.残る𝑛 −𝑘(𝑘 +1)/2文字が𝑘 +1個以上あれば(𝑘 +1)(𝑘 +2)/2 ≤𝑛となって𝑘の最大性に反するから,残りは𝑘個以下で,候補に残って出力されない.よってフレーズは𝑘本である.
ビット数を勘定する.|X| =2だから⌊log2|X|⌋ =1であり,定義 12.5.9 の括弧の中は⌊log2(𝑘 +1)⌋ +3である.𝑛 =21では6 ×7/2 =21 ≤21かつ7 ×8/2 =28 >21だから𝑘 =6で,⌊log27⌋ =2よりフレーズ1本あたり5ビット,合わせて30ビットである.𝑛 =54では9 ×10/2 =45 ≤54かつ10 ×11/2 =55 >54だから𝑘 =9で,⌊log210⌋ =3よりフレーズ1本あたり6ビット,合わせて54ビットである.𝑛 =61では55 ≤61かつ11 ×12/2 =66 >61だから𝑘 =10で,同じく⌊log211⌋ =3よりフレーズ1本あたり6ビット,合わせて60ビットである.◼
辞書が育つ様子がそのまま数に出ている.𝑛 =21では6本のフレーズが21文字を覆い,1本あたり平均3.5文字で,例 12.5.13 の13/7文字より長い.それでも30ビットかかって,書き写す21ビットには負けている.𝑛 =54でようやく書き写すのと並び,𝑛 =61では60ビットで書き写すより短くなる.これだけかかるのは,フレーズ1本あたりのビット数が本数の対数で増えるいっぽう,この系列で𝑘本のフレーズが覆える文字数は𝑘(𝑘 +1)/2と,本数の2乗の水準でしか伸びないからである.縮むところまで持っていくには,同じ文字が続くだけの系列でもこれだけの長さが要る.
系 12.5.12 が抑えたのはそこまでである.1文字あたりの符号長が定数を超えないことは分かったが,行き着く値が情報源のエントロピーレートかどうかは,ここまでの数え上げでは決まらない.数え上げが見ているのはフレーズが相異なることだけで,どのフレーズがどれだけ起こりやすいかを見ていないからである.次節は,そこに情報源の確率を入れる.
InformationTheory — 形式化検証つき情報理論教科書(レビュー版).数式は MathJax + AMS Euler で事前レンダリング.