モデル¶
目的変数y∈{0,1}の二値分類において、y=1である確率をp、y=0である確率を1−pとする。
ロジスティック回帰(logistic regression) はy=1の確率を表現するモデル
P(y=1∣β)=p=1+exp(−β⊤x)1 である。ここで 1+exp(−z)1 は (−∞,∞) の入力を (0,1)の範囲にする関数で、 (ロジスティック)シグモイド関数 という。
また、ロジスティック回帰はオッズ比の対数を線形モデルで説明するモデル
log(1−pp)=β⊤x ともいえる。
モデル表現の導出¶
(参考) 2つのモデル表現について
log(1−pp)=β⊤x の両辺の指数をとると
p=1+exp(β⊤x)exp(β⊤x) となり、
1+exp(β⊤x)exp(β⊤x)=1+exp(−β⊤x)1 であるため、2つのモデル表現が同値である。
Undefined control sequence: \b at position 37: …}{1-p} &= \exp(\̲b̲{\beta}^\top \b…
\begin{align}
\frac{p}{1-p} &= \exp(\b{\beta}^\top \b{x})\\
\implies
p &= \exp(\b{\beta}^\top \b{x}) (1-p)\\
&= \exp(\b{\beta}^\top \b{x}) - p \exp(\b{\beta}^\top \b{x})
\end{align}両辺をpで割ると
Undefined control sequence: \b at position 26: …gn}
1 &= \exp(\̲b̲{\beta}^\top \b…
\begin{align}
1 &= \exp(\b{\beta}^\top \b{x}) \frac{1}{p} - \exp(\b{\beta}^\top \b{x})\\
1 + \exp(\b{\beta}^\top \b{x}) &= \exp(\b{\beta}^\top \b{x}) \frac{1}{p}\\
\implies p &= \frac{ \exp(\b{\beta}^\top \b{x}) }{ 1 + \exp(\b{\beta}^\top \b{x}) }
\end{align}
1+exp(z)exp(z)=1+exp(−z)1 については、分子・分母にexp(z)を掛けると
(1+exp(z))/exp(z)exp(z)/exp(z)=(1+exp(z))/exp(z)1 であり、分母部分 (1+exp(z))/exp(z) については
exp(z)1+exp(z)=exp(z)1+exp(z)exp(z)=exp(−z)+1 となる。
※exp(z)1=exp(−z)については、 exp(z)1 は exp(z) と乗じると 1 になるため、指数法則 en⋅em=enm より、 exp(−z) となる
誤差関数¶
ロジスティック回帰は、統計学的な言い方だと最尤推定法でパラメータを推定する。
機械学習的な言い方をすると交差エントロピー誤差を最小化するようにパラメータを推定する。
ベルヌーイ分布¶
ロジスティック回帰はP(y=1)=p,P(y=0)=1−pのベルヌーイ分布に従う。
P(y)={p1−pif y=1if y=0 この確率質量関数は一括で書くと
P(Y=y)=py(1−p)1−y と書くことができる。
尤度関数¶
尤度関数L(θ)とは一般に確率(密度/質量)関数f(x∣θ)の積
L(θ)=i=1∏nf(xi∣θ) である(独立に得られたサンプルを仮定するので単純な積が同時確率を意味する)。
そのため、ベルヌーイ分布の尤度関数は
L(p)=i=1∏npyi(1−p)1−yi となる。
ロジスティック回帰で使う場合、p∈[0,1]はロジスティック回帰の予測値pi=σ(β⊤xi)、y∈{0,1}は実測値である。
L(β)=i=1∏npiyi(1−pi)1−yi 確率の積だとすごく小さい値になって計算が大変なので、通常は対数を取った対数尤度を使う。
ℓ(β)=lnL(β)=i=1∑n[yilnpi+(1−yi)ln(1−pi)] 交差エントロピー誤差¶
ベルヌーイ分布の対数尤度関数の符号を負に反転させたものを交差エントロピー誤差(cross entropy loss)という。log lossやlogistic lossとも呼ばれる
L(β)=−ℓ(β)=−i=1∑n{yilnpi+(1−yi)ln(1−pi)} 単に言葉の問題だが、統計学系の分野では「対数尤度の最大化(最尤推定法)」という言い方をして、機械学習では「交差エントロピー誤差(=負の対数尤度)の最小化」とか言う。やってることは同じ。
# 対数尤度
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def log_likelihood(X, y, beta):
p = sigmoid(X @ beta)
c = 0.0001
p = np.clip(p, a_min=c, a_max=1 - c) # log(p), log(1-p)でゼロをいれないようにする
return np.sum(y * np.log(p) + (1 - y) * np.log(1 - p))
2次元の特徴量からなる、次のようなデータがあるとする
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
# データ生成
X, y = make_blobs(n_samples=300, n_features=2, centers=2, cluster_std=1.7, random_state=42)
# プロット
fig, ax = plt.subplots(figsize=(4, 3))
ax.scatter(X[y == 0, 0], X[y == 0, 1], s=20, label="y = 0")
ax.scatter(X[y == 1, 0], X[y == 1, 1], s=20, label="y = 1")
ax.legend()
ax.set(xlim=(X[:, 0].min()-1, X[:, 0].max()+1), ylim=(X[:, 1].min()-1, X[:, 1].max()+1))
ax.set(xlabel="x1", ylabel="x2")
plt.show()
さまざまなβ1,β2の値のもとでの対数尤度を計算すると次のような等高線になる
# 対数尤度のplot
import matplotlib.pyplot as plt
# --- βのグリッド ---
beta_range = np.linspace(-50, 50, 100)
B1, B2 = np.meshgrid(beta_range, beta_range)
# --- 尤度を格子上で計算 ---
LL = np.zeros_like(B1)
for i in range(B1.shape[0]):
for j in range(B1.shape[1]):
beta = np.array([B1[i, j], B2[i, j]])
LL[i, j] = log_likelihood(X, y, beta)
# --- contour plot ---
fig, ax = plt.subplots(figsize=(4, 4))
cs = ax.contour(B1, B2, LL, levels=10)
ax.clabel(cs)
ax.set_xlabel(r"$\beta_1$")
ax.set_ylabel(r"$\beta_2$")
ax.set_title("Log-likelihood contour")
plt.show()
/tmp/ipykernel_40358/1805774186.py:5: RuntimeWarning: overflow encountered in exp
return 1 / (1 + np.exp(-x))
from scipy.optimize import minimize
beta0 = np.zeros(X.shape[1])
res = minimize(
fun=lambda beta: -log_likelihood(X, y, beta), # minimizeの関数なので負にする
x0=beta0,
method="BFGS",
options={"gtol": 1e-6, "maxiter": 1000},
)
beta_hat = res.x
print("success:", res.success)
print("message:", res.message)
print("beta_hat:", beta_hat)
print("max loglik:", -res.fun)
success: True
message: Optimization terminated successfully.
beta_hat: [ 41.07515312 -13.2522211 ]
max loglik: -0.0300015001000042
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
b1, b2 = beta_hat
# --- 散布図 ---
fig, ax = plt.subplots(figsize=(4, 3))
ax.scatter(X[y == 0, 0], X[y == 0, 1], s=20, label="y = 0")
ax.scatter(X[y == 1, 0], X[y == 1, 1], s=20, label="y = 1")
ax.legend()
ax.set(xlim=(X[:, 0].min()-1, X[:, 0].max()+1), ylim=(X[:, 1].min()-1, X[:, 1].max()+1))
# --- 識別境界 ---
x1 = np.linspace(X[:, 0].min(), X[:, 0].max(), 100)
eps = 1e-12
if abs(b2) > eps:
# 切片なしモデルだと識別境界は b1*x1 + b2*x2 = 0 → x2 = - (b1/b2) * x1
x2 = -(b1 / b2) * x1
ax.plot(x1, x2, linewidth=2)
else:
# β2 = 0 → 垂直線 β1 x1 = 0
ax.axvline(0.0, linewidth=2)
ax.set(xlabel="x1", ylabel="x2", title="Decision boundary")
plt.show()
交差エントロピーの勾配は
∇L(β)=∂β∂L(β)=i=1∑n(pi−yi)xi
総和を取るまえの1レコード単位のものを使う。
ℓ(β)=ylnσ(β⊤x)+(1−y)ln(1−σ(β⊤x)) \sに関する微分
Undefined control sequence: \s at position 27: …n}
\frac{d \ln \̲s̲}{d \beta}
&= \…
\begin{align}
\frac{d \ln \s}{d \beta}
&= \frac{d \ln \s}{d \s} \frac{d \s}{d (\beta^\top x)} \frac{d (\beta^\top x)}{d \beta}\\
&= \frac{1}{\s} \cdot \s (1 - \s) \cdot x\\
&= 1 - \s x
\\
\frac{d \ln (1 -\s)}{d \beta}
&= \frac{d \ln (1 -\s)}{d \s} \frac{d \s}{d (\beta^\top x)} \frac{d (\beta^\top x)}{d \beta}\\
&= -\frac{1}{1-\s} \cdot \s (1 - \s) \cdot x\\
&= - \s x
\end{align}より、
Undefined control sequence: \s at position 54: …eta}
&= y (1 - \̲s̲)x - (1 - y) \s…
\begin{align}
\frac{d \ell(\beta)}{d\beta}
&= y (1 - \s)x - (1 - y) \s x\\
&= (y - y\s - \s + y\s) x\\
&= (y - \s ) x\\
\end{align}(参考)使った微分
dxdlogxdxdσ(x)dxdσ(β⊤x)=x1=σ(x)(1−σ(x))=d(β⊤x)dσ(β⊤x)×dxd(β⊤x)=σ(β⊤x)(1−σ(β⊤x))×x from sklearn.datasets import load_breast_cancer
X, y = load_breast_cancer(return_X_y=True)
y∈{−1,1}にする場合¶
上記の例ではy∈{0,1}としていた。y∈{−1,1}とする場合は少し書き方が変わる
y=1の確率とy=−1の確率がそれぞれ
p(y=1∣x)p(y=−1∣x)=1+exp(β⊤x)exp(β⊤x)=1+exp(−β⊤x)1=1−p(y=1∣x)=1+exp(β⊤x)1+exp(β⊤x)−1+exp(β⊤x)exp(β⊤x)=1+exp(β⊤x)1 で表されるとする。y∈{−1,1}のとき、これらを1つにまとめて、yの確率を
p(y∣x)=1+exp(−yβ⊤x)1 と書くことができる。
尤度は
i=1∏n1+exp(−yiβ⊤xi)1 負の対数尤度は
i=1∑nlog(1+exp(−yiβ⊤xi)) と書くことができる。機械学習の分野だとこちらの表現のほうが目にするかも。
線形分離可能性¶
機械学習として(目的変数の予測が目的)のロジスティック回帰では、線形分離可能な問題であることが嬉しい
統計学としては最尤推定量が存在しない(解が一意に定まらない)という扱いになる様子