情報量(自己情報量)の定義と直感

情報理論において「情報量」とは、ある事象がどれだけ「驚き」を含んでいるかを定量化する概念です。直感的には、珍しい事象ほど多くの情報を持ち、確実に起きる事象は情報を持ちません。クロード・シャノンが1948年に提唱したこの概念は、通信、データ圧縮、機械学習など幅広い分野の基盤となっています。

本記事の内容

  • 自己情報量の直感と定義
  • 対数の底と単位(bit / nat)
  • 自己情報量の性質
  • エントロピーとの関係
  • Pythonでの計算と可視化

前提知識

この記事を読む前に、以下の知識があると理解が深まります。

  • 確率の基礎(確率分布、確率質量関数)
  • 対数関数の性質

自己情報量の直感

ニュースを聞いたとき、「ありえない!」と驚くような事象と、「まあそうだろう」と思う事象があります。情報理論では、この「驚き」の度合いを数値化します。

次のような性質を満たす関数 $I(x)$ を考えます。

  1. 確率が低い事象ほど情報量が大きい: $P(x)$ が小さいとき $I(x)$ は大きい
  2. 確実な事象の情報量は0: $P(x) = 1$ のとき $I(x) = 0$
  3. 独立事象の情報量は加法的: $I(x, y) = I(x) + I(y)$($x, y$ が独立のとき)

自己情報量の数学的定義

上記の3条件を満たす関数は、対数関数に限られます。

事象 $x$ の自己情報量(self-information)は次のように定義されます。

$$ \boxed{I(x) = -\log P(x)} $$

ここで $P(x)$ は事象 $x$ が起きる確率です。

3条件の確認

  1. $P(x)$ が小さい $\Rightarrow$ $-\log P(x)$ が大きい($\log$ は単調増加なので)
  2. $P(x) = 1$ のとき $I(x) = -\log 1 = 0$
  3. $x, y$ が独立のとき $P(x, y) = P(x)P(y)$ なので:

$$ \begin{align} I(x, y) &= -\log P(x, y) \\ &= -\log(P(x)P(y)) \\ &= -\log P(x) – \log P(y) \\ &= I(x) + I(y) \end{align} $$

対数の底と単位

対数の底の選び方によって、情報量の単位が変わります。

単位 用途
2 ビット(bit) 情報科学、通信
$e$ ナット(nat) 数学、物理学
10 ハートレー(hartley) 歴史的

$$ I_{\text{bit}}(x) = -\log_2 P(x), \quad I_{\text{nat}}(x) = -\ln P(x) $$

底の変換は:

$$ \log_2 P(x) = \frac{\ln P(x)}{\ln 2} $$

なので $I_{\text{bit}}(x) = I_{\text{nat}}(x) / \ln 2$ です。

具体例

公正なコインの表が出る事象:

$$ I(\text{表}) = -\log_2 \frac{1}{2} = 1 \text{ bit} $$

公正な6面サイコロで1が出る事象:

$$ I(1) = -\log_2 \frac{1}{6} = \log_2 6 \approx 2.585 \text{ bit} $$

サイコロのほうが珍しい事象なので、コインよりも多くの情報量を持ちます。

エントロピーとの関係

確率変数 $X$ のエントロピー(entropy)$H(X)$ は、自己情報量の期待値です。

$$ \boxed{H(X) = E[I(X)] = -\sum_{x} P(x) \log P(x)} $$

エントロピーは「平均的な驚きの大きさ」、つまり確率分布がどれだけ不確実かを表す量です。

エントロピーの性質

  • 非負性: $H(X) \geq 0$
  • 最大値: 離散確率変数 $X$ が $n$ 個の値をとるとき、一様分布で最大 $H(X) = \log n$
  • 一様分布で最大: 全ての結果が等確率のとき、不確実性が最も大きい

具体例: 偏りのあるコイン

表の確率を $p$、裏の確率を $1-p$ とするコインのエントロピー:

$$ H(X) = -p\log_2 p – (1-p)\log_2(1-p) $$

$p = 0.5$(公正なコイン)で最大値 $H = 1$ bit をとり、$p = 0$ または $p = 1$ で $H = 0$ bit となります。

Pythonでの実装

自己情報量の計算と可視化

import numpy as np
import matplotlib.pyplot as plt

# --- 自己情報量のグラフ ---
p = np.linspace(0.001, 1.0, 1000)
I_bit = -np.log2(p)
I_nat = -np.log(p)

fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# 自己情報量(bit)
axes[0].plot(p, I_bit, 'b-', linewidth=2, label='bit ($-\\log_2 p$)')
axes[0].plot(p, I_nat, 'r--', linewidth=2, label='nat ($-\\ln p$)')
axes[0].set_xlabel('Probability P(x)', fontsize=12)
axes[0].set_ylabel('Self-information I(x)', fontsize=12)
axes[0].set_title('Self-information vs Probability', fontsize=13)
axes[0].legend(fontsize=11)
axes[0].grid(True, alpha=0.3)
axes[0].set_xlim(0, 1)
axes[0].set_ylim(0, 10)

