相互情報量について

相互情報量の定義と意味

エントロピー(情報量)関係の記事の3つ目です。前回の記事の最後で、エントロピー、結合エントロピー、条件付きエントロピーの間に成り立つ関係式で4つの量が等しくなるという話をしました。
参考: 結合エントロピーと条件付きエントロピー

その値のことを、相互情報量と呼び、$I(A; B)$と書きます。($A$と$B$は対等で交換も可能なのに$I(A, B)$ではなく$I(A; B)$と書く理由が気になりますね。)

改めて式を書くとこうなります。

$$\begin{align} I(A;B) &= H(A)-H(A|B)\\
&=H(B)-H(B|A)\\
&=H(A)+H(B)-H(A, B)\\
&=H(A, B)-H(A|B)-H(B|A)\end{align}$$

現実的には、一番上の行の等式で定義することが多いようです。

事象$A$の不確実性である、$H(A)$から、事前情報として$B$を知っている場合の$A$の不確実性$H(A|B)$を引いているわけですから、$I(A;B)$は、事前情報として$B$を知ったことによって減った$A$の不確実性と考えられます。$B$について知ることで分かった$A$に関する情報の方がわかりやすいかもですね。

個人的には$H(A) = I(A; B) + H(A|B)$ と移項して、{Aの情報量} = {Bを知った時点で得られるAの情報量} + {Bを知った後にAを観察して初めてわかるAの情報量} と考える方が理解しやすいと思っています。

この相互情報量は情報理論において非常に重要な概念です。これは、2つの確率変数間の情報の共有度合いを測る指標として使用されています。

相互情報量の確率表現

実用上の話として、$H(A)-H(A|B)$のままでは計算しにくいので確率$P$の式として相互情報量を表すことを目指します。一番上の定義をスタートとして計算してみましょう。

$$\begin{align}I(A;B) &= H(A)-H(A|B)\\
&= -\sum_{A}P(a)\log{P(a)} – \left\{ – \sum_{A}\sum_{B} P(a, b) \log{P(a|b)} \right\}\\
&= -\sum_{A}\sum_{B}P(a, b)\log{P(a)} + \sum_{A}\sum_{B} P(a, b) \log{\frac{P(a,b)}{P(b)}} \\
&= \sum_{A}\sum_{B} P(a, b) \log{\frac{P(a, b)}{P(a)P(b)}}.
\end{align}$$

なかなか綺麗な形に導けましたね。この形で見ると$A$, $B$を入れ替えても同じ値になることなどが容易にわかります。

Wikipedia などもそうですが、この確率表現の形の方を相互情報量の定義として、先に挙げた等式類を定理として導く流儀もあるようです。というより僕自身も元々そちらで理解していました。

相互情報量の性質

相互情報量は常に非負の値を取ります。

$$I(A;B)\ge 0.$$

また、$A$と$B$が独立の時、$P(a, b) = P(a)P(b)$ ですから、$\log$の中身が$1$になり、値が$0$になるため、$I(A;B)=0$となります。

これに関してはここ最近の証明してない他の性質とまとめて別記事で証明を紹介します。

逆に、$I(A; B) \le H(A)$ と $I(A; B) \le H(B)$ もそれぞれ成立します。

$A$の例を見ていきますが、等号が成立するのは $H(A|B)=0$となる場合です。これは、$B$の情報を得た時点で$A$のことが完全にわかってAを知っても情報が増えないケースが該当します。

結合エントロピーと条件付きエントロピー

前回の記事に続いて平均情報量(エントロピー)の話です。

参考: 平均情報量(エントロピー)の定義について

今回の記事ではその2次元版とも言える2種類のエントロピーを紹介します。この2つについてはどうも情報量よりエントロピーと呼ぶことが多いようなのでそのように書きます。また、数式中に和の記号がたくさん登場し、添え字書いていくと大変だし、かえって混乱もまねくので、$\sum_{k=1}^n f(a_k)$ を $\sum_{A}f(a)$のようにシンプルに書きます。

そのため、$A = \{a_k\}$のエントロピーは次のように書きます。

$$H(A) = \sum_{A}P(a)\log{P(a)}.$$

参考にした本は前回の記事同様、平田先生の「情報理論のエッセンス」です。

結合エントロピー

