情報理論において「情報量」とは、ある事象がどれだけ「驚き」を含んでいるかを定量化する概念です。直感的には、珍しい事象ほど多くの情報を持ち、確実に起きる事象は情報を持ちません。クロード・シャノンが1948年に提唱したこの概念は、通信、データ圧縮、機械学習など幅広い分野の基盤となっています。
本記事の内容
- 自己情報量の直感と定義
- 対数の底と単位(bit / nat)
- 自己情報量の性質
- エントロピーとの関係
- Pythonでの計算と可視化
前提知識
この記事を読む前に、以下の知識があると理解が深まります。
- 確率の基礎(確率分布、確率質量関数)
- 対数関数の性質
自己情報量の直感
ニュースを聞いたとき、「ありえない!」と驚くような事象と、「まあそうだろう」と思う事象があります。情報理論では、この「驚き」の度合いを数値化します。
次のような性質を満たす関数 $I(x)$ を考えます。
- 確率が低い事象ほど情報量が大きい: $P(x)$ が小さいとき $I(x)$ は大きい
- 確実な事象の情報量は0: $P(x) = 1$ のとき $I(x) = 0$
- 独立事象の情報量は加法的: $I(x, y) = I(x) + I(y)$($x, y$ が独立のとき)
自己情報量の数学的定義
上記の3条件を満たす関数は、対数関数に限られます。
事象 $x$ の自己情報量(self-information)は次のように定義されます。
$$ \boxed{I(x) = -\log P(x)} $$
ここで $P(x)$ は事象 $x$ が起きる確率です。
3条件の確認
- $P(x)$ が小さい $\Rightarrow$ $-\log P(x)$ が大きい($\log$ は単調増加なので)
- $P(x) = 1$ のとき $I(x) = -\log 1 = 0$
- $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$
次のステップとして、以下の記事も参考にしてください。