Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

予測性能の評価指標(Metrics)

Regression

二乗誤差

誤差を二乗するので、絶対誤差に比べて大きく予測を外した値が強調されるのが特徴。

MSE (Mean Squared Error)

二乗誤差 (yiy^i)2(y_i - \hat{y}_i)^2 を平均したもの

RMSE (Root Mean Squared Error)

MSEの平方根。元の単位に戻るため比較的解釈しやすい。

絶対誤差

二乗しないため外れ値に強い。
また、ビジネスサイドへの説明も行いやすい。(RMSEは「誤差を二乗して平方根をとったもので⋯」とか説明しても計算が複雑でわかりにくい)

MAE (Mean Absolute Error)

平均絶対誤差。誤差の絶対値の平均。

絶対誤差の勾配は符号しか残らない

Source
import matplotlib.pyplot as plt
import numpy as np

e = np.linspace(-2, 2, 100)

plt.figure(figsize=[4,3])
plt.plot(x, e**2, label=r"Squared Error $e^2$")
plt.plot(x, abs(e), label=r"Absolute Error $|e|$")

plt.ylabel(r"$error$")
plt.xlabel(r"$e$")
plt.legend()
plt.show()
<Figure size 400x300 with 1 Axes>

誤差率

誤差と真値の比率に基づく指標。これも説明性は高い

(0除算に注意が必要)

MAPE (Mean Absolute Percentage Error)

平均絶対誤差率。

MAPE=1ni=1nyiy^iyi×100\text{MAPE} = \frac{1}{n}\sum_{i=1}^n \left| \frac{y_i - \hat{y}_i}{y_i} \right| \times 100
MAPEに対応する損失関数

MAPEに近いのはMAEではなくFair Loss。

MAE、つまり絶対誤差だと勾配をとったときに残差の符号しか残らず、誤差の大きさがわからなくなる。

その点、Fair Lossのほうがいい

