共分散と相関係数の定義・性質・Pythonでの計算

ある都市の気温とアイスクリームの売上には明らかな関係があります。気温が上がれば売上も上がる。しかし、気温が1度上がったとき売上はどれくらい上がるのでしょうか?そもそも、この「一緒に動く傾向」の強さをどうやって数値化すればよいのでしょうか?

2つの変数が「一緒に動く度合い」を定量化するのが共分散(covariance)と相関係数(correlation coefficient)です。共分散は2つの変数の共変動の「大きさ」を測り、相関係数はそれを「-1から1の範囲」に正規化して「強さ」を測ります。

共分散と相関係数を理解すると、以下のような場面で適切な分析ができるようになります。

  • ポートフォリオ理論: 資産間の相関を使ったリスク分散の設計
  • 回帰分析: 回帰係数と相関係数の関係の理解
  • 主成分分析(PCA): 分散共分散行列の固有値分解による次元削減
  • 信号処理: 信号間の類似度の評価
  • 品質管理: 複数の品質指標間の関係の把握

本記事の内容

  • 共分散の直感的な理解と数学的定義
  • 共分散の性質と公式
  • 相関係数の定義と幾何学的解釈
  • コーシー・シュワルツの不等式による範囲の証明
  • 相関係数の限界 — アンスコムの例
  • Pythonでの計算と可視化

前提知識

この記事を読む前に、以下の概念を理解しておくとスムーズです。

共分散とは — 「一緒に動く傾向」

日常的な直感

共分散の直感は、2つの変数が平均からどの方向にずれるかの傾向です。

気温とアイスクリーム売上の例で考えます。平均気温が25度、平均売上が100個だとしましょう。

  • 気温が平均より高い日(+方向のずれ)に売上も平均より多い(+方向のずれ)→ ずれの積は正
  • 気温が平均より低い日(-方向のずれ)に売上も平均より少ない(-方向のずれ)→ ずれの積は正
  • この「ずれの積」の平均が正の共分散

逆に、気温と暖房使用量なら

  • 気温が平均より高い日に暖房使用量は平均より少ない → ずれの積は負
  • この「ずれの積」の平均が負の共分散

共分散は、この「ずれの積の期待値」を数式にしたものです。

数学的定義

2つの確率変数 $X$ と $Y$ の共分散は次のように定義されます。

$$ \begin{equation} \text{Cov}(X, Y) = E[(X – \mu_X)(Y – \mu_Y)] \end{equation} $$

ここで $\mu_X = E[X]$、$\mu_Y = E[Y]$ です。

この式は「$X$ と $Y$ がそれぞれの平均からどれだけずれるか」の積の期待値です。

計算に便利な公式

共分散の定義を展開すると、計算に便利な公式が得られます。

$$ \text{Cov}(X, Y) = E[(X – \mu_X)(Y – \mu_Y)] $$

括弧を展開すると

$$ = E[XY – X\mu_Y – \mu_X Y + \mu_X \mu_Y] $$

期待値の線形性から各項を分けると

$$ = E[XY] – \mu_Y E[X] – \mu_X E[Y] + \mu_X \mu_Y $$

$E[X] = \mu_X$、$E[Y] = \mu_Y$ を代入すると

$$ = E[XY] – \mu_X \mu_Y – \mu_X \mu_Y + \mu_X \mu_Y = E[XY] – \mu_X \mu_Y $$

よって

$$ \begin{equation} \text{Cov}(X, Y) = E[XY] – E[X]E[Y] \end{equation} $$

この公式は「$XY$ の期待値」から「各期待値の積」を引いたものとして、計算がシンプルです。

共分散の性質

共分散は以下の基本性質を持ちます。

対称性: $\text{Cov}(X, Y) = \text{Cov}(Y, X)$

自分自身との共分散は分散: $\text{Cov}(X, X) = \text{Var}(X)$

