반응형

Logistic Regression

Logistic Regression의 원리는 이진분류에서 다뤘다. 하지만, 실제 데이터 분석 시에는 이진 분류보다는 다중 클래스 사이에서 데이터가 어느 클래스에 속하는지를 분류하는 문제가 많다. 사실 다중 분류를 위한 로지스틱 회귀는 이진 분류와 내용 차이가 크게 없지만, 많이 사용하는 만큼 따로 나눠서 소개를 하고 한다. 


다중 Logistic Regression 이란?

  • 3개 이상의 클래스 중, 하나의 클래스에 속하는지를 예측하는 문제이다.
  • 이진 분류와 가장 다른 점은, 이진 분류는 분류 문제의 정답이 '참'일 확률(p)만 고려하여, '참'과 '참이 아님'을 분류하면 되지만, 다중 분류는 여러 가지 클래스 중, 예측 모델이 속할 확률이 가장 높은 클래스를 찾는 문제이다.
  • 즉, 정답이 이진 분류에서는 정답 예측을 한 차원('참'일 확률 p)에서만 끝낼 수 있었지만, 다중 분류의 예측은 클래스의 개수만큼의 예측 결과가 필요하다. 
  • 이러한 다중 분류를 위해 다중 로지스틱 회귀 모델에서는 일반적으로 Softmax 함수를 사용한다. 

※ Softmax 함수
-  K개의 클래스가 있는 다중 분류 문제에서 j번째 softmax 함수 결과는 아래와 같이 나타난다.

 

-  Softmax 함수는 Logistic 함수의 일반화된 형태이다. 
-  Softmax 함수는 각 클래스에 속할 확률(p)을 각 클래스들에 속할 확률들의 합으로 나눠서, 0부터 1 사이로 Normalization 한 형태이다. 
-  일반적으로 Softmax 함숫값이 가장 큰 클래스로 예측 모델의 결과를 낸다. 

 

다중 Logistic Regression의 학습 방법

  • 다중 Logistic Regression의 학습을 위해서도 최대우도방법(MLE, Maximum Likelihood Estimation)을 사용한다.
  • 다중 Logistic Regression의 학습을 위해서, 학습에 사용되는 정답을 One-hot vector 형식으로 나타내야 한다. 
  • 다중 Logistic Regression의 학습을 위해서는 일반적으로 크로스 엔트로피(Cross Entropy) 함수를 사용하여, 목적 함수를 정의한다. 

[크로스 엔트로피]

  • 크로스 엔트로피는 정보 이론에서 사용되는 개념으로, 두 확률 분포가 얼마나 다른지를 측정하는 방법이다. 
  • 크로스 엔트로피 식은 다음과 같다.

p: 실제 확률, q: 예측 확률, n: 분포의 원소 개수

  • 크로스 엔트로피의 그래프를 확인해 보면, 예측 확률 q가 실제 확률 p과 동일한 지점에서 최솟값을 나타냄을 확인할 수 있다. 
  • 즉, 크로스 엔트로피가 최솟값을 가지는 구간이 실제 확률과 가장 비슷한 예측을 하였다고 할 수 있다.
  • 분류 문제에는 종속 변수가 범주형(각 클래스에 속할 확률이 0 or 1)으로 나타나기 때문에(One-Hot vector), 첫 번째 그래프처럼 실제 분포를 정확히 예측하였을 때, '0' 값을 갖는다.

[One-Hot Vector]

  • One-Hot vector는 범주형 데이터를 다루기 위해, 사용되는 벡터 표현 방법이다. 
  • 클래스에 정수형 범주를 붙인다면, 클래스 간의 대소 관계와 순서가 모델의 학습과정에서 고려되어, 숫자형 범주 자체를 '중요도'로 오해하여 학습될 수 있다. 이를 막기 위해 One-Hot vector를 이용하여 정답 레이블을 표시한다.
  • K개의 클래스가 있는 범주형 데이터가 있는 분류 문제에서, 해당 데이터가 실제로 i번째 클래스에  속해있다고 하면, i번째 데이터를 제외한 K-1개 클래스는 0으로, i번째 클래스는 1의 값을 갖는다.
  • One-Hot vector는 해당 클래스에 속할 확률을 나타낸다고 생각할 수 있다. 