(参考:SIGNATE 土地価格コンペ 1位解法

相関

相関係数

予測値と実測値の相関

R=Corr(y,y^)R = \operatorname{Corr}(y, \hat{y})

決定係数

決定係数。モデルがどれだけ分散を説明できるか。

R2=1(yiy^i)2(yiyˉ)2R^2 = 1 - \frac{\sum (y_i - \hat{y}_i)^2}{\sum (y_i - \bar{y})^2}

確率予測

Source
# データ生成
from sklearn.datasets import make_classification
size = 1000
args = dict(n_samples=size, n_features=2, n_informative=1, n_redundant=1, class_sep=0.5, n_classes=2, n_clusters_per_class=1, random_state=0)
X_train, y_train = make_classification(**args)
X_test, y_test = make_classification(**args)

# 予測確率の例
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression()
clf.fit(X_train, y_train)
y_prob = clf.predict_proba(X_test)[:, 1]

Calibration Plot

  • 横軸に予測確率

  • 縦軸には経験確率、つまり「同じくらいの予測確率になったサンプルを集めたときの実際の正例の比率」

を出したプロット

(参考:1.16. Probability calibration — scikit-learn 1.7.2 documentation

Source
import numpy as np
import matplotlib.pyplot as plt
from sklearn.calibration import CalibrationDisplay

# キャリブレーションプロット
disp = CalibrationDisplay.from_predictions(
    y_true=y_test,
    y_prob=y_prob,
    n_bins=10,          # 分割数(デフォルト10)
    strategy="uniform", # ビンの区切り方(uniform または quantile)
    name="Logistic Regression"
)

plt.title("Calibration Plot (Reliability Curve)")
plt.grid(True)
plt.show()
<Figure size 640x480 with 1 Axes>

Log Loss(Cross Entropy Loss)

予測確率の信頼度を含めた誤差指標。確率出力モデルに適する。

LogLoss=1ni=1n[yilogp^i+(1yi)log(1p^i)]\text{LogLoss} = -\frac{1}{n}\sum_{i=1}^n [y_i\log \hat{p}_i + (1-y_i)\log(1-\hat{p}_i)]
from sklearn.metrics import log_loss
log_loss(y_test, y_prob)
0.3873822188513259

Brier Score Loss

Brier Score は 正解クラスと予測確率の平均二乗誤差(MSE)で定義される指標。低いほど良いのでBrier Score Lossとも呼ばれる。

2クラス分類の場合

2クラス分類の場合は正解クラスyiy_iと予測確率p^i\hat{p}_iにより次のように表され、[0,1][0,1]の値をとる。

Brier Score=1Ni=1N(yip^i)2\text{Brier Score} = \frac{1}{N} \sum_{i=1}^N (y_i - \hat{p}_i)^2

CCクラス分類の場合

一般にCCクラス分類の場合は次のように表され、[0,2][0,2]の値をとる。

Brier Score=1Ni=1Nc=1C(yicp^ic)2\text{Brier Score} = \frac{1}{N}\sum_{i=1}^{N}\sum_{c=1}^{C}(y_{ic} - \hat{p}_{ic})^{2}

brier_score_loss — scikit-learn 1.8.0 documentation

from sklearn.metrics import brier_score_loss
brier_score_loss(y_test, y_prob)
0.1209847403686766

二値分類 (Binary Classification)

特定の閾値の下での評価

予測値の確率・信頼度を特定の閾値で区切ってPositive/Negativeを出した下での評価指標

混同行列(Confusion Matrix)

True Positive (TP) と True Negative (TN) に分けられた数の分布を視覚的に判断する

実際\予測PositiveNegative
PositiveTP(真陽性)FN(偽陰性)
NegativeFP(偽陽性)TN(真陰性)
Source
# create sample data
import numpy as np
size = 100
np.random.seed(42)
y_true = np.random.binomial(n=1, p=0.2, size=size)
y_pred = np.random.binomial(n=1, p=0.2, size=size)

# confusion matrix
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=[4, 3])
from sklearn.metrics import ConfusionMatrixDisplay
ConfusionMatrixDisplay.from_predictions(y_true, y_pred, ax=ax)
<sklearn.metrics._plot.confusion_matrix.ConfusionMatrixDisplay at 0x7a1796589720>
<Figure size 400x300 with 2 Axes>

Accuracy(正解率)

全体のうち、正しく分類できた割合。

Accuracy=TP+TNTP+FP+TN+FN\text{Accuracy} = \frac{TP + TN}{TP + FP + TN + FN}

Recall(再現率)

実際に「正例(Positive)」であるもののうち、正しく予測できた割合。
どれだけFalse Negativeを小さくできたか。

Recall=TPTP+FN\text{Recall} = \frac{TP}{TP + FN}

Precision(適合率)

「正例(Positive)」と予測したうち、実際にPositiveだった割合。
どれだけFalse Positiveを小さくできたか

Precision=TPTP+FP\text{Precision} = \frac{TP}{TP + FP}

F1-score

PrecisionとRecallの調和平均。両者のバランスを取る指標。
PrecisionとRecallにはトレードオフ関係がある(https://datawokagaku.com/f1score/ )ため平均で評価している。

F1=21Recall+1Precision=2Recall×PrecisionRecall+PrecisionF1 = \frac{2}{\frac{1}{Recall} + \frac{1}{Precision}} = 2 \frac{Recall \times Precision}{Recall + Precision}
from sklearn.metrics import accuracy_score, recall_score, precision_score, f1_score
for metrics in "accuracy_score, recall_score, precision_score, f1_score".split(", "):
    value = eval(f"{metrics}(y_true, y_pred)")
    print(f"{metrics}={value:.2}")
accuracy_score=0.64
recall_score=0.17
precision_score=0.12
f1_score=0.14

複数の閾値のもとでの指標

ROC-AUC(Area Under the ROC Curve)

ROC曲線(真陽性率 vs 偽陽性率)の下の面積。
1に近いほどモデルの識別能力が高い。

true positive rate TPRTPR(recallの別名、陽性者を正しく陽性だと当てる率、sensitivityとも)とfalse positive rate FPRFPR(陰性者のうち偽陽性になる率)

TPR=TPP=TPTP+FN=Positiveを当てたものPositiveのものFPR=FPN=FPFN+TN=Positiveを外したものNegativeのものTPR = \frac{TP}{P} = \frac{TP}{TP + FN} = \frac{\text{Positiveを当てたもの}}{\text{Positiveのもの}}\\ FPR = \frac{FP}{N} = \frac{FP}{FN + TN} = \frac{\text{Positiveを外したもの}}{\text{Negativeのもの}}

を用いて閾値を変えながら描いた曲線をreceiver operating characteristic(ROC; 受信者操作特性)曲線という。

ROC曲線の下側の面積(Area Under the Curve)をROC-AUCという。ランダムなアルゴリズム(chance level)だとROC-AUCは0.5になる

Source
from sklearn.datasets import make_classification
size = 1000
X, y = make_classification(n_samples=size, n_features=2, n_informative=1, n_redundant=1,
                           class_sep=0.5, n_classes=2, n_clusters_per_class=1, random_state=0)

# ランダムなアルゴリズム
import numpy as np
np.random.seed(1)
random = np.random.binomial(n=1, p=0.5, size=size)

# Logistic Regression
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression()
clf.fit(X, y)
y_pred = clf.predict(X)

# plot
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=[4, 3])

from sklearn.metrics import RocCurveDisplay
RocCurveDisplay.from_predictions(
    y,
    random,
    name="Random Classifier",
    color="darkorange",
    ax=ax
)
RocCurveDisplay.from_predictions(
    y,
    y_pred,
    name="Logistic Regression",
    color="steelblue",
    plot_chance_level=True,
    ax=ax
)
fig.show()
/tmp/ipykernel_57789/1909585709.py:37: UserWarning: Matplotlib is currently using module://matplotlib_inline.backend_inline, which is a non-GUI backend, so cannot show the figure.
  fig.show()
<Figure size 400x300 with 1 Axes>

Precision-Recall Curve

さまざまなthresholdの元でのRecallとPrecisionを算出し、横軸にRecall、縦軸にPrecisionを結んだグラフ

PR曲線の下側の面積(Area Under the Curve)をPR-AUCあるいはAverage Precisionという

AP=k=1K(RkRk1)PkAP = \sum^K_{k=1} (R_k - R_{k-1}) P_k

ROC曲線とは異なり、「ランダムなアルゴリズムなら0.5」のような安定したスケールではなく、スケールはクラスのバランス(不均衡具合)に依存する

その分、不均衡データにおけるモデル評価に向いていると言われている

Source
from sklearn.datasets import make_classification
size = 1000
X, y = make_classification(n_samples=size, n_features=2, n_informative=1, n_redundant=1,
                           class_sep=0.5, n_classes=2, n_clusters_per_class=1, random_state=0)

# Logistic Regression
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression()
clf.fit(X, y)
y_pred = clf.predict(X)

# plot
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=[4, 3])

