モデル¶
2クラスの場合¶
2クラス(C1,C2)を識別する線形モデルを考える。
特徴量ベクトルをx=(x1,⋯,xd)⊤、係数ベクトルをw=(w1,⋯,wd)⊤、バイアス項をw0とすれば、
f(x)=w0+w⊤x で表される。
識別境界をf(x)=0として、f(x)=0のときはリジェクトせずにC1とする場合、予測値C^を出力する識別規則は
{C1C2(f(x)≥0)(f(x)<0) となる。
多クラスの場合¶
クラス数がK(>2)個ある場合にはどうすればよいだろうか。
いくつか方法はある(はじパタ 6.1.2などを参照)が、最大識別関数法が現状もっとも良さそう。
これはK個の線形識別関数fj(x) (j=1,2,⋯,K)を用意して、最も出力値が大きいクラスを採用するというもの。
C^=argjmaxfj(x) パラメータの推定¶
最小二乗誤差基準¶
係数ベクトルにバイアスを含めてw=(w0,w1,⋯,wd)⊤とし、特徴量ベクトルをx=(1,x1,⋯,xd)⊤と表記することにする。
それにより、線形識別関数を
f(x)=w⊤x と表記する。
教師ラベルは{+1,−1}で表現されるものとする。
ti={+1−1(xi∈C1)(xi∈C2) ここでiはサンプルの添字でi=1,⋯,Nである。
特徴量を行列X=(x1,⋯,xN)⊤、教師ラベルのベクトルをt=(t1,⋯,tN)⊤と表記する。
二乗誤差E(w)を使って評価すると、次のようになる。
E(w)=i=1∑N(ti−f(xi))2=(t−Xw)⊤(t−Xw)=t⊤t−2t⊤Xw+w⊤X⊤Xw 二乗誤差を最小にするパラメータwはパラメータで微分して0になるパラメータなので、
∂w∂E(w)=−2X⊤t+2X⊤Xw=0 を解くことにより
w^=(X⊤X)−1X⊤t である。
# 2次元に描いた場合
import numpy as np
import matplotlib.pyplot as plt
# このようなデータがあったとする
x_c1 = np.array([
[.50, .55],
[.45, .75],
[.7, .50],
[.7, .75],
])
x_c2 = - x_c1
X = np.append(x_c1, x_c2, axis=0)
y = np.array([1] * x_c1.shape[0] + [-1] * x_c2.shape[0])
def plot_hyperplane(X, y, ax):
# データ点の散布図
is_1 = y == 1
ax.scatter(X[is_1, 0], X[is_1, 1], label="C1", color="orange")
ax.scatter(X[~is_1, 0], X[~is_1, 1], label="C2", color="steelblue")
# # x軸, y軸を描く
# ax.hlines(0, -1, 1, colors="black", linewidth=1)
# ax.vlines(0, -1.1, 1.1, colors="black", linewidth=1)
ax.legend(loc="upper left")
return ax
fig, ax = plt.subplots()
plot_hyperplane(X, y, ax)
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
fig.show()
# 最小二乗法によるパラメータの推定
w = np.linalg.inv(X.T @ X) @ X.T @ y
w
array([0.78271718, 0.82605555])
このパラメータによる識別超平面を描くと次の図のようになる
# 描画範囲
x1 = np.linspace(-1, 1, 100)
# 超平面:x2 = -(w1/w2) * x1の形にする
x2 = -(w[0] / w[1]) * x1
# plot
fig, ax = plt.subplots()
plot_hyperplane(X, y, ax)
ax.plot(x1, x2, color="dimgray", label="f(x)=w'x")
ax.legend(loc="upper left")
fig.show()