定数を足しても変わらない: $\text{Cov}(X + a, Y + b) = \text{Cov}(X, Y)$

双線形性: $$ \text{Cov}(aX + bY, Z) = a\,\text{Cov}(X, Z) + b\,\text{Cov}(Y, Z) $$

和の分散の公式: $$ \text{Var}(X + Y) = \text{Var}(X) + \text{Var}(Y) + 2\,\text{Cov}(X, Y) $$

独立ならば無相関: $X \perp Y$ ならば $\text{Cov}(X, Y) = 0$

和の分散の公式は特に重要です。この式から、正の共分散を持つ変数の和は分散が大きくなり(リスクの増大)、負の共分散を持つ変数の和は分散が小さくなる(リスクの分散効果)ことがわかります。これがポートフォリオ理論の数学的基盤です。

双線形性の証明

双線形性を示しましょう。

$$ \text{Cov}(aX + bY, Z) = E[(aX + bY)Z] – E[aX + bY]E[Z] $$

期待値の線形性から

$$ = aE[XZ] + bE[YZ] – (aE[X] + bE[Y])E[Z] $$

$$ = a(E[XZ] – E[X]E[Z]) + b(E[YZ] – E[Y]E[Z]) $$

$$ = a\,\text{Cov}(X, Z) + b\,\text{Cov}(Y, Z) $$

この双線形性のおかげで、共分散の計算は線形代数の内積と同じように扱えます。実際、共分散は確率変数の空間上の内積と見なすことができ、相関係数はその正規化された内積(コサイン類似度)に対応します。

ただし、共分散には1つ大きな問題があります。$X$ と $Y$ のスケール(単位)に依存するため、異なるデータ間で共分散の値を比較することができません。この問題を解決するのが相関係数です。

相関係数 — 共分散の正規化

定義

ピアソンの相関係数(Pearson correlation coefficient)は、共分散を各変数の標準偏差で割って正規化したものです。

$$ \begin{equation} \rho(X, Y) = \frac{\text{Cov}(X, Y)}{\sqrt{\text{Var}(X)} \sqrt{\text{Var}(Y)}} = \frac{\text{Cov}(X, Y)}{\sigma_X \sigma_Y} \end{equation} $$

この正規化により、$X$ や $Y$ のスケール(単位)に依存しない、純粋な「線形関係の強さ」の指標が得られます。

相関係数の範囲: $-1 \leq \rho \leq 1$

相関係数が $-1$ から $1$ の範囲に収まることは、コーシー・シュワルツの不等式から証明できます。

コーシー・シュワルツの不等式は、任意の確率変数 $U, V$ に対して

$$ [E[UV]]^2 \leq E[U^2] \cdot E[V^2] $$

を主張します。$U = X – \mu_X$、$V = Y – \mu_Y$ として適用すると

$$ [\text{Cov}(X, Y)]^2 \leq \text{Var}(X) \cdot \text{Var}(Y) $$

両辺を $\text{Var}(X) \cdot \text{Var}(Y)$ で割ると

$$ \rho^2 \leq 1 \quad \Rightarrow \quad -1 \leq \rho \leq 1 $$

等号条件

コーシー・シュワルツの等号条件は $V = cU$(ある定数 $c$)のときです。つまり

  • $\rho = 1$: $Y = aX + b$($a > 0$)の完全な正の線形関係
  • $\rho = -1$: $Y = aX + b$($a < 0$)の完全な負の線形関係

相関係数の絶対値が1に近いほど、2変数間の線形関係が強いことを意味します。

相関係数の解釈

$\rho$ の範囲 解釈
$\rho = 1$ 完全な正の線形関係
$0.7 \leq \rho < 1$ 強い正の線形関係
$0.3 \leq \rho < 0.7$ 中程度の正の線形関係
$0 < \rho < 0.3$ 弱い正の線形関係
$\rho = 0$ 線形関係なし(無相関)
$-1 < \rho < 0$ 負の線形関係(強さは絶対値で判定)
$\rho = -1$ 完全な負の線形関係