from sklearn.metrics import PrecisionRecallDisplay
PrecisionRecallDisplay.from_predictions(y, y_pred, ax=ax)
fig.show()
/tmp/ipykernel_57789/2352438180.py:18: UserWarning: Matplotlib is currently using module://matplotlib_inline.backend_inline, which is a non-GUI backend, so cannot show the figure.
  fig.show()
<Figure size 400x300 with 1 Axes>

imbalanced dataとPR曲線・ROC曲線

ある不均衡データがあったとする

from sklearn.datasets import make_classification
size = 1000
X, y = make_classification(n_samples=size, n_features=2, n_informative=1, n_redundant=1, weights=[0.9, 0.1],
                           class_sep=0.5, n_classes=2, n_clusters_per_class=1, random_state=0)

import pandas as pd
pd.Series(y).value_counts()
0 894 1 106 Name: count, dtype: int64
Source
# Logistic Regression
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression()
clf.fit(X, y)
y_pred = clf.predict(X)

from sklearn.metrics import accuracy_score, recall_score, precision_score, f1_score
for metrics in "accuracy_score, recall_score, precision_score, f1_score".split(", "):
    value = eval(f"{metrics}(y, y_pred)")
    print(f"{metrics}={value:.2}")
accuracy_score=0.9
recall_score=0.26
precision_score=0.55
f1_score=0.36
Source