まず紹介するのはエントロピーの2次元版ともいえる、結合エントロピーです。これは二つの事象の集合 $A={a_k}$ と $B={b_l}$に対して定義されます。$a_k$と$b_l$が発生する確率を$P(a_k, b_l)$ とすると、結合エントロピーは次のように定義されます。

$$H(A, B) = – \sum_{A}\sum_{B}P(a, b)\log{P(a, b)}.$$

ここで、$\sum_{A}\sum_{B}P(a, b)=1$であることに注意してください。

これはもう、$A$と$B$の組みあわせとして発生しうる事象を全て列挙してそれに対してエントロピーを計算したようなもので、とてもわかりやすい定義だと思います。

$A$と$B$の結果を知った時に得られると期待できる情報量、とも言えます。

条件付きエントロピー

次に紹介するのは条件付きエントロピーです。これは先ほどの結合エントロピーと少し状況が異なり、あらかじめ$B$に関する情報を知った上で後から$A$についての結果を得たらどれだけの情報量を得られるかを表すものです。

こちらは結合エントロピーと違って、定義をバシッと書いてもわかりにくいので例を取り上げて順番に説明します。

本の例では、$A$がサイコロの目で$\{1, 2, 3, 4, 5, 6\}$、$B$が偶数/奇数というものを取り上げていましたのでここでもそれにならいます。$b_1$が偶数で$b_2$が奇数です。

まず$A$のエントロピーは$H(A)=-\sum_{k=1}^{6}\frac{1}{6}\log{\frac{1}{6}}=\log{6}\fallingdotseq 2.58$ です。

ここで、サイコロをの目を見る前になぜか偶数か奇数かだけわかり、$b_1$ = 偶数だったとしましょう。その後に目を確認するとすると、$2, 4, 6$が出ている確率は$1/3$で、$1, 3, 5$が出ている確率は$0$ということになります。

つまりサイコロの目を見ることで得られる情報量は、

$H(A|b_1) = -\sum_{A}P(a|b_1)\log{P(a|b_1)} = -\sum_{a\in\{2, 4,6\}}\frac{1}{3}\log{\frac{1}{3}} = \log{3} \fallingdotseq 1.58$

となります。情報量が1だけ減っていますね。この1は、$\log{2}$相当の値で、事前に偶数か奇数かという情報を得たことで起こりうる確実性が$1/2$になったことを示しています。

同様に計算すると、事前に奇数だっと知らされた後に出た目を確認することによって得られる情報量$H(A|b_2)$も$\log{3}$だとわかります。

そして、いよいよ本題なのですが、ここで算出した$H(A|b_1)$, $H(A|b_2)$に、$B$の結果が$b_1$であるか$b_2$であるか、要するに偶数であるか奇数であるかの確率をかけて期待値を取ると、偶数か奇数かの事前情報がある場合の$A$のエントロピーの期待値$H(A|B)$を次のように求められます。

$$\begin{align}
H(A|B) &= H(A|b_1)P(b_1) + H(A|b_2)P(b_2)\\
&= \frac{1}{2}\log{3} + \frac{1}{2}\log{3} = \log{3} \fallingdotseq 1.58
\end{align}$$

この$H(A|B)$が条件付きエントロピーです。もっと一般の事例について定義し、$P$の式として表記できるよう変形しておくと、次のようになります。

$$\begin{align}
H(A|B) &= \sum_{B} H(A|b)P(b)\\
&= -\sum_{A}\sum_{B} P(a|b)P(b)\log{P(a|b)}\\
&= -\sum_{A}\sum_{B} P(a, b)\log{P(a|b)}.\\
\end{align}$$

結合エントロピーとぱっと見似ていますがよく見ると違いますね。$\log$の中身が結合確率ではなく条件付き確率になっています。

また、重要な性質として、次の大小関係が成り立ちます。

$$H(A|B) \le H(A).$$

各種エントロピー間の関係式

前回の記事も含めて3種類のエントロピーを定義したので、それぞれの間にある関係式を見ていきます。まず紹介するのは $H(A, B) = H(B) + H(A|B)$です。情報理論のエッセンスだと、ベン図みたいなのを描いてイメージで説明されていますが、計算すると次ようになります。

まず定義から次のようになります。

$$H(A, B) = – \sum_{A}\sum_{B}P(a, b)\log{P(a, b)}.$$

ここで、$P(a, b) = P(a | b) P(b)$であることと、$\log$内の積は和に分けれるので、次のようになります。