ただし、この閾値は分野によって異なります。物理学では $\rho = 0.3$ でも有意な関係と見なされることがありますが、社会科学では $\rho = 0.7$ 以上でないと強い関係とは言われないことがあります。

幾何学的解釈

相関係数は、確率変数を「ベクトル」と見たときのコサイン類似度に対応します。

$\tilde{X} = X – \mu_X$、$\tilde{Y} = Y – \mu_Y$ を中心化した確率変数とすると

$$ \rho = \frac{E[\tilde{X}\tilde{Y}]}{\sqrt{E[\tilde{X}^2]} \sqrt{E[\tilde{Y}^2]}} = \frac{\langle \tilde{X}, \tilde{Y} \rangle}{\|\tilde{X}\| \|\tilde{Y}\|} = \cos\theta $$

ここで $\langle \cdot, \cdot \rangle$ は $L^2$ 内積、$\|\cdot\|$ は $L^2$ ノルムです。$\theta$ は2つのベクトル間の角度に対応します。$\rho = 1$ は $\theta = 0$(同じ方向)、$\rho = -1$ は $\theta = \pi$(反対方向)、$\rho = 0$ は $\theta = \pi/2$(直交)です。

相関係数の限界について、次のセクションで議論しましょう。

相関係数の限界

線形関係しか捉えない

相関係数の最も重要な限界は、線形関係しか測定できないことです。

$X$ と $Y$ に強い非線形関係があっても、その関係が線形でなければ相関係数は低い値になります。独立性の記事で見た $Y = X^2$ の例がまさにこれです。

アンスコムの例

フランシス・アンスコムが1973年に示したアンスコムの四重奏(Anscombe’s quartet)は、この限界を劇的に示す古典的な例です。4つの全く異なるデータセットが、ほぼ同じ平均、分散、相関係数、回帰直線を持ちます。

相関関係と因果関係

もう1つの重要な注意は、相関関係は因果関係を意味しないということです。2つの変数に高い相関があっても、一方が他方を引き起こしているとは限りません。共通の原因(交絡因子)が存在する可能性があります。

たとえば、アイスクリームの売上と水難事故の件数は高い正の相関を持ちますが、アイスクリームが水難事故を引き起こしているわけではありません。両者は「気温」という共通の原因によって相関しているのです。

これらの限界を踏まえて、Pythonで共分散と相関係数の性質を可視化しましょう。

Pythonでの実装と可視化

相関係数の値と散布図の関係

相関係数が異なるデータセットの散布図を並べて比較します。

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

np.random.seed(42)
n = 500

# 異なる相関を持つ2次元正規分布を生成
correlations = [-0.95, -0.7, -0.3, 0.0, 0.3, 0.7, 0.95]

fig, axes = plt.subplots(2, 4, figsize=(16, 8))
axes = axes.flatten()

for idx, rho in enumerate(correlations):
    ax = axes[idx]
    mean = [0, 0]
    cov_matrix = [[1, rho], [rho, 1]]
    data = np.random.multivariate_normal(mean, cov_matrix, n)

    ax.scatter(data[:, 0], data[:, 1], alpha=0.3, s=10, color='steelblue')
    ax.set_title(f'$\\rho$ = {rho}', fontsize=13, fontweight='bold')
    ax.set_xlim(-4, 4)
    ax.set_ylim(-4, 4)
    ax.set_aspect('equal')
    ax.grid(True, alpha=0.3)

    # 回帰直線
    slope = rho
    x_line = np.linspace(-3, 3, 100)
    ax.plot(x_line, slope * x_line, 'r-', linewidth=2, alpha=0.5)