import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=[4, 3])
from sklearn.metrics import ConfusionMatrixDisplay
ConfusionMatrixDisplay.from_predictions(y, y_pred, ax=ax)
<sklearn.metrics._plot.confusion_matrix.ConfusionMatrixDisplay at 0x7a179615d9c0>
<Figure size 400x300 with 2 Axes>
Source
# plot
import matplotlib.pyplot as plt
fig, axes = plt.subplots(figsize=[8, 3], ncols=2)

from sklearn.metrics import RocCurveDisplay, PrecisionRecallDisplay
RocCurveDisplay.from_predictions(y, y_pred, plot_chance_level=True, ax=axes[0])
PrecisionRecallDisplay.from_predictions(y, y_pred, ax=axes[1])
fig.show()
/tmp/ipykernel_57789/4277730166.py:8: UserWarning: Matplotlib is currently using module://matplotlib_inline.backend_inline, which is a non-GUI backend, so cannot show the figure.
  fig.show()
<Figure size 800x300 with 2 Axes>

マシューズ相関係数(MCC)

マシューズ相関係数(Matthews Correlation Coefficient: MCC) は二値分類モデルの性能評価指標の一つで、特にクラスの不均衡がある場合に信頼性が高いことで知られている。

MCC=TPTNFPFN(TP+FP)(TP+FN)(TN+FP)(TN+FN)\mathrm{MCC}=\frac{T P \cdot T N-F P \cdot F N}{\sqrt{(T P+F P)(T P+F N)(T N+F P)(T N+F N)}}

言葉でいうと

  • 分子: 正しく分類された数(TP × TN) から、 誤分類の積(FP × FN) を引いたもの。

  • 分母:全体の規模を正規化(0除算を防ぐため)。

from sklearn.metrics import matthews_corrcoef

y_true = [1, 1, 0, 0, 0, 0, 0]
y_pred = [1, 0, 1, 0, 0, 0, 0]
print(f"MCC: {matthews_corrcoef(y_true, y_pred):.3f}")

# 不均衡なデータに対してMajority Classだけを予測した場合
y_true = [1, 0, 0, 0, 0, 0, 0]
y_pred = [0, 0, 0, 0, 0, 0, 0]
print(f"MCC: {matthews_corrcoef(y_true, y_pred):.3f}")
MCC: 0.300
MCC: 0.000

Balanced Accuracy

Balanced Accuracy は、各クラスの正解率(リコール、感度)を平均したもの

 Balanced Accuracy =12(TPTP+FN+TNTN+FP)\text { Balanced Accuracy }=\frac{1}{2}\left(\frac{T P}{T P+F N}+\frac{T N}{T N+F P}\right)

ここで:

  • TPTP+FN\frac{TP}{TP + FN}:感度(Sensitivity)または再現率(Recall)

  • TNTN+FP\frac{TN}{TN + FP}:特異度(Specificity)

不均衡データに強いとされる。

from sklearn.metrics import accuracy_score, balanced_accuracy_score

# 不均衡なデータに対してMajority Classだけを予測した場合
y_true = [1, 0, 0, 0, 0, 0, 0]
y_pred = [0, 0, 0, 0, 0, 0, 0]

