尤度関数と最尤推定法(MLE)をわかりやすく解説する

機械学習や統計学において、尤度関数と最尤推定法(Maximum Likelihood Estimation; MLE)は最も基本的で重要な概念の1つです。パラメータ推定の手法として頻繁に登場するため、しっかりと理解しておく必要があります。

今回は、尤度関数の定義から最尤推定法の導出、そして Python での実装まで解説します。

本記事の内容

  • 尤度関数の定義と確率との違い
  • 最尤推定法の考え方
  • 正規分布とベルヌーイ分布での導出
  • Python での可視化

前提知識

この記事を読む前に、以下の概念を理解しておくと理解が深まります。

  • 確率分布の基本(正規分布、ベルヌーイ分布)
  • 微分の基本

確率と尤度の違い

まず、確率と尤度の違いを明確にしましょう。

確率: パラメータ $\theta$ が固定されたもとで、データ $x$ がどれくらい起こりやすいかを表す。$x$ の関数。

$$ P(x|\theta) \quad (\theta \text{ は固定、} x \text{ が変数}) $$

尤度: データ $x$ が固定されたもとで、パラメータ $\theta$ がどれくらいもっともらしいかを表す。$\theta$ の関数。

$$ L(\theta|x) = P(x|\theta) \quad (x \text{ は固定、} \theta \text{ が変数}) $$

数式としては同じ形ですが、何を固定して何を変数として見るかが異なります。

尤度関数の定義

データ $\mathcal{D} = \{x_1, x_2, \dots, x_N\}$ が独立に分布 $p(x|\theta)$ から生成されたとき、尤度関数は次のように定義されます。

$$ \begin{equation} L(\theta|\mathcal{D}) = \prod_{n=1}^{N} p(x_n|\theta) \end{equation} $$

対数尤度

実用上は、積を和に変換できる対数尤度を使うことがほとんどです。

$$ \begin{equation} \ell(\theta) = \ln L(\theta|\mathcal{D}) = \sum_{n=1}^{N} \ln p(x_n|\theta) \end{equation} $$

対数は単調増加関数であるため、尤度を最大にする $\theta$ と対数尤度を最大にする $\theta$ は一致します。

最尤推定法とは

最尤推定法は、対数尤度を最大にするパラメータ $\hat{\theta}_{\text{MLE}}$ を求める方法です。

$$ \begin{equation} \hat{\theta}_{\text{MLE}} = \arg\max_\theta \ell(\theta) \end{equation} $$

具体的には、対数尤度を $\theta$ で微分して0とおく方程式を解きます。

$$ \begin{equation} \frac{\partial \ell(\theta)}{\partial \theta} = 0 \end{equation} $$

正規分布の最尤推定

データ $\{x_1, \dots, x_N\}$ が正規分布 $\mathcal{N}(\mu, \sigma^2)$ に従う場合を考えます。

対数尤度は、

$$ \begin{align} \ell(\mu, \sigma^2) &= \sum_{n=1}^{N} \ln \frac{1}{\sqrt{2\pi\sigma^2}} \exp\left(-\frac{(x_n-\mu)^2}{2\sigma^2}\right) \\ &= -\frac{N}{2}\ln(2\pi) – \frac{N}{2}\ln\sigma^2 – \frac{1}{2\sigma^2}\sum_{n=1}^{N}(x_n – \mu)^2 \end{align} $$

平均 $\mu$ の最尤推定

$\mu$ で微分して0とおくと、

$$ \frac{\partial \ell}{\partial \mu} = \frac{1}{\sigma^2}\sum_{n=1}^{N}(x_n – \mu) = 0 $$

$$ \begin{equation} \hat{\mu}_{\text{MLE}} = \frac{1}{N}\sum_{n=1}^{N} x_n = \bar{x} \end{equation} $$

最尤推定量は標本平均に一致します。

分散 $\sigma^2$ の最尤推定

$\sigma^2$ で微分して0とおくと、