# 最後のパネルは非線形関係(相関0だが強い関係)
ax = axes[7]
theta = np.random.uniform(0, 2*np.pi, n)
x_circle = np.cos(theta) + np.random.normal(0, 0.1, n)
y_circle = np.sin(theta) + np.random.normal(0, 0.1, n)
rho_circle = np.corrcoef(x_circle, y_circle)[0, 1]
ax.scatter(x_circle, y_circle, alpha=0.3, s=10, color='red')
ax.set_title(f'Nonlinear\n$\\rho$ = {rho_circle:.3f}', fontsize=13,
             fontweight='bold')
ax.set_xlim(-1.5, 1.5)
ax.set_ylim(-1.5, 1.5)
ax.set_aspect('equal')
ax.grid(True, alpha=0.3)

plt.suptitle('Correlation Coefficient and Scatter Plot Shape',
             fontsize=14, y=1.02)
plt.tight_layout()
plt.savefig('correlation_scatter.png', dpi=150, bbox_inches='tight')
plt.show()

この散布図の比較から、相関係数の直感的な意味が明確に読み取れます。

  1. $\rho = 0$: 散布図は円形で、$X$ と $Y$ に線形的な傾向は見られません。

  2. $|\rho|$ が増加するにつれて: 散布図が楕円形になり、$|\rho| = 0.95$ では細長い楕円(ほぼ直線)になります。$\rho > 0$ なら右上がり、$\rho < 0$ なら右下がりです。

  3. 最後のパネル(非線形関係): 円上に分布するデータは $\rho \approx 0$ ですが、明確な(非線形な)関係があります。相関係数がこの関係を捉えられないことが視覚的にわかります。

アンスコムの四重奏

4つの異なるデータセットが同じ統計量を持つことを確認します。

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

# アンスコムの四重奏データ
anscombe = {
    'I':   {'x': [10, 8, 13, 9, 11, 14, 6, 4, 12, 7, 5],
             'y': [8.04, 6.95, 7.58, 8.81, 8.33, 9.96, 7.24, 4.26, 10.84, 4.82, 5.68]},
    'II':  {'x': [10, 8, 13, 9, 11, 14, 6, 4, 12, 7, 5],
             'y': [9.14, 8.14, 8.74, 8.77, 9.26, 8.10, 6.13, 3.10, 9.13, 7.26, 4.74]},
    'III': {'x': [10, 8, 13, 9, 11, 14, 6, 4, 12, 7, 5],
             'y': [7.46, 6.77, 12.74, 7.11, 7.81, 8.84, 6.08, 5.39, 8.15, 6.42, 5.73]},
    'IV':  {'x': [8, 8, 8, 8, 8, 8, 8, 19, 8, 8, 8],
             'y': [6.58, 5.76, 7.71, 8.84, 8.47, 7.04, 5.25, 12.50, 5.56, 7.91, 6.89]},
}

fig, axes = plt.subplots(2, 2, figsize=(12, 10))
axes = axes.flatten()

for idx, (name, data) in enumerate(anscombe.items()):
    ax = axes[idx]
    x = np.array(data['x'])
    y = np.array(data['y'])

    ax.scatter(x, y, s=80, color='steelblue', edgecolors='gray',
               linewidth=0.5, zorder=5)

    # 回帰直線
    slope, intercept, r_value, _, _ = stats.linregress(x, y)
    x_line = np.linspace(2, 20, 100)
    ax.plot(x_line, slope * x_line + intercept, 'r-', linewidth=2, alpha=0.7)

    # 統計量
    stats_text = (f'$\\bar{{x}}$ = {x.mean():.1f}, $\\bar{{y}}$ = {y.mean():.2f}\n'
                  f'$s_x$ = {x.std():.2f}, $s_y$ = {y.std():.2f}\n'
                  f'$r$ = {r_value:.3f}\n'
                  f'$y$ = {slope:.2f}$x$ + {intercept:.2f}')
    ax.text(0.05, 0.95, stats_text, transform=ax.transAxes, fontsize=9,
            verticalalignment='top',
            bbox=dict(boxstyle='round,pad=0.3', facecolor='lightyellow'))

    ax.set_title(f"Anscombe's Quartet: Dataset {name}", fontsize=12)
    ax.set_xlabel('x', fontsize=11)
    ax.set_ylabel('y', fontsize=11)
    ax.set_xlim(2, 20)
    ax.set_ylim(2, 14)
    ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('anscombe_quartet.png', dpi=150, bbox_inches='tight')
