로지스틱(이중 분류) 회귀 시뮬레이션

Logistic Regression Visualization & Simulation

로지스틱 회귀(Logistic Regression)는 이진 분류(binary classification) 문제를 풀기 위한 확률적 모델이에요.

예를 들어, 기온이 높을수록 사람들이 바캉스를 갈 확률이 높다고 해볼게요.
과거 데이터를 보면, 20도 이하에서는 대부분 집에 있고, 30도 이상에서는 대부분 바캉스를 간다고 합시다.

결국 그래프는 이렇게 생겼습니다. 선형 회귀의 아이스크림 예시에선 온도에 따라서 아이스크림이 37개가 팔릴 수도 있고 88개가 팔릴수도 있으니 그래프에 점 분포가 다양했죠.

하지만 바캉스는 가거나 안가거나 둘 중 하나이지 37만큼 간다는 개념은 없기 때문에 y축엔 "간다", "안 간다" 밖에 없습니다. 그래서 점이 y=0 또는 y=1만 있는 겁니다. 이런 데이터는 대각선 직선 그래프로 표현할 수가 없습니다.

그래서 우리는 S자와 모양의 "시그모이드"라는 그래프를 이용합니다.

직선보다는 이렇게 자연스러운 곡선을 그려볼게요.

이 그래프를 이용하면 온도에 따라 바캉스를 갈 확률을 계산할 수 있습니다. 이렇게 생긴 모양의 함수가 시그모이드입니다. 이분적인(ex. 0,1) 데이터에 대해서 x값을 기준으로 y값이 0~1로 변하도록 하는 것입니다. 여기서 저 S자를 좁게 모으거나 넓게 퍼뜨릴수록 0과 1이 얼마나 급격하거나 서서히 변할지가 결정됩니다.

예를 들어 특정 기온을 기점으로 바캉스를 간다, 안 간다가 극단적으로 나누어 진다면 파란색 점선처럼 수렴할 것이고, 특정 기온 범위에서 바캉스를 가는지 여부가 사람에 따라서 서서히 바뀐다면 붉은 색 점선처럼 수렴할 것입니다. 시뮬레이션에선 여러분들이 설정한 이분값의 분포에 따라서 S자가 얼마나 벌어지게 되는지 보여드리게 됩니다.

이 시뮬레이터에서는 로지스틱 회귀의 확률적 분류 과정을 직접 체험할 수 있어요 👇
  • 굵은 선 두개 중 아래쪽이 Class 0 (y=0), 위쪽이 Class 1 (y=1)입니다. 아래쪽은 바캉스를 안 가는 사람들, 위쪽은 바캉스를 가는 사람들에 해당합니다.
  • 캔버스의 라인을 클릭해서 포인트를 추가해봅니다. 분류가 이루어지려면 y=0엔 비교적 오른쪽에 점을 많이 찍고, y=1엔 왼쪽에 점을 많이 찍는 식으로 구분을 해야 합니다. "랜덤 포인트" 버튼을 클릭할 수도 있습니다.
  • "학습하기"버튼을 누르면 학습이 이루어지는 모습을 볼 수 있습니다.
  • 학습은 기본적으로 데이터를 아주 빠르게 반복 학습합니다. "학습하기"가 아닌 "한 스텝"을 클릭하면 한번의 계산이 어떤 차이(loss의 변화) 등을 불러오는지 확인할 수 있습니다.
  • 학습이 완료된 상태에서 "검사하기"버튼을 누르면 어떤 입력값이 있을 때 그것이 Class 0 또는 Class 1에 해당하는지 확률을 확인해볼 수 있습니다. 학습된 모델을 사용하는 단계인 것입니다.
즉, 직접 데이터를 찍고 학습시켜서 “기온이 높을수록 바캉스를 갈 확률이 어떻게 올라가는지” 눈으로 확인할 수 있습니다 🎯
x값에 따라 0 또는 1인 2진 분류 모델을 만들어보겠습니다.
굵은 선(y=0, y=1)에 점을 찍어 데이터를 추가해보세요. 위쪽 선은 Class 1, 아래쪽 선은 Class 0에 해당합니다.