print(f"accuracy: {accuracy_score(y_true, y_pred):.3f}")
print(f"balanced_accuracy: {balanced_accuracy_score(y_true, y_pred):.3f}")
accuracy: 0.857
balanced_accuracy: 0.500

多クラス分類(Multiclass Classification)

Macro F1

各クラスのF1スコアを単純平均したもの。クラス不均衡に弱い。
各クラスを等しく扱う。

Micro F1

全サンプルのTP・FP・FNを合計してからF1を計算。
サンプル数の多いクラスに影響されやすい。

Weighted F1

各クラスのF1をクラスのサンプル数で重み付けして平均。
クラス不均衡データに適する。

ランキング・推薦(Ranking / Recommender)

Precision@k

上位 kk 件の予測のうち、正解が占める割合。

P@k=正解件数@kk\text{P@k} = \frac{\text{正解件数@k}}{k}

Recall@k

上位 kk 件が、全正解のうちどれだけをカバーしたか。

R@k=正解件数@k全正解件数\text{R@k} = \frac{\text{正解件数@k}}{\text{全正解件数}}

MAP(Mean Average Precision)

各クエリに対する平均適合率(AP)を平均化したもの。

MAP=1Qq=1Q1Rqk=1RqPrecision@k\text{MAP} = \frac{1}{Q}\sum_{q=1}^{Q} \frac{1}{R_q}\sum_{k=1}^{R_q} \text{Precision@k}

NDCG(Normalized Discounted Cumulative Gain)

順位の高い正解をより高く評価する。上位の重要性を考慮。

NDCG@k=DCG@kIDCG@k\text{NDCG@k} = \frac{\text{DCG@k}}{\text{IDCG@k}}

MRR(Mean Reciprocal Rank)

最初の正解が出現する順位の逆数を平均。

MRR=1Qi=1Q1ranki\text{MRR} = \frac{1}{Q}\sum_{i=1}^{Q} \frac{1}{\text{rank}_i}

類似度

コサイン類似度

ベクトルの方向が似ているものは似ている

コサイン類似度(Cosine Similarity)とは?:AI・機械学習の用語辞典 - @IT

2つのベクトルがなす角(コサイン)の値が類似度として使える、ということになる