plt.show()

アンスコムの四重奏は、統計量だけでデータを判断する危険性を鮮明に示しています。

  1. 4つのデータセットは、平均、分散、相関係数、回帰直線がほぼ同一であるにもかかわらず、散布図を見ると全く異なるパターンです。

  2. データセットI: 線形関係が適切に当てはまる「正常な」データ。相関係数が意味を持つケースです。

  3. データセットII: 放物線状の非線形関係。直線では不適切であり、相関係数は過小評価されています。

  4. データセットIII: 1つの外れ値が回帰直線を歪めています。外れ値を除けばほぼ完全な線形関係です。

  5. データセットIV: 1つの極端な点が相関を作り出しています。この点がなければ相関はほぼ0です。

分散共分散行列とポートフォリオ理論

複数の確率変数の共分散を行列にまとめた分散共分散行列とその応用を示します。

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

np.random.seed(42)

# 3つの資産のリターン(相関構造あり)
n_days = 1000
mu = np.array([0.08, 0.12, 0.06])  # 年間期待リターン
sigma = np.array([0.15, 0.25, 0.10])  # 年間ボラティリティ

# 相関行列
corr_matrix = np.array([
    [1.0,  0.3,  -0.2],
    [0.3,  1.0,  0.1],
    [-0.2, 0.1,  1.0]
])

# 分散共分散行列
cov_matrix = np.outer(sigma, sigma) * corr_matrix

# サンプル生成
daily_mu = mu / 252
daily_cov = cov_matrix / 252
returns = np.random.multivariate_normal(daily_mu, daily_cov, n_days)

fig, axes = plt.subplots(1, 3, figsize=(16, 5))

# (a) 分散共分散行列のヒートマップ
ax = axes[0]
labels = ['Asset A', 'Asset B', 'Asset C']
im = ax.imshow(cov_matrix, cmap='RdBu_r', vmin=-0.04, vmax=0.08)
plt.colorbar(im, ax=ax, label='Covariance')
ax.set_xticks(range(3))
ax.set_yticks(range(3))
ax.set_xticklabels(labels, fontsize=10)
ax.set_yticklabels(labels, fontsize=10)
for i in range(3):
    for j in range(3):
        ax.text(j, i, f'{cov_matrix[i,j]:.4f}', ha='center', va='center',
                fontsize=10, fontweight='bold',
                color='white' if abs(cov_matrix[i,j]) > 0.03 else 'black')
ax.set_title('Covariance Matrix', fontsize=13)

# (b) 相関行列のヒートマップ
ax = axes[1]
sample_corr = np.corrcoef(returns.T)
im2 = ax.imshow(sample_corr, cmap='RdBu_r', vmin=-1, vmax=1)
plt.colorbar(im2, ax=ax, label='Correlation')
ax.set_xticks(range(3))
ax.set_yticks(range(3))
ax.set_xticklabels(labels, fontsize=10)
ax.set_yticklabels(labels, fontsize=10)
for i in range(3):
    for j in range(3):
        ax.text(j, i, f'{sample_corr[i,j]:.3f}', ha='center', va='center',
                fontsize=10, fontweight='bold',
                color='white' if abs(sample_corr[i,j]) > 0.3 else 'black')
ax.set_title('Sample Correlation Matrix', fontsize=13)

# (c) ポートフォリオのリスク-リターン
ax = axes[2]
n_portfolios = 5000
weights_all = np.random.dirichlet([1, 1, 1], n_portfolios)

port_returns = weights_all @ mu
port_volatility = np.sqrt(np.array([w @ cov_matrix @ w for w in weights_all]))