Quick Tips
  • 캔버스를 클릭해 데이터 포인트를 추가합니다.
  • 학습하기를 클릭해 시그모이드를 학습시킵니다.
  • 검사하기를 클릭해서 모델을 확인합니다.

How Logistic Regression Works

Logistic Regression은 입력값 \(x\)에 대해 클래스 1일 확률을 모델링하는 확률적 선형 모델입니다. 모델은 선형 결합 \(z = a x + b\) 을 만들고, 그 값을 시그모이드 함수 \(\sigma(z)\)로 변환하여 확률을 얻습니다:

\[ \hat{y} = \sigma(z) = \sigma(ax + b) = \frac{1}{1 + e^{-(ax+b)}} \]

손실 함수 — Binary Cross-Entropy (Log Loss)

예측 확률 \(\hat{y}_i\)와 실제 레이블 \(y_i \in \{0,1\}\)에 대해 한 샘플의 손실은 아래와 같아요. \[ (\ell_i = -\big( y_i \log\hat{y}_i + (1-y_i)\log(1-\hat{y}_i)\big)\) \] 전체 데이터(샘플 수 \(n\))에 대한 평균 손실(목표 함수)은

\[ L(a,b) = -\frac{1}{n}\sum_{i=1}^{n}\Big(y_i\log\hat{y}_i + (1-y_i)\log(1-\hat{y}_i)\Big). \]

경사(Gradient) 유도 — 파라미터 업데이트 법

경사하강법을 위해 파라미터에 대한 편미분을 계산하면 (간단히 표기),

\[ \frac{\partial L}{\partial a} = \frac{1}{n}\sum_{i=1}^n (\hat{y}_i - y_i)\, x_i,\qquad \frac{\partial L}{\partial b} = \frac{1}{n}\sum_{i=1}^n (\hat{y}_i - y_i). \]

따라서 학습률 \(lr\)을 사용한 한 스텝 업데이트는

\[ a \leftarrow a - lr\cdot\frac{\partial L}{\partial a},\qquad b \leftarrow b - lr\cdot\frac{\partial L}{\partial b}. \]

벡터화 표현

입력을 행렬/벡터로 정리하면 더 간결합니다. 행렬 \(X\in\mathbb{R}^{n\times d}\)와 파라미터 벡터 \(\mathbf{w}\) (여기서는 \(d=1\))에 대해 \(\hat{\mathbf{y}}=\sigma(X\mathbf{w}+b)\)이고, 그라디언트는 \(\frac{1}{n}X^\top(\hat{\mathbf{y}}-\mathbf{y})\) 입니다. (코드에서 이 계산을 루프 대신 한 번에 처리하면 효율적입니다.)

수치 안정성 팁
  • \(\log\) 계산 시 \(\log(0)\) 문제를 피하려면 \(\hat{y}\)에 작은 값 \(\epsilon\)을 더하세요: \(\log(\hat{y}+\epsilon)\).
  • 시그모이드 계산에서 큰 음수/양수 입력이 있으면 오버플로우/언더플로우가 발생할 수 있습니다. 필요하면 클리핑하거나 안정화된 수식을 사용하세요.
결정 경계 (Decision boundary)

Logistic Regression의 결정 경계는 \(ax+b=0\) 입니다. 1차원에서는 임계값 \(x^* = -b/a\)로 단순하게 표현됩니다. 즉 \(x>x^*\)이면 \(a>0\)일 때 클래스1 쪽 확률이 커집니다.

학습 방식(SGD·배치)

앞서 선형 회귀 시뮬레이션에선 즉시 계산과 배치 경사하강법, 확률적 경사하강법을 선택할 수 있었습니다. 하지만 로지스틱 회귀에선 즉시 계산을 할 수 있는 계산법이 존재하지 않습니다. 그리고 선형 회귀 시뮬레이션을 해보셨다면 아시겠지만 확률적 경사하강법 보다는 배치 경사하강법이 가장 안정적인 수렴을 이룰 수 있습니다. 로지스틱 회귀 시뮬레이션에선 배치 경사하강법을 통한 시뮬레이션만 보여드립니다.