$$ \frac{\partial \ell}{\partial \sigma^2} = -\frac{N}{2\sigma^2} + \frac{1}{2(\sigma^2)^2}\sum_{n=1}^{N}(x_n – \mu)^2 = 0 $$

$$ \begin{equation} \hat{\sigma}^2_{\text{MLE}} = \frac{1}{N}\sum_{n=1}^{N}(x_n – \bar{x})^2 \end{equation} $$

ベルヌーイ分布の最尤推定

コイントスのように $x_n \in \{0, 1\}$ のデータに対するベルヌーイ分布 $\text{Bern}(x|\mu)$ の場合を考えます。

対数尤度は、

$$ \ell(\mu) = \sum_{n=1}^{N}[x_n \ln\mu + (1-x_n)\ln(1-\mu)] $$

$\mu$ で微分して0とおくと、

$$ \frac{\partial \ell}{\partial \mu} = \frac{\sum x_n}{\mu} – \frac{N – \sum x_n}{1 – \mu} = 0 $$

$$ \begin{equation} \hat{\mu}_{\text{MLE}} = \frac{1}{N}\sum_{n=1}^{N} x_n = \frac{m}{N} \end{equation} $$

$m$ は表が出た回数です。直感的にも納得できる結果です。

Python での実装

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

# 正規分布の最尤推定
np.random.seed(42)
true_mu = 5.0
true_sigma = 2.0
N = 50
data = np.random.normal(true_mu, true_sigma, N)

# 尤度関数の可視化(muの関数として)
mu_range = np.linspace(2, 8, 300)
sigma_fixed = true_sigma

# 対数尤度の計算
log_likelihoods = np.array([
    np.sum(norm.logpdf(data, mu, sigma_fixed)) for mu in mu_range
])

# 最尤推定値
mu_mle = data.mean()
sigma_mle = data.std()

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

# 左: 対数尤度関数
ax1 = axes[0]
ax1.plot(mu_range, log_likelihoods, 'b-', linewidth=2)
ax1.axvline(x=mu_mle, color='r', linestyle='--', label=f'MLE: mu={mu_mle:.2f}')
ax1.axvline(x=true_mu, color='g', linestyle=':', label=f'True: mu={true_mu}')
ax1.set_xlabel('mu', fontsize=12)
ax1.set_ylabel('Log-likelihood', fontsize=12)
ax1.set_title('Log-Likelihood Function', fontsize=13)
ax1.legend(fontsize=10)
ax1.grid(True, alpha=0.3)

# 右: データ数による推定精度の変化
ax2 = axes[1]
n_trials = 1000
for n_data in [5, 20, 50, 200]:
    mle_estimates = []
    for _ in range(n_trials):
        samples = np.random.normal(true_mu, true_sigma, n_data)
        mle_estimates.append(samples.mean())
    ax2.hist(mle_estimates, bins=50, density=True, alpha=0.4, label=f'N={n_data}')

ax2.axvline(x=true_mu, color='r', linestyle='--', linewidth=2, label=f'True mu={true_mu}')
ax2.set_xlabel('MLE estimate', fontsize=12)
ax2.set_ylabel('Density', fontsize=12)
ax2.set_title('Distribution of MLE Estimates', fontsize=13)
ax2.legend(fontsize=9)
ax2.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

print(f"MLE: mu={mu_mle:.4f}, sigma={sigma_mle:.4f}")
print(f"True: mu={true_mu}, sigma={true_sigma}")

左のグラフでは対数尤度関数が標本平均で最大になること、右のグラフではデータ数が増えるほど最尤推定量のばらつきが小さくなることが確認できます。

まとめ

本記事では、尤度関数と最尤推定法について解説しました。

  • 尤度はデータを固定してパラメータの関数として見たもので、確率とは視点が異なる
  • 最尤推定法は対数尤度を最大化するパラメータを求める手法
  • 正規分布の最尤推定量は標本平均と標本分散に一致する
  • データ数が増えるほど最尤推定量は真のパラメータに収束する(一致性)

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