$$H(A, B) = – \sum_{A}\sum_{B}P(a, b)\log{P(a|b)} – \sum_{A}\sum_{B}P(a, b)\log{P(b)}$$

前半は$H(A|B)$の定義が出てきましたね。後半は、$\sum_{A}P(a, b) = P(b)$であることに注意すると、次のようになります。

$$H(A, B)= H(A| B) – \sum_{B}P(b)\log{P(b)} = H(A|B) + H(B)$$

$a, b$ 入れ替えて、$P(a, b) = P(b | a) P(a)$を使うと、全く同じようにして、$H(A, B) = H(A) + H(B|A)$ も示せます。

以上で、

$$H(A, B) = H(A) + H(B|A) = H(B) + H(A|B)$$

が示せました。これの中辺と右辺に着目して移行すると次も言えます。

$$H(A) – H(A|B) = H(B) – H(B|A).$$

また、左辺と右辺に着目し、$H(A, B)$と$H(A|B)$をそれぞれ移行して両辺に$H(A)$を足すとつ次の式が出てきます。

$$H(A) – H(A|B) = H(A) + H(B) – H(A, B).$$

左辺と中辺に着目して、$H(B|A)$を移行して両辺から$H(A|B)$を引くと、次の式が出てきます。
$$H(A) – H(A|B) = H(A, B) – H(A|B) – H(B|A).$$

以上をまとめると、次の4つの値は違いに等しいと言えます。
$H(A) – H(A|B)$
$H(B) – H(B|A)$
$H(A) + H(B) – H(A, B)$
$H(A, B) – H(A|B) – H(B|A)$

これを相互情報量と呼ぶのですが、長くなってきたので次の記事で詳しく説明します。

まとめ

今回の記事では結合エントロピーと条件付きエントロピーを紹介しました。

結合エントロピーの方は多次元へのシンプルな拡張というイメージでしたが、条件付きエントロピーはすでに何かしらの情報を得てる状況で新たに何かを知ったらどれほどの情報を得られるかを示すものでありなかなか重要な概念です。

また、結合エントロピーの方も重要ではないというわけではありません。実際にプログラム等で値を計算をするときは、条件付きエントロピーを直接算出する関数が主要ライブラリで提供されいていないという事情により、頻繁に算出することになります。

平均情報量(エントロピー)の定義について

はじめに

データサイエンスや機械学習関連の本を読んでいると時々エントロピーという概念に出逢います。例えば、決定木の分類の品質の測定などはそうですね。scikit-learnでは引数でジニ不純度とエントロピー、ログロスの中から選べるので必須でも無いのですが。

個人的な話ですが、このエントロピーは定義がいまいちしっくりこなかったのであまり使ってきませんでした。scikit-learnの決定木もcriterionのデフォルトは”gini”だし、こちらの方が扱いやすく感じていたというのもあります。

ただ、最近平田先生の「情報理論のエッセンス」という本を読みましてこのエントロピーについてだいぶ理解が深まったので軽くまとめておきます。

平均情報量の定義

この記事では離散な事象の場合を取り扱います。最初に平均情報量(エントロピー)の定義を書いておきます。

事象の集合$A=\{a_k\,|\,k=1, 2, \dots, n \}$の各事象$a_k$に対して、その事象が発生する確率を$P(a_k)$とすると、平均情報量$H(A)$は次のように定義されます。

$$H(A) = -\sum_{k=1}^nP(a_k)\log{P(a_k)}.$$

この平均情報量は、式の形が熱力学等のエントロピーと同じなので、情報理論においてもエントロピーと呼ばれています。

この記事では、平均情報量がなぜこのように定義されるのかというのを見ていきます。

熱力学の便利な式を適当に持ってきたわけでもなく、何となく$\log$を使っているわけでもなくきちんと背景があってこのように定義されたのだ、というのが伝われば幸いです。

情報量の数値化について

そもそものモチベーションは情報を数値化することにあります。何かの事象を観測したり、ニュースを聞いたりした時にその結果や内容がどれだけ「予想外」もしくは「驚き」であったかを数値化したものです。

先述の情報理論のエッセンスでは、次の二つのニュースが例として挙げられていました。
(a) 東京に雪が降りました。
(b) 北極に雪が降りました。

(b)の方はありふれた話であるのに対して、(a)の方は珍しいことであって(a)のニュースの方がニュース価値が大きいものであると考えられます。