# 具体例をプロット
examples = {
    'Coin (1/2)': 1/2,
    'Die (1/6)': 1/6,
    'Card (1/52)': 1/52,
    'Rare (1/1000)': 1/1000,
}

for name, prob in examples.items():
    info = -np.log2(prob)
    axes[0].plot(prob, info, 'ko', markersize=6)
    axes[0].annotate(f'{name}\n{info:.2f} bit',
                     xy=(prob, info), xytext=(prob + 0.05, info + 0.3),
                     fontsize=9, arrowprops=dict(arrowstyle='->', lw=0.5))

# 二値エントロピー関数
p_coin = np.linspace(0.001, 0.999, 1000)
H_binary = -p_coin * np.log2(p_coin) - (1 - p_coin) * np.log2(1 - p_coin)

axes[1].plot(p_coin, H_binary, 'b-', linewidth=2)
axes[1].set_xlabel('Probability p', fontsize=12)
axes[1].set_ylabel('Entropy H(X) [bit]', fontsize=12)
axes[1].set_title('Binary Entropy Function', fontsize=13)
axes[1].axvline(x=0.5, color='red', linestyle='--', alpha=0.5, label='p=0.5 (max)')
axes[1].axhline(y=1.0, color='gray', linestyle='--', alpha=0.3)
axes[1].legend(fontsize=11)
axes[1].grid(True, alpha=0.3)
axes[1].set_xlim(0, 1)
axes[1].set_ylim(0, 1.1)

plt.tight_layout()
plt.show()

エントロピーの計算

import numpy as np
import matplotlib.pyplot as plt

# --- 離散分布のエントロピー計算 ---
def entropy(probs, base=2):
    """確率分布のエントロピーを計算"""
    probs = np.array(probs)
    probs = probs[probs > 0]  # 0の確率は除外(0 log 0 = 0 の規約)
    if base == 2:
        return -np.sum(probs * np.log2(probs))
    else:
        return -np.sum(probs * np.log(probs))

# 様々な分布のエントロピー
distributions = {
    'Certain': [1.0, 0.0, 0.0, 0.0],
    'Biased': [0.7, 0.1, 0.1, 0.1],
    'Moderate': [0.4, 0.3, 0.2, 0.1],
    'Uniform': [0.25, 0.25, 0.25, 0.25],
}

fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# 左: 各分布の棒グラフ
x_pos = np.arange(4)
width = 0.2
for i, (name, probs) in enumerate(distributions.items()):
    H = entropy(probs)
    axes[0].bar(x_pos + i * width, probs, width, label=f'{name} (H={H:.3f})')

axes[0].set_xlabel('Event', fontsize=12)
axes[0].set_ylabel('Probability', fontsize=12)
axes[0].set_title('Probability Distributions', fontsize=13)
axes[0].set_xticks(x_pos + 1.5 * width)
axes[0].set_xticklabels(['x1', 'x2', 'x3', 'x4'])
axes[0].legend(fontsize=10)
axes[0].grid(True, alpha=0.3, axis='y')

# 右: n値の一様分布のエントロピー
n_values = np.arange(2, 101)
H_uniform = np.log2(n_values)

axes[1].plot(n_values, H_uniform, 'b-', linewidth=2)
axes[1].set_xlabel('Number of outcomes n', fontsize=12)
axes[1].set_ylabel('Entropy H [bit]', fontsize=12)
axes[1].set_title('Max entropy (uniform distribution) vs n', fontsize=13)
axes[1].grid(True, alpha=0.3)

# 特定の値をマーク
for n, name in [(2, 'coin'), (6, 'die'), (52, 'cards')]:
    H = np.log2(n)
    axes[1].plot(n, H, 'ro', markersize=8)
    axes[1].annotate(f'{name} (n={n})\nH={H:.2f} bit',
                     xy=(n, H), xytext=(n + 3, H - 0.5), fontsize=10,
                     arrowprops=dict(arrowstyle='->', lw=0.5))

plt.tight_layout()
plt.show()

まとめ

本記事では、自己情報量の定義と直感について解説しました。

  • 自己情報量: $I(x) = -\log P(x)$。珍しい事象ほど情報量が大きい
  • 単位: 底2でビット(bit)、底 $e$ でナット(nat)
  • 加法性: 独立事象の情報量は和になる
  • エントロピー: 自己情報量の期待値 $H(X) = -\sum P(x)\log P(x)$
  • 最大エントロピー: 一様分布のとき $H = \log n$

次のステップとして、以下の記事も参考にしてください。