어떤 회귀 알고리즘은 분류에서도 사용할 수 있으며, 그 반대의 경우도 있다.
로지스틱 회귀(Logistic Regression)는 샘플이 특정 클래스에 속할 확률을 추정하는 데 널리 사용된다. 추정 확률이 50% 이상이면 모델은 그 샘플이 해당 클래스에 속한다고 예측하며, 그렇지 않으면 클래스에 속하지 않는다고 예측한다. 즉 이진 분류기이다.
# 확률 추정
로지스틱 회귀 모델은 입력 특성의 가중치 합에 편향을 더하여 계산한다. 이때 선형 회귀처럼 바로 결과를 출력하지 않고, 결과값의 로지스틱(Logistic)을 출력한다.
로지스틱 회귀 모델의 확률 추정 벡터 표현식은 다음과 같다.
$$ \hat{p} = h_\theta (\mathrm{x}) = \sigma \big( \theta^T \cdot \mathrm{x} \big) $$
로지스틱($\sigma (\cdot)$ 으로 표시)느 0과 1 사이의 값을 출력하는 시그모이드 함수 이다. 이 함수는 다음과 같이 정의된다.
$$ \sigma (t) = \frac{1}{1 + e^{-t}} $$
위의 그래프에서, $t$ 가 0 이상이면 $\sigma(t)$ 는 0.5 이상이므로 로지스틱 회귀 모델은 1이라고 예측하고, $t$ 가 음수일때 0이라고 예측하는데, 이떄 1은 양성 클래스, 0은 음성 클래스라고 한다.
# 훈련과 비용 함수
로지스틱 회귀 모델의 훈련 목적은 양성 샘플(y=1) 에 대해서는 높은 확률을 추저 하고 음성 샘플(y=0)에 대해서는 낮은 확률을 추정하는 파라미터 벡터 $\theta$를 찾는 것이다. 이를 위한 하나의 훈련 샘플 $\mathrm{x}$ 에 대한 비용 함수는 다음과 같다.
$$ c(\theta) = \begin{cases} -log(\hat{p}) & \quad y =1 \\ -log(1-\hat{p}) & \quad y = 0 \end{cases} $$
위에 나타난 비용 함수는 실제 y = 1 인 양성 샘플을 0에 가까운 확률로 예측할 수록 비용이 크게 증가하며, 1에 가까운 확률로 예측할 수록 비용은 0에 수렴하게 된다. 음성 샘플의 경우도 잘 예측할 수록 비용이 감소하고, 잘못 예측할 수록 비용이 커진다.
전체 훈련 세트에 대한 비용 함수는 모든 훈련 샘플의 비용을 평균한 것이며, 이를 로그 손실(log loss)이라고 한다. 다음은 로지스틱 회귀의 로그 손실을 나타낸 식이다.
$$ J(\theta) = - \frac{1}{m} \sum_{i=1}^{m} \big[ y^{(i)} log \big( \hat{p}^{(i)} \big) + \big(1-y^{(i)} \big) log \big( 1- \hat{p}^{(i)} \big) \big] $$
이 비용함수는 최솟값을 계산하는 알려진 해가 없지만(정규 방정식 같은), 볼록 함수이기에 경사 하강법이 전역 최솟값을 찾는 것을 보장한다. 비용 함수의 $j$ 번째 모델 파라미터 $\theta_j$ 에 대해 편미분한 식은 다음과 같다.
$$ \frac{\partial}{\partial \theta_j} J(\theta) = \frac{1}{m} \sum_{i=1}^{m} (\sigma (\theta^T \cdot \mathrm{x}^{(i)} ) - y^{(i)} ) \chi_j^{(i)} $$
로그 손실을 미분한 결과값을 찾는 아이디어는 StackOverflow 에 잘 나타나 있다.
# 결정 경계
로지스틱 회귀를 이용하여 꽃잎 너비를 기반으로 붓꽃 데이터셋에서 Iris-Versicolor 종을 감지하는 분류기를 만들어 보도록 하자.
from sklearn import datasets
import numpy as np
iris = datasets.load_iris()
list(iris.keys())
# ['data', 'target', 'target_names', 'DESCR', 'feature_names', 'filename']
X = iris['data'][:,3:] # 꽃잎의 너비
y = (iris['target']==2).astype(np.int) # Iris-Versicolor 면 1, 그 외 0
X 는 꽃잎의 너비 데이터이며 y 는 Iris-Versicolor 레이블을 1, 나머지 레이블을 0 으로 지정한 데이터이다. logisticRegression 을 사용해 로지스틱 회귀 모델을 훈련시킬 수 있다.
from sklearn.linear_model import LogisticRegression
log_reg = LogisticRegression(solver='liblinear')
log_reg.fit(X,y)
꽃잎의 너비가 0~3cm 인 꽃을 대상으로 모델의 추정 확률을 계산하고, 그래프로 나타내면 다음과 같다.
X_new = np.linspace(0, 3, 1000).reshape(-1, 1) # 스케일 조정
y_proba = log_reg.predict_proba(X_new) # 예측 값
decision_boundary = X_new[y_proba[:, 1] >= 0.5][0] # 양성 클래스일 확률 0.5 이상
# 그래프 출력
plt.figure(figsize=(8, 3))
plt.plot(X[y==0], y[y==0], "bs") # 음성 클래스
plt.plot(X[y==1], y[y==1], "g^") # 실제 Iris-Verginica 클래스
# 결정 경계 출력
plt.plot([decision_boundary, decision_boundary], [-1, 2], "k:", linewidth=2)
plt.plot(X_new, y_proba[:, 1], "g-", linewidth=2, label="Iris-Virginica")
plt.plot(X_new, y_proba[:, 0], "b--", linewidth=2, label="Not Iris-Virginica")
plt.text(decision_boundary+0.02, 0.15, "decision boundary", fontsize=14, color="k", ha="center")
plt.arrow(decision_boundary, 0.08, -0.3, 0, head_width=0.05, head_length=0.1, fc='b', ec='b')
plt.arrow(decision_boundary, 0.92, 0.3, 0, head_width=0.05, head_length=0.1, fc='g', ec='g')
plt.xlabel("petal width (cm)", fontsize=14)
plt.ylabel("probability", fontsize=14)
plt.legend(loc="center left", fontsize=14)
plt.axis([0, 3, -0.02, 1.02])
plt.show()
실제 Iris-Virginica 샘플은 꽃잎 너비 1.4 ~ 2.5cm 에 분포하고, 다른 샘플은 꽃잎 너비 0.1~1.8cm 에 분포한다. 분류기는 꽃잎 너비 1.6cm 이상인 샘플은 Iris-Virginica 클래스로 예측하며, 그 보다 꽃잎 너비가 작은 샘플은 음성 클래스로 예측하는데, 이때 기준이 되는 1.6cm 근방에서 결정 경계(decision boundary) 가 만들어진다.
다음 포스트에서는 로지스틱 회귀의 마지막 개념으로 소프트맥스 회귀에 대해서 다뤄보려 한다.
'Artificial Intelligence > Machine Learning' 카테고리의 다른 글
핸즈온 머신러닝(6) - 서포트 벡터 머신 1 (1) | 2020.01.27 |
---|---|
핸즈온 머신러닝(5) - 로지스틱 회귀 2 (0) | 2020.01.24 |
핸즈온 머신러닝(5) - 규제가 있는 선형 모델 (0) | 2020.01.24 |
핸즈온 머신러닝(5) - 학습 곡선 (0) | 2020.01.24 |
핸즈온 머신러닝(5) - 다항 회귀 (0) | 2020.01.23 |
댓글