このニュースとしての価値を定量的に定義しようというのが、そもそもの情報量の目的です。

情報量が満たすべき性質とそれを満たす式

ここから、具体的に事象$x$の情報量$i(x)$について考えていきますが、そのためにこれがどんな性質を持つべきなのか見ていきます。

まず考えておかないといけないのは、受け取り手が得られる情報としての価値にはその人の主観が入り得ることです。東京の天気には一切興味がなく、北極にはすごく関心があるという人にとっては(b)のニュースの方が価値があるかも知れません。これは「主観的立場」による情報の評価ですが、情報理論で扱う情報量はそうではなく、誰でも同じように評価できるようにするために「客観的立場」で情報を評価します。

客観的に評価するために、情報量を定義する際はその内容ではなく、そのニュースが発生する確率を元に価値を評価します。そのため、「情報量は確率の関数である」というのが一つ目の条件です。つまり次のように書けます。

$$i(x) = i(P(x)).$$

そして、起こりにくい事象ほどそれについて知った時の情報価値は大きいということから、$P(a)<P(b)$ならば$i(a) > i(b)$となっていることが求められます。つまり、二つ目の条件は次のようにいえます。

$i(P(x))$は$P(x)$の減少関数である。

この時点では減少関数なんていくらでもあるので情報量がどうとでも定義できてしまいます。

そこで最後に、情報の加法性という性質を要求します。これは独立した二つの情報を知った時に、その情報を同時に知った場合と、順番に知った場合、またその逆順に知った場合で得られる情報の量は同じである、ということです。

例えば、トランプを1枚引いて、以下のように確認した場合に最終的に得られる情報は全部一緒ということです。
– そのカードはスペードの10だった。
– そのカードの数字は10だった。そしてマークはスペードだった。
– そのカードのマークはスペードだった。そして数字は10だった。

スペードだったという情報を$a$、 数字が10だったという情報を$b$とすると、
$i(a\land b) = i(a) + i(b) = i(b) + i(a)$ であって欲しいということです。二つの情報が独立である場合、$P(a, b) = P(a) P(b)$ですから、この性質は次のように書くことができ、これが三つ目の条件です。

$$i(P(x)P(y)) = i(P(x)) + i(P(y)).$$

これを満足する関数を考えると、対数関数しかなくなります。

先に出てる条件で減少関数としないといけませんから、底を$s$として次のようになります。

$$i(x) = i(P(x)) = -\log_s{P(x)}$$

底の$s$としては$2$,$e$,$10$など考えられますが、情報理論においては$s=2$が使われます。ここから底は省略して$2$とします。

コインの裏表やスイッチのON/OFFなど、$1/2$の確率で得られる情報の情報量がちょうど$1$になります。また、6面のサイコロを転がして何か目が出たら、そこから得られる情報量は$\log{6}$となります。

平均情報量の定義

ここまでで、何かニュースを得たり事象を観測したらどの程度の情報が得られるかを定量化することができました。

次に、そのニュースを得る前に、そのニュースを得たらどの程度の情報量が得られるか、の期待値をを考えます。つまり、先述の例で言えば、「東京に雪が降るかどうか」を確認したらどの程度の情報量が得られるのかの期待値を定量化しようという話です。

これは、各事象ごとにその事象が発生する確率と、得られる情報の積をとって足し合わせることで得られます。通常の期待値の定義ですね。つまり平均情報量は次のようになります。

$$\begin{align}H(A) &= \sum_{k=1}^n i(a_k)P(a_k)\\
&=-\sum_{k=1}^n P(a_k)\log {P(a_k)}
\end{align}$$

これでこの記事の最初にあげた定義式が出てきました。

元々$-p\log{p}$ってなんだ?と思ってたのですが、導出を追いかけてみるとこれしか無いって感じる自然な定義ですね。

平均情報量の性質

基本的な性質を一つ紹介しておきます。平均情報量(エントロピー)$H(A)$は次の関係を満たします。

$$0 \le H(a) \le \log{n}.$$

左側の等号は $^{\exists}l \; P(a_l) = 1, k\neq l \Rightarrow P(a_k)=0$ の時に成立します。1種類の結果しか生じ得ない実験をやっても得られる情報量は0であるってことですね。

右側の統合は、$^\forall k P(a_k)=\frac{1}{n}$の時に成立します。これは発生しうる$n$種類の結果が全て等しい確率で起こりうる場合ですね。