ab=a bcos(a,b)    cos(a,b)=aba b\newcommand{\b}[1]{\boldsymbol{#1}} \b{a} \cdot \b{b} = ||\b{a}|| \ ||\b{b}|| \cos(\b{a}, \b{b}) \\ \implies \cos(\b{a}, \b{b}) = \frac{ \b{a} \cdot \b{b} }{ ||\b{a}|| \ ||\b{b}|| }
Source
import numpy as np
import matplotlib.pyplot as plt

def cos(a, b):
    e = 1e-8
    return a @ b / (np.linalg.norm(a + e) * np.linalg.norm(b + e))

def plot(ax, a, b):
    for x in [a, b]:
        ax.axhline(color="gray", alpha=.5)
        ax.axvline(color="gray", alpha=.5)
        ax.text(x[0], x[1], f"{x[0], x[1]}", color="black")
        ax.annotate("", xy=(x[0], x[1]), xytext=(0, 0),
                    arrowprops=dict(arrowstyle="->", connectionstyle="arc3"))
        ax.set(title=f"cos(a, b) = {cos(a, b):.2f}", xlim=(-5, 5), ylim=(-5, 5))
        # ax.grid(True)
    return ax


data = [
    [
        np.array([4, 4]),
        np.array([2, 2])
    ],
    [
        np.array([1, 3]),
        np.array([4, 3])
    ],
    [
        np.array([4, 0]),
        np.array([0, 4])
    ],
    [
        np.array([3, 3]),
        np.array([-4, -4])
    ]
]

fig, axes = plt.subplots(figsize=(8, 2), ncols=4)
for i in range(4):
    a, b = data[i]
    plot(axes[i], a, b)
fig.tight_layout()
<Figure size 800x200 with 4 Axes>

KLダイバージェンス

2つの分布p(x),q(x)p(x), q(x)に対する距離のようなもの。ただし、非対称(KL(pq)KL(qp)\operatorname{KL}(p\|q) \ne \operatorname{KL}(q\|p))である。

確率密度関数 p(x)p(x), q(x)q(x) に対して:

KL(pq)=p(x)logp(x)q(x)dx=Ep ⁣[logp(X)q(X)]\mathrm{KL}(p\|q) = \int p(x) \log \frac{p(x)}{q(x)} \, dx = \mathbb{E}_{p}\!\left[\log \frac{p(X)}{q(X)}\right]
Source
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm

# Fix p = N(0,1)
mu_p = 0
sigma_p = 1

# q = N(mu_q, 1), vary mu_q
mu_q_vals = np.linspace(-3, 3, 200)
sigma_q = 1

# KL for normal distributions with same variance simplifies to:
# KL = (mu_p - mu_q)^2 / (2*sigma^2)
kl_vals = ((mu_p - mu_q_vals)**2) / (2 * sigma_q**2) 

plt.figure(figsize=(4,2.5))
plt.plot(mu_q_vals, kl_vals)
plt.xlabel(r"$\mu_q$")
plt.ylabel("KL(p || q)")
plt.title(r"KL Divergence: $p = N(0,1), q = N(\mu_q,1)$")
plt.grid(True)
plt.show()
<Figure size 400x250 with 1 Axes>
(参考)1変量正規分布同士のKLダイバージェンスの導出

1 次元の正規分布 p(x)=N(μ0,σ02)p(x) = \mathcal{N}(\mu_0, \sigma_0^2)q(x)=N(μ1,σ12)q(x) = \mathcal{N}(\mu_1, \sigma_1^2) に対してKL(pq)\operatorname{KL}(p\|q) を定義から導く。

KL ダイバージェンスの定義は

KL(pq)=p(x)logp(x)q(x)dx=Ep ⁣[logp(X)q(X)]\operatorname{KL}(p\|q) = \int p(x) \log \frac{p(x)}{q(x)} \, dx = \mathbb{E}_{p}\!\left[\log \frac{p(X)}{q(X)}\right]

正規分布の密度は

p(x)=12πσ0exp ⁣((xμ0)22σ02),q(x)=12πσ1exp ⁣((xμ1)22σ12)p(x) = \frac{1}{\sqrt{2\pi}\sigma_0} \exp\!\left( - \frac{(x-\mu_0)^2}{2\sigma_0^2} \right) ,\quad q(x) = \frac{1}{\sqrt{2\pi}\sigma_1} \exp\!\left( - \frac{(x-\mu_1)^2}{2\sigma_1^2} \right)

1. 対数比とその期待値について

対数比 logp(x)q(x)\log \dfrac{p(x)}{q(x)} をとる:

logp(x)q(x)=log(σ1σ0)(xμ0)22σ02+(xμ1)22σ12\begin{aligned} \log \frac{p(x)}{q(x)} &= \log\left( \frac{\sigma_1}{\sigma_0} \right) -\frac{(x-\mu_0)^2}{2\sigma_0^2} +\frac{(x-\mu_1)^2}{2\sigma_1^2} \end{aligned}

KLダイバージェンスは対数比の期待値であるため

KL(pq)=Ep ⁣[logp(X)q(X)]=logσ1σ012σ02Ep[(Xμ0)2]+12σ12Ep[(Xμ1)2]\begin{aligned} \operatorname{KL}(p\|q) &= \mathbb{E}_p\!\left[\log\frac{p(X)}{q(X)}\right] \\ &= \log\frac{\sigma_1}{\sigma_0} - \frac{1}{2\sigma_0^2}\mathbb{E}_p[(X-\mu_0)^2] + \frac{1}{2\sigma_1^2}\mathbb{E}_p[(X-\mu_1)^2] \end{aligned}

なので、残りは Ep[(Xμ0)2]\mathbb{E}_p[(X-\mu_0)^2]Ep[(Xμ1)2]\mathbb{E}_p[(X-\mu_1)^2] を評価すればよい。

2. Ep[(Xμ0)2]\mathbb{E}_p[(X-\mu_0)^2] について

Ep[(Xμ0)2]=Varp(X)=σ02\mathbb{E}_p[(X-\mu_0)^2] = \operatorname{Var}_p(X) = \sigma_0^2 であるため、

12σ02Ep[(Xμ0)2]=12σ02σ02=12-\frac{1}{2\sigma_0^2}\mathbb{E}_p[(X-\mu_0)^2] = -\frac{1}{2\sigma_0^2}\sigma_0^2 = -\frac12

とシンプルにできる。

3. Ep[(Xμ1)2]\mathbb{E}_p[(X-\mu_1)^2] について

(Xμ1)(X-\mu_1)μ0\mu_0を足して引いて (Xμ0)+(μ0μ1)(X-\mu_0)+(\mu_0-\mu_1) に分解する:

(Xμ1)2=((Xμ0)+(μ0μ1))2=(Xμ0)2+2(Xμ0)(μ0μ1)+(μ0μ1)2\begin{aligned} (X-\mu_1)^2 &= \bigl((X-\mu_0)+(\mu_0-\mu_1)\bigr)^2 \\ &= (X-\mu_0)^2 + 2(X-\mu_0)(\mu_0-\mu_1) + (\mu_0-\mu_1)^2 \end{aligned}

これを pp に関する期待値にすると:

Ep[(Xμ1)2]=Ep[(Xμ0)2]+2(μ0μ1)Ep[Xμ0]+(μ0μ1)2\begin{aligned} \mathbb{E}_p[(X-\mu_1)^2] &= \mathbb{E}_p[(X-\mu_0)^2] + 2(\mu_0-\mu_1)\mathbb{E}_p[X-\mu_0] + (\mu_0-\mu_1)^2 \end{aligned}

ここで

  • Ep[(Xμ0)2]=σ02\mathbb{E}_p[(X-\mu_0)^2] = \sigma_0^2

  • Ep[Xμ0]=0\mathbb{E}_p[X-\mu_0] = 0

なので、

Ep[(Xμ1)2]=σ02+(μ0μ1)2\mathbb{E}_p[(X-\mu_1)^2] = \sigma_0^2 + (\mu_0-\mu_1)^2

したがって

12σ12Ep[(Xμ1)2]=σ02+(μ0μ1)22σ12\frac{1}{2\sigma_1^2}\mathbb{E}_p[(X-\mu_1)^2] = \frac{\sigma_0^2 + (\mu_0-\mu_1)^2}{2\sigma_1^2}

4. まとめ

以上をまとめると

KL(pq)=logσ1σ012+σ02+(μ0μ1)22σ12\begin{aligned} \operatorname{KL}(p\|q) &= \log\frac{\sigma_1}{\sigma_0} - \frac12 + \frac{\sigma_0^2 + (\mu_0-\mu_1)^2}{2\sigma_1^2} \end{aligned}

よって、1 次元正規分布どうしの KL ダイバージェンスは

KL(N(μ0,σ02)N(μ1,σ12))=logσ1σ0+σ02+(μ0μ1)22σ1212\boxed{ \operatorname{KL}\bigl(\mathcal{N}(\mu_0,\sigma_0^2) \big\| \mathcal{N}(\mu_1,\sigma_1^2) \bigr) = \log\frac{\sigma_1}{\sigma_0} + \frac{\sigma_0^2 + (\mu_0-\mu_1)^2}{2\sigma_1^2} -\frac12 }

となる。