対数:「何回掛けたか」を数える
このレッスンでは、第5章から使ってきた罰(交差エントロピー)の正体に近づくために、対数 という道具を使います。高校で習う数学ですが、使う性質は1つだけです。
2を何回掛けると、その数になるか
2×2×2=8 なので、「2を 3回 掛けると8になる」と言えます。この「3」を、次のように書きます。
log28=3
「ログ、底が2の、8」と読みます。同じように、log216=4、log21024=10 です。log21=0(1回も掛けない)です。
0と1の間の数では、答えがマイナスになります。21 は「2で1回割った数」なので log221=−1、41 は log241=−2 です。
掛け算が、足し算になる
対数の一番大切な性質は、次のとおりです。
log2(8×16)=log28+log216=3+4=7
8×16=128 は、2を 3+4=7 回掛けた数だからです。「何回掛けたか」を数えるので、掛け算は、回数の足し算 になります。
自然対数:e を何回掛けたか
機械学習では、2の代わりに、第5章のシグモイド関数で紹介した e(約2.718)を使うことがほとんどです。「e を何回掛けるとその数になるか」を 自然対数 と呼び、底を書かずに logx と書きます(本や分野によっては lnx とも書きます)。例えば log2≈0.693 です。
第5章の「0.69」の正体
第5章の罰は、正解に付けた確率 p の自然対数にマイナスを付けた、−logp でした。
正解に付けた確率(横軸)と、罰 −log p(縦軸)の曲線。確率1で罰は0、0.5で0.693、0.25で1.386と、確率が半分になるたびに0.693ずつ増える(○の3点)。確率が0に近づくと、罰は急に大きくなり、0.01では4.6になる
確率が半分になると、「21 を1回多く掛けた」ことになります。掛け算は足し算になるので、罰は −log21=log2≈0.693 だけ増えます。第5章の「確率が半分になるたびに、罰が約0.69ずつ増える」の0.69は、log2 だったのです。
なぜ対数を使うのか:とても小さな数を扱うため
確率0.9のことが1000回続けて起こる確率は、0.9を1000回掛けた 1.7×10−46(小数点の後に0が45個並ぶ数)です。1万回なら約 10−458 になり、コンピューターの小数が表せる範囲(約 10−308 まで)を下回って、正しく計算できなくなります。
対数をとれば、掛け算は足し算になります。0.9の1万回の掛け算は、log0.9≈−0.105 を1万回足した −1053.6 という、ふつうの大きさの数で扱えます。次のスライドでは、この性質を使います。
最尤推定:データが一番起こりやすくなる値を選ぶ
問題:この硬貨の、表の確率はいくつか
表と裏の出方が偏っているかもしれない硬貨を10回投げたところ、表が7回、裏が3回出ました。この硬貨の表の確率 p は、いくつだと考えるのがよいでしょうか。
「7回 ÷ 10回で0.7」と答えたくなります。それで正しいのですが、ここでは、この答えを データから確率を見積もる一般的な方法 で導きます。この方法が、機械学習の学習の土台になっています。
尤度:その p だとしたら、このデータはどれくらい起こりやすいか
例えば表の確率が p=0.5 だとしたら、実際に起こった「表7回・裏3回」(投げた順番も含めて、実際に起こった通りの並び)が起こる確率は、次のとおりです。
0.57×0.53≈0.00098
p=0.7 なら、0.77×0.33≈0.00222 です。このように、「p がその値だとしたら、手元のデータが起こる確率」を、p の 尤度 と呼びます(レッスン3のベイズの定理の「尤度」と同じ考え方です)。いろいろな p で計算しました。
表の確率 p(横軸)と、「表7回・裏3回」の尤度を1000倍した値(縦軸)。山の形の曲線で、p が0.7のとき(○)に一番高く、約2.22。0.5では約0.98、0.9では約0.48で、0.7から離れるほど低くなる
尤度が一番大きくなるのは、p=0.7 のときです。「手元のデータが一番起こりやすくなる p を、答えとして選ぶ」方法を 最尤推定(さいゆうすいてい。「最も尤もらしい」値を推定する、という意味)と呼びます。
対数をとって、マイナスを付ける
実際の機械学習では、データが何千・何万件もあるので、尤度は前のスライドのように、とても小さな数の掛け算になってしまいます。そこで、対数をとって足し算にします(対数尤度)。
log(p7(1−p)3)=7logp+3log(1−p)
さらに、マイナスを付けて「小さいほどよい」数にし、データの数(10)で割ります。これを、1回あたりの負の対数尤度 と呼びます。
対数は、元の数が大きいほど大きくなるので、「尤度が一番大きい p」と「負の対数尤度が一番小さい p」は同じ0.7です。
これが、第5章の罰だった
1回あたりの負の対数尤度を、1回ずつに分けてみます。
107×(−logp)+3×(−log(1−p))
表が出た7回は「表に付けた確率 p」の −log、裏が出た3回は「裏に付けた確率 1−p」の −log です。つまり、「実際に出た方(正解)に付けた確率の −log」の平均 です。これは、第5章の罰(交差エントロピー)の平均そのものです。
ロジスティック回帰は、データごとに「1である確率 p」を予測するモデルでした。罰の平均を小さくする学習は、「訓練データが一番起こりやすくなるように、モデルの重みを選ぶ」最尤推定 だったのです。
正規分布の最尤推定と、MAP推定
正規分布の平均を、最尤推定で求める
20人の身長を測りました(Pythonで作ったデータで、平均は168.9cm)。身長が「標準偏差6の正規分布」に従うと考えて、その平均 μ(ミュー)を最尤推定で求めます。μ の候補ごとに、20人分の負の対数尤度を計算しました。
一番小さくなったのは、20人の身長の平均と同じ168.9でした。実は、正規分布の平均を最尤推定すると、いつもデータの平均と一致します。ふだん何気なく使っている「平均」は、最尤推定の答えでもあったのです。
最小二乗法も、最尤推定だった
正規分布の曲線の式は、中心 μ からのずれを2乗した (x−μ)2 を使って表されます。負の対数尤度を計算すると、
負の対数尤度=2σ21i∑(xi−μ)2+(μによらない数)
という形になります(σ(シグマ)は標準偏差)。つまり、負の対数尤度を最小にすることは、ずれの2乗の和を最小にすることと同じ です。
第4章の線形回帰では、「誤差の2乗の平均」を最小にするように直線を決めました(最小二乗法)。これは、「誤差は正規分布に従う」と考えたときの最尤推定になっています。
- 回帰(誤差が正規分布) → 最尤推定 = 二乗誤差を最小にする
- 分類(正解がベルヌーイ分布) → 最尤推定 = 交差エントロピーを最小にする
回帰と分類で罰が違ったのは、データがどんな分布に従うと考えるか が違ったからです。
MAP推定:データが少ないときは、事前の考えも使う
硬貨を3回投げて、3回とも表だったとします。最尤推定の答えは 33=1.0、つまり「この硬貨は必ず表が出る」になってしまいます。3回だけで、そこまで言い切るのは言い過ぎでしょう。
そこで、レッスン3のベイズの定理のように、「硬貨はだいたい公平だろう」という 事前の考え(事前確率) も合わせて使います。ここでは簡単に、表と裏を1回ずつ「見たことにする」仮の観測を足します。
データが少ないときは事前の考えが効いて極端な答えを防ぎ、データが多くなると差はほとんど消えます。事前確率と尤度を掛けた「事後確率」が一番大きくなる値を選ぶ方法を、MAP推定(事後確率最大化推定)と呼びます。
第8章の 正則化 は、MAP推定の一種と見ることができます。「重みは0に近い小さな値だろう」という事前の考えを置くと、事後確率を最大にすることが、「罰 + 重みの大きさへの罰」を最小にすることになるのです。
Pythonで確かめる、よくある誤解と振り返り
負の対数尤度が一番小さい p を探す
import numpy as np
p = np.linspace(0.01, 0.99, 99) # 0.01, 0.02, …, 0.99 の99個の候補
nll = -(7 * np.log(p) + 3 * np.log(1 - p)) / 10 # 1回あたりの負の対数尤度(表7回・裏3回)
print(round(p[nll.argmin()], 2)) # → 0.7
print(nll.min()) # → 0.6108…
np.log は自然対数です(底が2の対数は np.log2)。argmin() は、一番小さい値が何番目にあるかを返します。
scikit-learn の罰が、負の対数尤度であることを確かめる
第9章の乳がんの診断データで、標準化とロジスティック回帰のモデルを作り、テストデータ(171件)で確かめました。
from sklearn.metrics import log_loss
proba = model.predict_proba(X_test) # 各データの、クラス0・1の確率
p_true = proba[np.arange(len(y_test)), y_test] # 各データの「正解のクラスの確率」だけを取り出す
print(log_loss(y_test, proba)) # → 0.0892(scikit-learn の交差エントロピー)
print(-np.log(p_true).mean()) # → 0.0892(正解の確率の −log の平均)
proba[np.arange(len(y_test)), y_test] は、「0番目のデータは y_test[0] 列、1番目のデータは y_test[1] 列、…」のように、行ごとに正解の列の値を1つずつ取り出す書き方です。2つの値は一致しました。scikit-learn の log_loss(交差エントロピー)は、「正解に付けた確率の −log の平均」、つまり1件あたりの負の対数尤度です。
よくある誤解
- 「尤度は、p の確率」: 尤度は「p がその値だとしたら、手元のデータが起こる確率」です。p=0.7 の尤度0.00222は、「p が0.7である確率」ではありません。いろいろな p の尤度を足しても、1にはなりません
- 「対数をとると、答えが変わる」: 対数は、元の数が大きいほど大きくなるので、一番大きくなる場所は変わりません。計算しやすくなるだけです
- 「最尤推定は、いつも正しい答えを出す」: データが少ないと、3回中3回表から「必ず表が出る」と答えるような、極端な答えになります(過学習と同じ問題)。MAP推定や正則化で、これを和らげます
振り返り
- 対数 log は「何回掛けたか」を表す。掛け算を足し算に変えるので、とても小さな確率の掛け算を扱える
- 最尤推定は、手元のデータが一番起こりやすくなる値を選ぶ方法。計算では、負の対数尤度を最小にする
- 分類の交差エントロピーも、回帰の二乗誤差も、最尤推定から出てくる罰。第5章の0.69は log2
- MAP推定は、事前の考えも使って、データが少ないときの極端な答えを防ぐ。正則化はその一種