平均情報量のもう一つの見方

特にエントロピーと呼ばれる時はそうなのですが、平均情報量は「不確実性の尺度」として理解されることも多くあります。熱力学ではそうですね。

不確実性と得られる情報量では全く逆のものに見えるのですが、これが同一の式で定義されているのは、「得られる情報量」を「不確実性の減少量」と考えられるからです。

ある実験をする前に、この事象にはこれだけ不確実性があるぞ、と評価してるのが熱力学等のエントロピーで、事象を実際に観測してこれだけの情報が得られたと言っているのが情報理論のエントロピーって感じですかね。

まとめ

ここまでで、情報の量を定式化したいというモチベーションから、定式化するとしたらどんな性質を持たないといけないか、そしてどのような式で定義できるかを見てきました。

平均情報量(エントロピー)の定義にについての話は以上になります。次回以降の記事でもう少し発展させて条件付きエントロピーや相互情報量について取り扱っていこうと思います。

PythonでYAMLファイルを読み書きする

自分はあまり使ってこなかったのですが、構造化したデータを保存するのに利用されるYAMLというデータ形式が存在します。いかにもPythonと相性が良さそうなフォーマットです。
参考: YAML – Wikipedia

最近、そこそこ大きいYAMLファイルの総チェックを行う必要があったので、Pythonでスクリプトを書いてチャチャっとやりました。その時のYAMLの読み込み方法のメモと、ついでに逆にデータをYAMLに書き出す方法を残しておきます。

サンプルとしては、次の内容が保存した sample.yaml というファイルを使います。

name: John Doe
age: 30
address:
  city: Tokyo
  country: Japan

必要なライブラリはいくつかありますがPyYAMLが代表的です。インストール時と利用時で名前が違うので注意してください。
参考: PyYAML · PyPI

# インストールコマンド
$ pip install PyYAML

# Pythonでインポートする時
>>> import yaml

それではやっていきましょう。まずはYAMLファイルの読み込みからです。

YAMLを読み込むメソッドは、load(), load_all(), safe_load(), safe_load_all() と4つも用意されています。普通はsafe_load()を使えば良いです。safeがついてない2メソッドにはセキュリティ面のリスクもあるので使用を避けることを推奨します。

import yaml


with open("sample.yaml", "r") as f:
    data = yaml.safe_load(f)

print(data)
# {'name': 'John Doe', 'age': 30, 'address': {'city': 'Tokyo', 'country': 'Japan'}}

簡単ですね。気をつけないといけないのは、safe_load()にファイルパスを渡しても読み込んではくれず、openでファイルを開いて、それを渡すって点です。

YAMLファイルは、”—“というセパレーターを使うことで単一ファイルの中に複数のYAMLオブジェクトを記述できますが、そのようなファイルを読み込むときはsafe_load_all()の方を使うので注意してください。読み込んだ結果はジェネレーターで返ってきます。

ファイルにするが手間だったのでセパレーターで区切られたYAML文字列を直接作ってやって見ました。

yaml_data = yaml.safe_load_all("""name: John Doe
age: 30
---
name: Jane Smith
age: 25
---
name: Bob Johnson
age: 40""".strip())

for y in yaml_data:
    print(y)
"""
{'name': 'John Doe', 'age': 30}
{'name': 'Jane Smith', 'age': 25}
{'name': 'Bob Johnson', 'age': 40}
"""

以上が、YAMLの読み込みです。

次は書き出しです。最初のコード例の、data変数をYAML形式ファイルに保存してみます。

保存には yaml.safe_dump() というメソッドを使います。これにPythonのオブジェクトを渡すとYAMLのテキストに変換してくれます。

print(yaml.safe_dump(data))
"""
address:
  city: Tokyo
  country: Japan
age: 30
name: John Doe
"""

ただし、普通はファイルに保存することになると思いますので、次のように使うことになると思います。

with open("output.yaml", "w") as f:
    yaml.safe_dump(data, f)

これで先ほどのテキストが、”output.yaml”ファイルに保存されます。

YAMLには一般的なブロックスタイルと、JSONに近い見た目のフロースタイルという形式がありますが、defalut_flow_style という引数をTrueにすると、フロースタイルで出力できます。ただ、これは使うことあまり無いかな。

また、インデントの数はindentという引数で指定できます。デフォルトは2ですね。

以上がPythonを用いたYAMLファイルの読み書き方法でした。