본문 바로가기
Machine-Learning/Basic

[ML] Logistic Regression

by AteN 2021. 3. 17.

로지스틱 회귀 (Logistic Regression)

만약 우리가 해결해야 하는 문제가 분류 문제라면 어떻게 해야 할까?

답은 선형 모델에 있다. 단조 미분 가능 함수 하나만 찾아내어 분류 문제의 실제 레이블 y와 선형 회귀 모델의 예측 값을 연결해 주기만 하면 된다.

 

결괏값이  \(y \in {{0, 1}}\) 인 이진 분류 문제를 생각해 보자 

선형 회귀 모델이 생성한 예측 값 \( z= w^Tx + b \)는 실수 이다. 따라서 실수 \(z\) 를 0/1값으로 변환해 줘야 한다. 

이때, 가장 이상적인 방법은 단위 계단 함수 (unit-step function)을 활용하는 것이다

 

$$ \left\{\begin{matrix}
 0, & z < 0; \\ 
 0.5,& z = 0; \\ 
 1, & z > 0; \\ 
\end{matrix}\right. $$

 

만약 예측값 z가 0보다 크다면 양성값으로, 0보다 작으면 음성값으로 주어진다

예측값이 임곗값인 0이면 임의로 판별한다.

하지만 위의 그림에서 볼수 있듯이, 단위 계단 함수는 불연속적이다. 따라서 \(g^-(\cdot )\)를 직접적으로 사용할 수 없다. 우리는 일정 수준에서 단위 계단 함수와 근사한 대체 함수 (surrogate function)를 찾고 싶어 한다. 그리고 이 함수는 단조 미분이 가능해야 한다. 이 경우 로지스틱 함수 (logistic function)가 자주 쓰이는 대체 함수이다 

$$ y=\frac{1}{1 + e^{-z}}$$

그림에서 볼 수 있듯이 로지스틱 함수는 일종의 시그모이드 함수 (sigmoid function)이다. 이 함수는 z값을 0이나 1에 근사한 y값으로 전환하고, 아웃풋이 z=0 근처에서 급격하게 변화한다. 로지스틱 함수를 \(g^-(\cdot )\)로 대입하여 다음의 식을 얻을 수 있다 

$$y=\frac{1}{1 + e^{-(w^{T}x + b)}}$$

위의 식과 비슷하게 다음의 식으로 바꿀 수 있다

$$\ln\frac{y}{{1} - {y}}={w^{T}x + b}$$

만약 y를 샘플 x 가 양성값일 가능성을 본다면 1 - y는 반대로 음성값일 가능성이 된다. 이 둘의 비굣 값은 다음과 같은 식으로 나타낼 수 있으며, 이를 오즈 (odds)라고 부른다 

$$\frac{y}{1 - y}$$

 

오즈는 x가 양성값일 상대적 가능성을 나타낸다. 오즈에 대해서 로그를 취하면 로그 오즈 (log odds)라고 부르고 로짓(logit)이라고 부른다 

$$ln \frac{y}{1 - y} $$

위 식에서 알수 있는 것은 사실상 선형 회귀 모델의 예측 결괏값을 사용하여 실제 데이터의 로그 오즈에 근사한다는 것이다. 따라서 이러한 모델을 로지스틱 회귀 (logistic regression) 또는 로짓 회귀 (logit regression)라고 부른다. 여기서 주의해야 할 점은 명칭은 회귀이지만, 사실상 일종의 분류 학습법이라는 것이다. 이러한 방법은 많은 장점을 가지고 있다. 예를 들면, 이러한 모델은 분류 가능성에 대해 직접적으로 모델을 만들고 사전 데이터 분포에 대한 가정이 필요하지 않다. 이는 가설 분포가 부정확해서 일으킬 수 있는 문제들을 피할 수 있게 해준다. 그리고 로지스틱 회귀 '클래스'를 예측할 뿐 아니라 근사확률에 대한 예측도 할 수 있다. 이는 확률을 통해 의사 결정을 도와야 하는 상황에서 큰 도움이 된다. 

이외에도 로지스틱 회귀가 구하고자 하는 해의 목표 함수는 어떤 단계에서든 구할 수 있는 컨벡스(볼록) 함수 convex function라는 점이다. 이는 수학적으로 매우 좋은 성질이다. 현재 존재하는 많은 수치 최적화 알고리즘 모두 최적해 (optimum solution)를 구하는데 사용할 수 있기 때문이다 

 

로지스틱 회귀(Logistic Regression) 실습

from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import precision_score
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
 
# 데이터 불러오기
raw_cancer = datasets.load_breast_cancer()
 
# 피쳐, 타겟 데이터 지정
X = raw_cancer.data   # 피터 데이터
y = raw_cancer.target # 타깃 데이터 
# 트레이닝/테스트 데이터 분할
X_tn, X_te, y_tn, y_te=train_test_split(X,y,random_state=0)
 
#데이터 표준화
std_scale = StandardScaler()
std_scale.fit(X_tn)
X_tn_std = std_scale.transform(X_tn)
X_te_std  = std_scale.transform(X_te)
 
# 데이터 학습 
# 로지스틱 회귀분석(L2 제약식 적용)
# penalty 옵션을 사용해 제약식 종류를 정할 수 있다 
# penalty='l1' penalty='l2' penalty='elasticnet'
clf_logi_l2 =  LogisticRegression(penalty='l2')
clf_logi_l2.fit(X_tn_std, y_tn)
 
LogisticRegression()
 
# 로지스틱 회귀분석 모형(L2 제약식 적용) 추정 계수
print(clf_logi_l2.coef_)
print(clf_logi_l2.intercept_)
[[-0.29792942 -0.58056355 -0.3109406  -0.377129   -0.11984232  0.42855478
  -0.71131106 -0.85371164 -0.46688191  0.11762548 -1.38262136  0.0899184
  -0.94778563 -0.94686238  0.18575731  0.99305313  0.11090349 -0.3458275
   0.20290919  0.80470317 -0.91626377 -0.91726667 -0.8159834  -0.86539197
  -0.45539191  0.10347391 -0.83009341 -0.98445173 -0.5920036  -0.61086989]]
[0.02713751]
 
# 예측
pred_logistic = clf_logi_l2.predict(X_te_std)
print(pred_logistic)
[0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 0 0 0 0 1 1 0 1 1 0 1 0 1 0 1 0 1 0 1
 0 1 0 0 1 0 1 1 0 1 1 1 0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 0 1 0 0 0 1 1 0 1 0
 0 1 1 1 1 1 0 0 0 1 0 1 1 1 0 0 1 0 0 0 1 1 0 1 1 1 1 1 1 1 0 1 0 1 1 1 1
 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 0 0 0 1 1 1 0]
 
# 확률값으로 예측 (클래스 확률로 예측)
pred_proba = clf_logi_l2.predict_proba(X_te_std)
print(pred_proba)
[[9.98638613e-01 1.36138656e-03]
 [3.95544804e-02 9.60445520e-01]
 ....
 [1.26424968e-03 9.98735750e-01]
 [9.99999994e-01 5.81805301e-09]]
# 정밀도
precision = precision_score(y_te, pred_logistic)
print(precision)
0.9666666666666667
 
# confusion matrix 확인 
conf_matrix = confusion_matrix(y_te, pred_logistic)
print(conf_matrix)
[[50  3]
 [ 3 87]]
 
# 분류 레포트 확인
class_report = classification_report(y_te, pred_logistic)
print(class_report)
              precision    recall  f1-score   support

           0       0.94      0.94      0.94        53
           1       0.97      0.97      0.97        90

    accuracy                           0.96       143
   macro avg       0.96      0.96      0.96       143
weighted avg       0.96      0.96      0.96       143

'Machine-Learning > Basic' 카테고리의 다른 글

[ML] 회귀 (Regression) 평가 지표  (0) 2021.09.05
[ML] 분류 (Classification)  (0) 2021.09.05
[ML] 회귀(Regression)  (0) 2021.03.15
[ML] 퍼셉트론과 인공신경망  (0) 2021.03.04
[ML] 인공지능(AI) 개요  (0) 2019.12.05

댓글