์ด์ ๊น์ง ์ค๋ช ํ๋ ํผ์ ํธ๋ก ์๊ณ ๋ฆฌ์ฆ์ ๊ฐ๋จํ๊ณ ์ข์ง๋ง ํด๋์ค๊ฐ ์ ํ์ ์ผ๋ก ๊ตฌ๋ถ๋์ง ์์ ๋๋ ์๋ ดํ์ง ์์ต๋๋ค. ๋ฐ๋ผ์, ๋ ๊ฐ๋ ฅํ ์๊ณ ๋ฆฌ์ฆ ๋ก์ง์คํฑ ํ๊ท๋ฅผ ์ค๋ช ํ๋ ค๊ณ ํฉ๋๋ค. ์ด๋ฆ์ ํ๊ท์ง๋ง ์ฌ์ค์ ๋ถ๋ฅ ์๊ณ ๋ฆฌ์ฆ์์ ์์ง๋ง์ธ์!
1. ๋ก์ง์คํฑ ํ๊ท์ ์ดํด์ ์กฐ๊ฑด๋ถ ํ๋ฅ
๋จผ์ , ์ค์ฆ๋น(odds ratio)๋ฅผ ์๊ฐํ๋๋ก ํ๊ฒ ์ต๋๋ค. ์ค์ฆ๋ ํน์ ํ ์ํฉ์ด ๋ฐ์ํ ํ๋ฅ ๋ก, ๊ทธ๋ฆผ 1๊ณผ ๊ฐ์ ์์์ ๊ฐ์ต๋๋ค. ์ฌ๊ธฐ์ P๋ ์์ธกํ ๋์, ์์ฑ ์ํ์ ์๋ฏธํฉ๋๋ค. ์ฌ๊ธฐ์ ๋ก๊ทธ ํจ์๋ฅผ ์ทจํ๋ฉด ๋ก์ง(logit)ํจ์๊ฐ ๋ฉ๋๋ค.
์ฌ๊ธฐ์์ ๋ก๊ทธ๋ ์์ํ์ จ๋ฏ ์์ฐ๋ก๊ทธ์ ๋๋ค. logitํจ์๋ 0์์ 1์ฌ์ด์ ๊ฐ์ ์ ๋ ฅ๋ฐ์์ ์ค์ ๋ฒ์์ ๊ฐ์ผ๋ก ๋ณํํฉ๋๋ค. ๊ฐ์ค์น w๋ก ํํ๋์๋ ์์ ํจ์๋ฅผ ๊ธฐ์ตํ์๋์? ํน์ฑ ๊ฐ์ค์น ํฉ๊ณผ ๋ก๊ทธ ์ค์ฆ ์ฌ์ด์ ๊ด๊ณ๋ ์๋์ ๊ฐ์ด ์ฐ์ ๋๋ค. ์ฌ๊ธฐ์ P(y=1|x) ๋ ํน์ฑ x๊ฐ ์์ ๋ ์ด ์ํ์ด ํด๋์ค(y) 1์ ์ํ ์กฐ๊ฑด๋ถ ํ๋ฅ ์ ๋๋ค.
ํ์ง๋ง ์ฐ๋ฆฌ๋ ์ด๋ค ์ํ์ด ํน์ ํด๋์ค์ ์ํ ํ๋ฅ ์ ์์ธกํ๋ ๊ฒ์ ๋ฐ๋ผ๋ logit ํจ์๋ฅผ ๊ฑฐ๊พธ๋ก ๋ค์ง์ต๋๋ค. ํ๋ฅ ์ ๋ถ์๋๊น์! ์ด ํจ์๋ฅผ ๋ก์ง์คํฑ ์๊ทธ๋ชจ์ด๋ ํจ์(logistic sigmoid function), ์ค์ฌ์ ์๊ทธ๋ชจ์ด๋ ํจ์(sigmoid function)์ด๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
z๋ ์ต์ข ์ ๋ ฅ, ์ฆ w^Tx๊ฐ ๋ฉ๋๋ค. ์๋ ์ฝ๋๋ ์๊ทธ๋ชจ์ด๋ ํจ์๊ฐ ์ด๋ป๊ฒ ์๊ฒผ๋์ง๋ฅผ ์ง์ ๊ทธ๋ ค๋ณด๋ ์ฝ๋๋ก, -7๋ถํฐ 7๊น์ง ๊ทธ๋ ค๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
import matplotlib.pyplot as plt
import numpy as np
def sigmoid(z):
return 1.0 / (1.0 + np.ezp(-z)
z = np.arange(-7, 7, 0.1)
phi_z = sigmoid(z)
plt.plot(z, phi_z)
plt.axvline(0.0, color = 'k')
plt.ylim(-0.1, 1.1)
plt.xlabel('z')
plt.yticks([0.0, 0.5, 1.0])
ax = plt.gca()
ax.yaxis.grid(True)
plt.tight_layout()
plt.show()
์ฝ๋๋ฅผ ์คํํ๋ฉด S์ ํํ์ ์๊ทธ๋ชจ์ด๋ ๊ณก์ ์ ํ์ธํ ์ ์์ต๋๋ค. x์ถ์ ๋ด๋นํ๋ z๊ฐ ๋ฌดํ๋์ ๊ฐ๊น์์ง์๋ก e^(-z)์ ๊ฐ์ ์์์ง๊ธฐ ๋๋ฌธ์ ์๊ทธ๋ชจ์ด๋๋ 1์ ๊ฐ๊น์์ง๋๋ค. ๋น์ทํ๊ฒ z๊ฐ ์์ ๋ฌดํ๋๋ก ๊ฐ๊น์์ง์๋ก e^(-z)์ ๊ฐ์ ์ปค์ง๊ธฐ ๋๋ฌธ์ ์๊ทธ๋ชจ์ด๋๋ 0์ ์๋ ดํ๊ฒ ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์ด ์๊ทธ๋ชจ์ด๋ ํจ์๋ ์ ๋ ฅ์ 0๊ณผ 1 ์ฌ์ด์ ๊ฐ์ผ๋ก ๋ณํํ๊ฒ ๋ฉ๋๋ค.
์ฌ๋ฌ๋ถ ๋ชจ๋ ์์์ ์ธ๊ธํ ์๋ฌ๋ฆฐ์ ๊ธฐ์ตํ์๋์? ๋ก์ง์ฝํฑ ํ๊ท ๋ชจ๋ธ์ ์๋ฌ๋ฆฐ๊ณผ ๋น๊ตํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์ ๊ทธ๋ฆผ์์ ํ์ธํ ์ ์๋ค์ํผ ์๋ฌ๋ฆฐ์ ์ ํ ํ์ฑํ ํจ์๋ฅผ ์ต์ข ์ ๋ ฅ๊ณผ ์๊ณํจ์ ์ฌ์ด์ ์ผ์ง๋ง, ๋ก์ง์คํฑ ํ๊ท๋ ์ ํ ํ์ฑํ ํจ์ ์๋ฆฌ์ ์๊ทธ๋ชจ์ด๋ ํ์ฑํ ํจ์๋ฅผ ์ ์ฉํฉ๋๋ค. ์๊ทธ๋ชจ์ด๋ ํจ์์ ๊ฒฐ๊ณผ๋ก ์ ๋ ฅ์ด ํด๋์ค 1์ ์ํ ์กฐ๊ฑด๋ถ ํ๋ฅ ์ด ์ถ๋ ฅ๋๊ณ , ์ดํ ์ค์ฐจ๊ฐ ๋์๊ฐ ๊ฐ์ค์น๋ฅผ ์ ๋ฐ์ดํธ ํฉ๋๋ค.
์ฌ๊ธฐ์ ์ ๋ ฅ์ด ํด๋์ค 1์ ์ํ ์กฐ๊ฑด๋ถ ํ๋ฅ ์ด โฎ(z) = P(y=1|x;w)๋ก ํด์๋ฉ๋๋ค. ๋ง์ฝ์ ์ด๋ค ์ํ์ด โฎ(z) = 0.3์ด๋ผ๋ฉด ์ํ์ด ํด๋์ค 1์ ์ํ ํ๋ฅ ์ด 30%๋ผ๋ ๋ป์ด์ฃ . ๋ฐ๋๋ก ํด๋์ค 2์ผ ํ๋ฅ ์ 70%๊ฐ ๋์ฃ . ์์ธก ํ๋ฅ ์ธ y hat์ ๋ค์๊ณผ ๊ฐ์ด ์ ๋ฆฌํ ์ ์์ต๋๋ค.
์ด ๋ชจ์์ ์๋ฌ๋ฆฐ์ ์๊ณ ํจ์์์ ํ์ธํ ์ ์๋ ๊ฒ๊ณผ ์ ์ฌํ๋ฉฐ, ์๊ทธ๋ชจ์ด๋ ํจ์ ๊ทธ๋ํ์ ๋์ผํจ์ ํ์ธํ ์ ์์ต๋๋ค.
๋ก์ง์คํฑ ํ๊ท๋ ๋น๊ฐ ์ฌ์ง, ์ค์ง ์์์ง๋ฅผ ์์ธกํ๋ ๊ฒ ๋ฟ๋ง ์๋๋ผ ๋น๊ฐ ์ฌ ํ๋ฅ ์ ์์ธกํด์ผํ๋ ๊ฒฝ์ฐ์๋ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋น์ทํ๊ฒ๋ ํน์ ์ฆ์์ด ์๋ ํ์๊ฐ ํน์ ์ง๋ณ์ ๊ฐ์ง ํ๋ฅ ์ ์์ธกํ๋๋ฐ์๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
3. ๋ก์ง์คํฑ ๋น์ฉ ํจ์์ ๊ฐ์ค์น ํ์ต
์ด์ ๊ฐ์ค์น w์ ํ์ต ๋ฐฉ๋ฒ์ ๋ํด์ ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ์์์ ์ฐ์ธ ์ ๊ณฑ ์ค์ฐจํฉ ํจ์๋ฅผ ๊ธฐ์ตํ์๋์? ์๋์ ๊ฐ์ ํจ์์์ต๋๋ค.
์๋ฌ๋ฆฐ ๋ถ๋ฅ ๋ชจ๋ธ์์๋ ์ด ํจ์๋ฅผ ์ต์ํํ๋ ๊ฐ์ค์น w๋ฅผ ํ์ตํ์ต๋๋ค. ๋ก์ง์คํฑ์ ๊ฒฝ์ฐ์๋ ๋ชจ๋ธ์ ๋ง๋ค ๋ ์ต๋ํํ๋ ค๋ ๊ธฐ๋ฅ L(likelihood)์ ์ ์ํฉ๋๋ค. ๊ณต์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ค์ ์์๋ ๊ฐ๋ฅ๋๊ฐ ๋ฎ์ ๋ ์ผ์ด๋๋ ์ธ๋ํ๋ก๋ฅผ ๋ฏธ์ฐ์ ๋ฐฉ์งํ ์ ์๊ณ , ๊ณ์์ ๊ณฑ์ ๊ณ์์ ํฉ์ผ๋ก ๋ฐ๊ฟ์ธ ์ ์๋ ์์ฐ๋ก๊ทธ๋ฅผ ์ต๋ํํ๋ ๊ฒ์ด ๋ ์ฝ์ต๋๋ค. ์ด ํจ์๋ฅผ ๋ก๊ทธ ๊ฐ๋ฅ๋ ํจ์๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
๊ฒฝ์ฌ ์์น๋ฒ ๊ฐ์ ์ต์ ํ ์๊ณ ๋ฆฌ์ฆ์ ํตํด ๋ก๊ทธ ๊ธฐ๋ฅ๋ ํจ์๋ฅผ ์ต๋ํํ๊ฑฐ๋ ๋ก๊ทธ ๊ธฐ๋ฅ๋ ํจ์๋ฅผ ๋ค์ ๋น์ฉํจ์์ธ J๋ก ํํํด ๊ฒฝ์ฌํ๊ฐ๋ฒ์ ์ด์ฉํด ์ต์ํํ ์๋ ์์ต๋๋ค.
์ด ๋น์ฉํจ์๋ฅผ ์ดํดํ๊ธฐ ์ํด์ ์ํ์ด ํ๋์ผ ๋ ๋น์ฉ์ ๊ณ์ฐํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ์ด ์์ ๋ณด๋ฉด y = 0์ผ ๋ ์ฒซ์งธ ํญ์ด 0์ด ๋๊ณ , y = 1์ผ ๋๋ ๋์งธ ํญ์ด 0์ด ๋ฉ๋๋ค.
๊ฐ๋จํ ์ฝ๋๋ฅผ ํตํด์ ์ํ์ด ํ๋์ธ ๊ฒฝ์ฐ์ โฎ(z) ๊ฐ์ ๋ฐ๋ฅธ ๋ถ๋ฅ ๋น์ฉ์ ๊ทธ๋ ค๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
def cost_1(z):
return - np.log(sigmoid(z))
def cost_0(z):
return - np.log(1 - sigmoid(z))
z = np.arange(-10, 10, 0.1)
phi_z = sigmoid(z)
c1 = [cost_1(x) for x in z]
plt.plot(phi_z, c1, label='J(w) if y=1')
c0 = [cost_0(x) for x in z]
plt.plot(phi_z, c0, linestyle='--', label='J(w) if y=0')
plt.ylim(0.0, 5.1)
plt.xlim([0, 1])
plt.xlabel('$\phi$(z)')
plt.ylabel('J(w)')
plt.legend(loc='best')
plt.tight_layout()
plt.show()
ํด๋์ค 1์ ์ํ ์ํ์ ์ ํํ๊ฒ ์์ธกํ๋ฉด ๋น์ฉ์ด 0์ ์๋ ดํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.(ํ๋์ ์ค์ ) ํด๋์ค 0์ ์ํ ์ํ์ ์ ํํ๊ฒ ์์ธกํ๋ฉด ๋ง์ฐฌ๊ฐ์ง๋ก ๋น์ฉ์ด 0์ ์๋ ดํ๋ ๊ฒ๋ ํ์ธํ ์ ์์ฃ .(๋ ธ๋์ ์ ์ ) ์์ธก์ด ์๋ชป๋๋ฉด ๋น์ฉ์ ๋ฌดํ๋๋ก ๋ฐ์ฐํฉ๋๋ค. ์๋ชป๋ ์์ธก์๋ ๊ทธ์ ๋ฐ๋ฅธ ๋ ํฐ ๋น์ฉ์ด ๋ถ์ฌ๋๋ ๊ฒ์ ๋๋ค.
3. ์๋ฌ๋ฆฐ ๊ตฌํ์ ๋ก์ง์คํฑ ํ๊ท ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๋ฐ๊พธ๊ธฐ
์ ์ธ์ ์์ ๊ตฌํํ ์๋ฌ๋ฆฐ์ ๋ก์ง์คํฑ ํ๊ท ์๊ณ ๋ฆฌ์ฆ์ ์ ์ฉํ๊ธฐ ์ํด์๋ ๋น์ฉํจ์๋ง ๋์ฒดํด์ฃผ๋ฉด ๋ฉ๋๋ค.
์ ๊ทธ๋ฆผ 11์ ๋์จ ๋น์ฉํจ์๋ฅผ ์ฌ์ฌ์ฉํ๋๋ก ํ๊ฒ ์ต๋๋ค. ์ด ํจ์๋ก ์ํฌํฌ๋ง๋ค ํ๋ จ์ํ์ ๋ถ๋ฅํ๋ ๋น์ฉ์ ๊ณ์ฐํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ ํ ํ์ฑํ ํจ์๋ฅผ ์๊ทธ๋ชจ์ด๋ ํจ์๋ก ๋์ฒดํ๊ณ , ์๊ณ ํจ์๊ฐ ํด๋์ค 1๊ณผ -1์ด ์๋ 0๊ณผ 1์ ๋ฐํํ๋๋ก ๋ณ๊ฒฝํ๋ฉด ๋ฉ๋๋ค. ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค.
class LogisticRegressionGD(object):
"""๊ฒฝ์ฌ ํ๊ฐ๋ฒ์ ์ฌ์ฉํ ๋ก์ง์คํฑ ํ๊ท ๋ถ๋ฅ๊ธฐ
๋งค๊ฐ๋ณ์
------------
eta : float
ํ์ต๋ฅ (0.0๊ณผ 1.0 ์ฌ์ด)
n_iter : int
ํ๋ จ ๋ฐ์ดํฐ์
๋ฐ๋ณต ํ์
random_state : int
๊ฐ์ค์น ๋ฌด์์ ์ด๊ธฐํ๋ฅผ ์ํ ๋์ ์์ฑ๊ธฐ ์๋
์์ฑ
-----------
w_ : 1d-array
ํ์ต๋ ๊ฐ์ค์น
cost_ : list
์ํฌํฌ๋ง๋ค ๋์ ๋ ๋ก์ง์คํฑ ๋น์ฉ ํจ์ ๊ฐ
"""
def __init__(self, eta=0.05, n_iter=100, random_state=1):
self.eta = eta
self.n_iter = n_iter
self.random_state = random_state
def fit(self, X, y):
"""ํ๋ จ ๋ฐ์ดํฐ ํ์ต
๋งค๊ฐ๋ณ์
----------
X : {array-like}, shape = [n_samples, n_features]
n_samples ๊ฐ์ ์ํ๊ณผ n_features ๊ฐ์ ํน์ฑ์ผ๋ก ์ด๋ฃจ์ด์ง ํ๋ จ ๋ฐ์ดํฐ
y : array-like, shape = [n_samples]
ํ๊น๊ฐ
๋ฐํ๊ฐ
-------
self : object
"""
rgen = np.random.RandomState(self.random_state)
self.w_ = rgen.normal(loc=0.0, scale=0.01, size=1 + X.shape[1])
self.cost_ = []
for i in range(self.n_iter):
net_input = self.net_input(X)
output = self.activation(net_input)
errors = (y - output)
self.w_[1:] += self.eta * X.T.dot(errors)
self.w_[0] += self.eta * errors.sum()
# ์ค์ฐจ ์ ๊ณฑํฉ ๋์ ๋ก์ง์คํฑ ๋น์ฉ์ ๊ณ์ฐํฉ๋๋ค.
cost = -y.dot(np.log(output)) - ((1 - y).dot(np.log(1 - output)))
self.cost_.append(cost)
return self
def net_input(self, X):
"""์ต์ข
์
๋ ฅ ๊ณ์ฐ"""
return np.dot(X, self.w_[1:]) + self.w_[0]
def activation(self, z):
"""๋ก์ง์คํฑ ์๊ทธ๋ชจ์ด๋ ํ์ฑํ ๊ณ์ฐ"""
return 1. / (1. + np.exp(-np.clip(z, -250, 250)))
def predict(self, X):
"""๋จ์ ๊ณ๋จ ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ํด๋์ค ๋ ์ด๋ธ์ ๋ฐํํฉ๋๋ค"""
return np.where(self.net_input(X) >= 0.0, 1, 0)
# ๋ค์๊ณผ ๋์ผํฉ๋๋ค.
# return np.where(self.activation(self.net_input(X)) >= 0.5, 1, 0)
์ฌ๊ธฐ์ ๊ตฌํ๋ ๋ก์ง์คํฑ ๋ชจ๋ธ์ ์ค์ง ์ด์ง ๋ถ๋ฅ ๋ฌธ์ ์๋ง ์ ์ฉ๊ฐ๋ฅํฉ๋๋ค. ๋ฐ๋ผ์ ๋ค์ค ๋ถ๋ฅ ๋ฌธ์ ์๋ ์ ์ฉํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ํด๋์ค 1๊ณผ 0๋ง์ ๊ฐ๊ณ ์๊ธฐ ๋๋ฌธ์ด์ฃ . ๋ถ๊ฝ ๋ฐ์ดํฐ ๋ ๊ฐ๋ฅผ ๊ฐ์ง๊ณ ๋ก์ง์คํฑ ํ๊ท ๊ตฌํ์ด ์ ๋์๊ฐ๋์ง ํ์ธํ๋๋ก ํ๊ฒ ์ต๋๋ค.
X_train_01_subset = X_train[(y_train == 0) | (y_train == 1)]
y_train_01_subset = y_train[(y_train == 0) | (y_train == 1)]
lrgd = LogisticRegressionGD(eta=0.05, n_iter=1000, random_state=1)
lrgd.fit(X_train_01_subset,
y_train_01_subset)
plot_decision_regions(X=X_train_01_subset,
y=y_train_01_subset,
classifier=lrgd)
plt.xlabel('petal length [standardized]')
plt.ylabel('petal width [standardized]')
plt.legend(loc='upper left')
plt.tight_layout()
plt.show()
4. ์ฌ์ดํท๋ฐ์ ์ด์ฉํ ๋ก์ง์คํฑ ํ๊ท ๋ชจ๋ธ ํ๋ จ
์์์ ์๋ฌ๋ฆฐ๊ณผ ๋ก์ง์คํฑ ํ๊ท์ ์ฐจ์ด์ ์ ๋ํด์ ๊ณต๋ถํ์ผ๋, ์ด๋ฒ์๋ ์ฌ์ดํท๋ฐ์์ ๋ก์ง์คํฑ ํ๊ท๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์๋ณผ๊น์? ์ด๋ฒ์๋ ์ ์ฝ๋์ ๋ค๋ฅด๊ฒ ๋ค์ค ๋ถ๋ฅ๋ ์ง์ํฉ๋๋ค. ์๋ ์ฝ๋์์ sklearn.linear_model.LogisticRegression์ fit ๋ฉ์๋๋ฅผ ํตํด ํ์คํ๋ ํด๋์ค ์ธ ๊ฐ๋ฅผ ๋์์ผ๋ก ๋ชจ๋ธ์ ํ๋ จํ๋๋ก ํ๊ฒ ์ต๋๋ค.
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression(solver='liblinear', multi_class='auto', C=100.0, random_state=1)
lr.fit(X_train_std, y_train)
plot_decision_regions(X_combined_std, y_combined,
classifier=lr, test_idx=range(105, 150))
plt.xlabel('petal length [standardized]')
plt.ylabel('petal width [standardized]')
plt.legend(loc='upper left')
plt.tight_layout()
plt.show()
ํ๋ จ ๋ฐ์ดํฐ ๋ชจ๋ธ์ ํ๋ จํ๊ณ ๊ทธ๋ฆฌ๋ฉด ๊ทธ๋ฆผ 15์ ๊ฐ์ด ๊ฒฐ์ ๊ฒฝ๊ณ๋ฅผ ์ ๋ช ํ๊ฒ ํ์ธํ ์ ์์ต๋๋ค. ์ฌ๋ฌ๋ถ์ ์์ง ์ ์ฝ๋์ 'C' ๋ผ๋ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๋ชจ๋ฅด์๊ฒ ์ง๋ง, ์ด๊ฑด ๋ค์ 5๋ฒ์์ ์ค๋ช ๋๋ฆด ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค. ์ด ๋ฐ๋ก ๋ค์์๋ overfitting๊ณผ ๊ท์ ์ ๋ํด์ ์๊ฐํ๊ฒ ๋ ํ ๋๊น์.
ํ๋ จ ์ํ์ด ์ด๋ค ํด๋์ค์ ์ํ ํ๋ฅ ์ predict_proba ๋ฉ์๋๋ฅผ ์ด์ฉํด์ ์์ธกํ ์ ์์ต๋๋ค.
lr.predict_proba(X_test_std[:3,:])
์ ์ฝ๋๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ ๋ฐฐ์ด์ ๋ฐํํฉ๋๋ค. ์ฒซ ๋ฒ์งธ ํ์ ์ฒซ ๋ฒ์งธ ๋ถ๊ฝ ํด๋์ค์ ์์ ํ๋ฅ ์ด๊ณ , ๋ ๋ฒ์งธ ํ์ ๋ ๋ฒ์งธ ๊ฝ์ ํด๋์ค ์์ ํ๋ฅ ์ ๋ํ๋ ๋๋ค. ๋ชจ๋ ์ด์ ๋ํ๋ฉด ๋น์ฐํ ํ๋ฅ ์ ํฉ์ด๋ฏ๋ก 1์ด ๋๊ฒ ์ฃ ? ์ฒซ ๋ฒ์งธ ํ์์ ๊ฐ์ฅ ํฐ ๊ฐ์ 0.855 ์ ๋์ ๋๋ค. ์ด๊ฒ์ ์ฒซ ๋ฒ์งธ ๊ฝ์ด ํด๋์ค 3์ ์์๋ ํ๋ฅ ์ด 85.5% ๋ผ๋ ๋ป์ ๋๋ค. ์ฌ๊ธฐ์ ์ ์ถํ ์ ์๋ฏ์ด, ๊ฐ ํ์์ ๊ฐ์ฅ ํฐ ๊ฐ์ด ์์ธก ํด๋์ค ๋ ์ด๋ธ์ด ๋ฉ๋๋ค. ๋ํ์ด ํจ์์ธ argmax๋ฅผ ์ฌ์ฉํ๋ฉด ์๋์ ๊ฐ์ต๋๋ค.
lr.predict_proba(X_test_std[:3, :]).argmax(axis=1)
#array([2,0,0])
lr.predict(X_test_std[:3, :])
#array([2,0,0])
lr.predict(X_test_std[0,:].reshape(1, -1))
#array([2])
์คํํ๋ฉด array([2, 0, 0]) ์ด ์ถ๋ ฅ๋ฉ๋๋ค. ๋ ๋ฒ์งธ ์ค๊ณผ ๊ฐ์ด ์กฐ๊ธ ๋ ๊ฐ๋จํ๊ฒ ์ง์ predict ํจ์๋ฅผ ํธ์ถํ์ฌ๋ ๋น ๋ฅด๊ฒ ํ์ธํ ์ ์์ต๋๋ค. ๋ง์ง๋ง์ผ๋ก ์ํ ํ๋์ ํด๋์ค ๋ ์ด๋ธ์ ์์ธกํ ๋ ์ฃผ์ํ ์ ์, ์ฌ์ดํท๋ฐ์ ์ ๋ ฅ ๋ฐ์ดํฐ๋ก 2์ฐจ์ ๋ฐฐ์ด์ ์๊ตฌํ๋ฏ๋ก, ํ๋์ ํ์ 2์ฐจ์ ํฌ๋งท์ผ๋ก ๋ณ๊ฒฝํด์ผํ๋ค๋ ์ ์ ๋๋ค. ์ธ ๋ฒ์งธ ์ค์ฒ๋ผ reshape ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๊ฒ ์๋ก์ด ์ฐจ์์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
5. ๊ท์ ๋ฅผ ์ฌ์ฉํ์ฌ ๊ณผ๋์ ํฉ ํผํ๊ธฐ
๊ณผ๋์ ํฉ์ ์์ ์ธ์ ์์๋ ๋ช ๋ฒ ์ธ๊ธ๋ overfitting์ผ๋ก, ๋จธ์ ๋ฌ๋์์ ์์ฃผ ๋ฐ์ํ๋ ๋ฌธ์ ์ ๋๋ค. ๋ชจ๋ธ์ด ํ๋ จ ๋ฐ์ดํฐ๋ก๋ ์ ๋์ํ์ง๋ง ํ ์คํธ ๋ฐ์ดํฐ์์๋ ์ ํ๋๊ฐ ๋ง์ด ๋จ์ด์ง๋ ํ์์ ๋๋ค. ์ฐ๋ฆฌ๋ ๋ชจ๋ธ์ ๊ณผ๋์ ํฉ๋ ๋ ๋ถ์ฐ์ด ํฌ๋ค๊ณ ๋งํฉ๋๋ค.
๋น์ทํ๊ฒ ๋ชจ๋ธ์ด ๊ณผ์์ ํฉ, ์ฆ underfitting์ผ ๋๋ ์์ต๋๋ค. ํ๋ จ ๋ฐ์ดํฐ์ ์๋ ํจํด์ ๊ฐ์งํ ์ ๋๋ก ๋ชจ๋ธ์ด ๋ณต์กํ์ง ์๋ค๋ ์๋ฏธ์ ๋๋ค. ์๋ ๊ทธ๋ฆผ 16์ ๊ฒฐ์ ๊ฒฝ๊ณ๋ฅผ ํตํด์ ์ฝ๊ฒ ์ค๋ช ํ ์ ์์ต๋๋ค.
๊ทธ๋ฆผ์์ ๋ณผ ์ ์๋ ์ข์ ์ ์ถฉ์ ์ ์ฐพ๋ ํ ๊ฐ์ง ๋ฐฉ๋ฒ์ ๊ท์ (regularization)์ ์ด์ฉํด์ ๋ชจ๋ธ์ ๋ณต์ก๋๋ฅผ ์กฐ์ ํ๋ ๊ฒ์ ๋๋ค. ๊ท์ ๋ ๊ณต์ ์ฑ(collinearity), ์ฆ ํน์ฑ๊ฐ์ ์๊ด๊ด๊ณ๋ฅผ ๋ค๋ฃจ๊ฑฐ๋ ๋ฐ์ดํฐ์ ์ก์์ ์ ๊ฑฐํ๋ ์ ์ฉํ ๋ฐฉ๋ฒ์ ๋๋ค. ๊ณผ๋ํ ๊ฐ์ค์น ๊ฐ์ ์ ํํ๊ธฐ ์ํด์ ์ถ๊ฐ์ ์ธ ์ ๋ณด์ธ ํธํฅ์ ์ฃผ์ ํ๋ ๊ฐ๋ ์ด์ฃ . ๊ฐ์ฅ ๋ง์ด ์ฐ์ด๋ ๊ท์ ๋ L2๊ท์ (๋ค๋ฅธ ๋ง๋ก L2์ถ์ ๋๋ ๊ฐ์ค์น ๊ฐ์ )์ ๋๋ค.
์ด ์์์ ๋๋ค๋ ๊ท์ ํ์ดํผํ๋ผ๋ฏธํฐ๋ฅผ ์๋ฏธํฉ๋๋ค. ๋ก์ง์คํฑ ํ๊ท์์ ๋น์ฉํจ์๋ ๊ท์ ํญ์ ์ถ๊ฐํด์ ์ ์ฉํฉ๋๋ค. ์์ ์๋์ ๊ฐ์ต๋๋ค.
๋๋ค๋ฅผ ์ฌ์ฉํด ๊ฐ์ค์น๋ฅผ ์๊ฒ ์ ์งํ๋ฉด์ ํ๋ จ๋ฐ์ดํฐ์ ๋ง์ถ๋ ์ ๋๋ฅผ ์กฐ์ ํ ์ ์์ต๋๋ค. ๋ถ์์์์ ํ์ธํ ์ ์๋ฏ์ด ๋๋ค๊ฐ์ด ์ฆ๊ฐํ๋ฉด ๊ท์ ์ ๊ฐ๋๋ ๋์์ง์ฃ .
์์์ ๊ถ๊ธํ๋ ๋งค๊ฐ๋ณ์ 'C' ๋ ๊ท์ ํ์ดํผ ํ๋ผ๋ฏธํฐ์ธ ๋๋ค์ ์ญ์์ ๋๋ค. ๋ฐ๋ผ์ C๊ฐ์ ๊ฐ์์ํค๋ฉด ๊ท์ ๊ฐ๋๊ฐ ์ฆ๊ฐํ๋ ๊ฒ์ด์ฃ . ์ด ๊ณผ์ ์์ L2 ๊ท์ ํจ๊ณผ๋ฅผ ๊ทธ๋ํ๋ก ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
weights, params = [], []
for c in np.arange(-5, 5):
lr = LogisticRegression(solver='liblinear', multi_class='auto', C=10.**c, random_state=1)
lr.fit(X_train_std, y_train)
weights.append(lr.coef_[1])
params.append(10.**c)
weights = np.array(weights)
plt.plot(params, weights[:, 0],
label='petal length')
plt.plot(params, weights[:, 1], linestyle='--',
label='petal width')
plt.ylabel('weight coefficient')
plt.xlabel('C')
plt.legend(loc='upper left')
plt.xscale('log')
plt.show()
์ด ์ฝ๋๋ฅผ ํตํด ๊ทธ๋ฆผ 19์ ๊ทธ๋ํ๋ฅผ ๊ทธ๋ฆด ์ ์์ต๋๋ค. ๊ฒฐ๊ณผ ๊ทธ๋ํ์์ ํ์ธํ ์ ์๋ฏ์ด C๊ฐ ๊ฐ์ํ๋ฉด ๊ฐ์ค์น ์ ๋๊ฐ์ด ์ค์ด๋ญ๋๋ค, ์ฆ ๊ท์ ๊ฐ๋๊ฐ ์ฆ๊ฐํ๋ ๊ฒ์ด์ฃ .
์ด๋ฒ ์ธ์ ์์๋ ๋ก์ง์คํฑ ํ๊ท์ ๋ํด์ ์์๋ณด์์ต๋๋ค. ๋์์ ์ค์ํ ๊ฐ๋ ์ธ overfitting, underfitting ๊ทธ๋ฆฌ๊ณ ๊ท์ (regularization)์ ๋ค๋ฃจ์์ต๋๋ค. ๋ก์ง์คํฑ ํ๊ท ์๊ณ ๋ฆฌ์ฆ์ ์ ๊ฐ ์ฒ์ ๋จธ์ ๋ฌ๋์ ์ ํ๋ธ <๋ชจ๋๋ฅผ ์ํ ๋จธ์ ๋ฌ๋>์ผ๋ก ๋ฐฐ์ธ ๋ ๊ทน ์ด๋ฐ์ ๋ฐฐ์ ๋ ๋ด์ฉ์ด๊ธฐ๋ ํ๊ณ , ์ค์ ๋ก๋ ์์ฃผ ์ฐ์ด๋ ๋ชจ๋ธ์ ๋๋ค. ์ ๋ ์๋ฌ๋ฆฐ๊ณผ ํผ์ ํธ๋ก ์ ์ด๋ฒ์ ์ฒ์ ๋ค์ด๋ณธ ๊ฐ๋ ์ด์๋๋ฐ, ๋ก์ง์คํฑ ํ๊ท๋ ์ ๋ช ํด์ ์๊ณ ์์๊ฑฐ๋ ์. ์ ๋ง ๋ง์ด ์ฐ์ด๋ ๋ถ๋ฅ ๋ชจ๋ธ์ ๋ฐฐ์ด ๊ฒ์ ์ถํ๋๋ฆฝ๋๋ค! ๋ค์ ์ธ์ ์์ ์ต๋ ๋ง์ง ๋ถ๋ฅ์ ๋น์ ํ ๋ฌธ์ ๋ฅผ ๋ค๊ณ ์ฐพ์์ค๋๋ก ํ๊ฒ ์ต๋๋ค.