[다중 로지스틱 회귀 목적함수]

    • 다중 로지스틱 회귀를 이용한 분류 문제의 목적은 실제 데이터가 속한 클래스와 비슷한 분포를 예측하는 모델을 만드는 것이다.
    • 위의 크로스 엔트로피 식에서 p를 실제 데이터의 분포를 One-Hot vector로 변환한 값, q를 모델이 예측한 분포라고하면, 크로스 엔트로피 값이 최소인 지점이 모델이 실제 데이터를 가장 잘 예측하였을 때라고 생각할 수 있다.
    •  결국 다중 로지스틱 회귀 모델의 학습의 목적은 Softmax 함수의 형태로 구해진 예측 모델의 결과가 실제 정답의 분포에 가장 유사한 형태를 갖도록, 크로스 엔트로피 값을 최소화할 수 있는 모델 파라미터를 찾는 것이다.  

y : 실제 정답 레이블(one-hot vector 형태), K: 클래스 개수, N: 데이터 개수 

  • 다중 로지스틱 회귀 목적함수는 다음과 같다. 

Logistic Regression의 Python 구현

  • 다중 Logistic Regression은 Python의 Sklearn을 이용하여 쉽게 구현 가능하다.
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score


if __name__ == "__main__":
    # 데이터 Load (iris 데이터 사용, X :꽃의 길이와 너비, y: 꽃의 종류, 3개의 class)
    iris = load_iris()
    X = iris.data[:, :2]
    y = iris.target
        
    # 데이터 분할
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=5)

    # 모델 학습
    clf = LogisticRegression(random_state=1)
    clf.fit(X_train, y_train)

    # 모델 예측
    y_pred = clf.predict(X_test)

    # 정확도 계산
    acc = accuracy_score(y_test, y_pred)
    print("Accuracy:", acc)

 

반응형

Logistic Regression

Linear Regression을 통해서, 연속적 값에 대한 출력 변수를 모델링을 할 수 있다. 하지만, 연속 데이터의 예측 문제에서 Linear Regression은 효과적이지만, 연속적인 값을 추측하기 때문에 분류 모델에서는 적합하지 않다. 분류 문제를 푸는 방법에는 여러가지가 있지만, 오늘 알아볼 Logistic Regression에 대한 이해가 필수적이다. 


Logistic Regression 이란?

  • 이진 분류 문제(입력 값을 2가지 유형으로 나누는 문제)에서 사용하는 분류 모델이다. 
  • Linear Regression과 비슷하게, 입력변수와 출력변수 간의 관계를 모델링하는데, Linear Regression과 달리 값의 범위를 제한하기 위해 일반적으로 Sigmoid 함수를 사용한다. (다른 함수를 사용할 수 있지만, 일반적으로 Sigmoid를 사용한다.)
  • Linear Regression은 입력변수와 출력변수의 선형적 관계에 초점을 맞췄다면, Logistic Regression은 Sigmoid 함수를 통해, 0에 가까운지 1에 가까운지를 모델링하는데에 초점을 맞췄다.
  • Sigmoid 함수

-   Sigmoid 함수는 이진 분류를 위해 사용하는 함수로 출력값을 0에서 1 값으로 제한하는데 사용된다.
-   Sigmoid 함수는 입력변수로 구해진 모델링 값을, 중간의 일부 구간을 제외하고, 0이나 1에 매우 가까운 근접 값으로 출력해준다. (아래 그래프를 보면 이해가 쉽다.)
-   Sigmoid 함수는 무엇보다, 모든점에서 미분이 가능하기 때문에, Back Propagation을 통한, Weight와 Bias 업데이트가 가능하다. 즉, 머신러닝 문제에서 활용 가능하다.
-   Sigmoid 함수는 아래 그래프에서 확인 할 수 있듯이, Z 값이 너무 크거나, 작을 때는 Gradient가 0에 가까워 지는 Gradient Vanishing 문제가 있다.  

 

 

  • Logistic Regression에서의 예측 출력값은 다음과 같이 나타난다. 

 

 