sharpe = port_returns / port_volatility

scatter = ax.scatter(port_volatility * 100, port_returns * 100,
                     c=sharpe, cmap='viridis', alpha=0.5, s=5)
plt.colorbar(scatter, ax=ax, label='Sharpe Ratio')

# 個別資産のプロット
for i, label in enumerate(labels):
    ax.scatter(sigma[i]*100, mu[i]*100, s=100, marker='D', zorder=5,
               edgecolors='black', linewidth=1.5, label=label)

ax.set_xlabel('Volatility (%)', fontsize=12)
ax.set_ylabel('Expected Return (%)', fontsize=12)
ax.set_title('Efficient Frontier\n(Portfolio Risk-Return)', fontsize=13)
ax.legend(fontsize=9)
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('covariance_portfolio.png', dpi=150, bbox_inches='tight')
plt.show()

この可視化から、分散共分散行列のポートフォリオ理論への応用が理解できます。

  1. 左図(分散共分散行列): 対角要素は各資産の分散であり、Asset Bが最も大きい(0.0625、ボラティリティ25%)。非対角要素が共分散で、Asset AとCは負の共分散(-0.0030)を持っています。

  2. 中央図(相関行列): 標本から推定した相関行列です。AとBの正の相関(0.3付近)、AとCの負の相関(-0.2付近)が理論値と概ね一致しています。

  3. 右図(効率的フロンティア): 異なる重み配分のポートフォリオのリスク-リターンが示されています。負の共分散を持つ資産の組み合わせにより、個別資産よりもリスク(ボラティリティ)が低く、リターンが高いポートフォリオが存在することが確認できます。これが分散投資の効果であり、和の分散の公式 $\text{Var}(\sum w_i X_i) = \bm{w}^T \bm{\Sigma} \bm{w}$ が基盤です。

標本共分散と標本相関係数

定義

観測データ $(x_1, y_1), \ldots, (x_n, y_n)$ から計算する標本共分散標本相関係数

$$ s_{XY} = \frac{1}{n-1} \sum_{i=1}^{n} (x_i – \bar{x})(y_i – \bar{y}) $$

$$ r = \frac{s_{XY}}{s_X s_Y} = \frac{\sum_{i=1}^{n}(x_i – \bar{x})(y_i – \bar{y})}{\sqrt{\sum_{i=1}^{n}(x_i – \bar{x})^2} \sqrt{\sum_{i=1}^{n}(y_i – \bar{y})^2}} $$

$n-1$ で割るのは不偏推定量にするためです(ベッセルの補正)。

注意: $r$ の標本分布

$\rho \neq 0$ のとき、$r$ の標本分布は正規分布に従いません。フィッシャーの $z$ 変換

$$ z = \frac{1}{2} \ln\frac{1+r}{1-r} = \text{artanh}(r) $$

を施すと、$z$ は近似的に $N(\text{artanh}(\rho), 1/(n-3))$ に従い、正規近似が使えるようになります。

まとめ

本記事では、共分散と相関係数の定義・性質・応用について解説しました。

  • 共分散 $\text{Cov}(X, Y) = E[(X – \mu_X)(Y – \mu_Y)] = E[XY] – E[X]E[Y]$ は2つの変数の共変動の大きさを測る
  • 相関係数 $\rho = \text{Cov}(X,Y) / (\sigma_X \sigma_Y)$ は共分散を正規化し、$-1 \leq \rho \leq 1$ の範囲に収まる
  • $|\rho| = 1$ は完全な線形関係、$\rho = 0$ は線形関係なし(無相関)を意味する
  • 相関係数は線形関係しか捉えない — アンスコムの四重奏が示すように、散布図の確認が不可欠
  • 相関関係は因果関係を意味しない — 交絡因子の可能性を常に考慮する
  • 分散共分散行列はポートフォリオ理論やPCAの基盤であり、多変量解析の中核的な概念

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