[Logistic Regression 식 유도] 

Logistic Regression의 식은 Odds를 Logistic 변환하여 유도된다. 


odds 식 :성공 확률 (y=1)이 실패 확률(y=0)의 몇 배인지 나타내는 식 


odds 식의 logit 변환 수행 (편의상, 성공확률을 p로 표기)

 logit 변환된 odds를 입력변수의 선형 변환 예측하면,


성공확률 p는 다음과 같다.

라하면, 


Logistic 식이 만들어진다.

 

Logistic Regression의 학습 방법

  • 일반적으로 Logistic Regression의 학습을 위해서는 최대우도방법(MLE, Maximum Likelihood Estimation)을 사용한다. (물론, Linear Regression과 같이, 최소제곱법을 사용 가능하지만, 효과적이지 않다.)
  • 최대우도방법은 주어진 파라미터를 통해, 실제 값이 나올 확률을 최대화하는 방향을 따라 학습하도록 하는 알고리즘이다.
  • 보통 학습은 경사하강법을 사용하여 학습된다.

 

[최대우도방법]

  • 최대 우도 방법은 입력변수(x)와 모델 파라미터(θ)가 있을 때, 실제 결과 값(y)가 나오는 Likelihood를 최대화하는 방법이다.   Likelihood 함수는 최대화하는 값을 구하는 것이, 입력 변수에 대한 실제 결과 값을 가장 잘 추론할 수 있는 파라미터를 찾는 것이다. (yi:i번째 Label - 0 or 1, pi: i번째 성공 확률)

  • Likelihood 함수의 최댓값을 그대로 구해도 되지만, 양변에 Log함수를 취하면, (x값에 따라 y값이 증가하므로, log를 취한 최댓값을 찾는 것은, log 취하기 전 값의 최댓값을 찾는 것과 같다. 보통은 학습의 안정성 때문에 활용한다.)

  • 결국, 최대우도방법은 가장 Log Likelihood가 가장 큰 값이 될 수 있는 모델의 파라미터(θ)를 추정하도록 학습하는 방법이다.

[경사하강법]

  • 경사하강법은 함수의 기울기를 이용하여, 함수의 최적값을 찾는 최적화 알고리즘이다. 
  • Logistic Regression에서 경사하강법은 다음과 같이 실행된다.

1. Logistic Regression에서 모델의 파라미터 θ를 학습하는 것은 아래 식을 최대화하는 θ를 찾는 과정이다.

2. 이것은 logistic likelihood에 음수값을 취한 값을 최소화하는  θ를 찾는 것과 같다. 따라서, 목적함수는 다음과 같다.

3. 모델 파라미터  θ를 무작위로 초기화한다.(후에 초기화를 위한 여러 방법도 있지만, 기본적으로 무작위이다.)

4. 목적함수를 최소화하는 방향으로  θ를 업데이트한다. 

5. 특정 Epoch이나, 조건이 될때까지, 4번을 반복한다. 

 

Logistic Regression의 Python 구현

  • Logistic Regression은 Python의 Sklearn을 이용하여 쉽게 구현 가능하다.
  • 특히, classification 문제는 패키지로 쉽게 load 가능한 데이터들이 많다. (구현에서는 iris 사용)
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score


if __name__ == "__main__":
    # 데이터 Load (iris 데이터 사용, X :꽃의 길이와 너비, y: 꽃의 종류, 3개의 class)
    iris = load_iris()
    temp_X = iris.data[:, :2]
    temp_y = iris.target
    
    # 이진분류를 위해, class=0인 데이터들은 제외함
    indices = np.where(temp_y != 0)[0]
    
    X = temp_X[indices]
    y = temp_y[indices]
        
    
    # 데이터 분할
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=5)

    # 모델 학습
    clf = LogisticRegression(random_state=1)
    clf.fit(X_train, y_train)

    # 모델 예측
    y_pred = clf.predict(X_test)

    # 정확도 계산
    acc = accuracy_score(y_test, y_pred)
    print("Accuracy:", acc)

+ Recent posts