개요

지난 글에서 선형회귀를 정리했다. 직선 하나로 숫자를 예측하고, 계수를 읽어 관계까지 해석하는 방법이었다.

이번엔 문제를 바꾼다. “이 고객이 카드값을 연체할까?”처럼 답이 숫자가 아니라 예/아니오인 문제다. 여기에 선형회귀를 그대로 쓰면 왜 안 되는지, 그리고 그걸 어떻게 고친 게 로지스틱회귀인지가 이 글의 내용이다.

미리 못 박아둘 게 하나 있다. 이름에 “회귀”가 붙어 있지만 로지스틱회귀는 분류 모델이다. 이 작명 때문에 초반에 꽤 헷갈렸는데, 이유는 글 중간에 나온다. 속에 선형회귀가 그대로 들어 있어서다.


1. 여기서부터 분류 — 왜 선형회귀로는 안 되나

이제 문제를 바꿔보자. “이 고객이 카드값을 연체할까?” 같은 예/아니오 문제다.

정답이 0(정상) 또는 1(연체)이니, 선형회귀로 0과 1을 예측하면 되지 않을까? 안 된다.

직선과 시그모이드

이유는 그림에 다 있다. 직선은 끝없이 뻗어나간다. 그래서 입력값이 크거나 작으면 예측값이 1을 넘거나 0 아래로 내려간다.

“연체할 확률 137%”, “연체할 확률 −20%”

말이 안 되는 값이다. 확률로 쓸 수가 없다.

다중 분류에서는 더 심각하다

범주가 3개 이상이면 문제가 더 커진다. 날씨를 예측한다고 {1: 맑음, 2: 눈, 3: 비}처럼 숫자를 붙이면,

  • 맑음(1)과 눈(2) 사이 거리 = 1
  • 눈(2)과 비(3) 사이 거리 = 1
  • 그러니까 “맑음과 눈의 차이”와 “눈과 비의 차이”가 같다고 주장하는 셈

게다가 맑음 < 눈 < 비라는 순서까지 암묵적으로 생긴다. 실제로는 아무 순서도 없는데.

범주형 변수에 그냥 번호를 매기는 순간, 의도하지 않은 순서와 거리를 모델에게 가르치게 된다. 이건 개발할 때 열거형(enum)을 int로 캐스팅해 쓰다가 사고 나는 것과 정확히 같은 함정이다.


2. 로지스틱회귀 — S자 곡선으로 눌러 담기

해결책은 우아하다. 직선의 출력을 0과 1 사이로 눌러 담는 함수를 하나 씌우는 것이다. 그게 시그모이드(Sigmoid)다.

        1
S(z) = ─────────
       1 + e⁻ᶻ

말로 옮기면 “어떤 숫자를 넣어도 0과 1 사이 값으로 바꿔주는 함수”다.

z가 S(z)는
아주 큰 양수 1에 한없이 가까워짐
0 정확히 0.5
아주 큰 음수 0에 한없이 가까워짐

중요한 건 0과 1에 절대 도달하지는 않는다는 점이다. 무한히 가까워질 뿐이다. 그래서 로지스틱회귀의 출력 범위는 0과 1을 포함하지 않는 사이값이다. “절대 100% 확신하지 않는다”는 성질인데, 개인적으로 꽤 마음에 들었다.

그래서 로지스틱회귀는 이렇게 만들어진다.

로지스틱회귀 = 선형회귀 + 시그모이드

범주가 3개 이상이면? 시그모이드 대신 소프트맥스를 쓴 다항 로지스틱회귀로 확장한다. 각 범주에 점수를 매긴 뒤 전부 더해서 1이 되도록 나눠주는 방식이라, 위에서 지적한 “번호를 매기면 없던 순서가 생긴다” 문제가 사라진다. 원리는 같으니 이 글에서는 이진 분류만 본다.

선형회귀로 숫자를 하나 뽑고, 그 숫자를 시그모이드에 통과시켜 확률로 바꾼다. 이름에 “회귀”가 붙은 이유가 이거였다. 속에 선형회귀가 그대로 들어 있다.


3. 오즈와 로짓 — 왜 굳이 로그를 씌우나

로지스틱회귀를 설명할 때 반드시 나오는 개념이 오즈로짓이다. 처음엔 “왜 굳이 이런 걸?” 싶었는데, 이유를 알고 나니 납득이 됐다.

확률 오즈 로짓

오즈(Odds)

오즈 = 성공 확률 ÷ 실패 확률

“실패에 비해 성공이 몇 배나 되는가”다. 스포츠 중계에서 “이 팀이 이길 확률 9대 1”이라고 할 때의 그 9대 1이 오즈다.

  • 성공 확률 0.5 → 오즈 = 0.5 ÷ 0.5 = 1 (반반)
  • 성공 확률 0.9 → 오즈 = 0.9 ÷ 0.1 = 9 (성공이 9배 유력)
  • 성공 확률 0.1 → 오즈 = 0.1 ÷ 0.9 = 0.11

확률은 0~1에 갇혀 있지만, 오즈는 0부터 무한대까지 늘어난다. 위쪽 제한이 풀렸다. 확률이 0.999가 되면 오즈는 999, 0.9999면 9999로 끝없이 커진다.

로짓(Logit) = 로그 오즈

문제는 아래쪽이다. 오즈는 아무리 작아져도 0 밑으로는 못 간다. 그래서 로그를 한 번 더 씌운다.

로짓 = log(오즈)

로그는 1보다 작은 수를 음수로 보내는 함수다. 그래서 이 한 방으로 아래쪽 벽도 사라진다.

  • 오즈가 1보다 크면 → 로짓은 양수
  • 오즈가 1이면 → 로짓은 0
  • 오즈가 1보다 작으면 → 로짓은 음수

실제 숫자로 보면 이 변환이 무슨 일을 하는지 한눈에 들어온다.

확률 p 오즈 = p / (1−p) 로짓 = log(오즈)
0.01 0.010 −4.60
0.10 0.111 −2.20
0.25 0.333 −1.10
0.50 1 0
0.75 3 +1.10
0.90 9 +2.20
0.99 99 +4.60

이 표를 보고 두 가지가 눈에 들어왔다.

① 로짓은 0.5를 기준으로 완벽하게 대칭이다. 확률 0.9와 0.1은 로짓에서 +2.20과 −2.20이다. 확률로 보면 0.9와 0.1은 “0.8만큼 차이”지만, 로짓으로 보면 부호만 뒤집힌 같은 크기다. 훨씬 다루기 좋은 형태다.

② 양 끝으로 갈수록 로짓이 급격히 벌어진다. 확률이 0.90에서 0.99로 갈 때, 확률은 0.09밖에 안 늘었는데 로짓은 2.20에서 4.60으로 2배가 됐다. “거의 확실”에서 “진짜 확실”로 가는 게 그만큼 어려운 일이라는 걸 숫자가 반영한다.

이제 −∞부터 +∞까지 전 구간을 쓸 수 있다. 그리고 이게 정확히 직선이 필요로 하는 범위다.

그래서 결론은 확률에 직접 직선을 붙이면 범위가 안 맞아서 터지지만, 로짓으로 바꿔놓으면 직선을 그대로 얹을 수 있다.

즉 로지스틱회귀는 이렇게 두 방향으로 읽을 수 있다.

방향 읽는 법
예측할 때 선형회귀 결과를 시그모이드에 넣어 확률을 만든다
해석할 때 로짓(로그 오즈)이 입력에 대해 직선으로 변한다

같은 걸 뒤집어 본 것뿐이다. 문제를 직접 풀지 않고, 풀기 쉬운 축으로 옮겨서 푸는 발상이다.

이건 데이터 시각화를 정리하면서 만났던 것과 같은 기술이다. 값의 범위가 너무 넓어 그래프가 뭉개질 때 y축을 로그 스케일로 바꾸면 갑자기 읽히는 그림이 되는데, 데이터를 고친 게 아니라 보는 축을 바꾼 것이다. 로짓 변환도 정확히 그 일을 한다.

해석할 때 주의할 점

이 구조 때문에 계수 해석이 선형회귀보다 까다롭다.

계수가 0.0055라면, 이건 “확률이 0.0055 오른다”가 아니라 “로그 오즈가 0.0055 오른다”는 뜻이다. 로그를 되돌리면 덧셈이 곱셈으로 바뀌므로, 확률 변화는 원래 위치에 따라 달라진다.

로짓이 1 오르면 오즈는 e배(약 2.7배)가 된다. 이게 로지스틱회귀 계수를 읽는 핵심 문장이다.

실제 예시로 따라가 보면 이렇다. 카드 사용액이 1000에서 2000으로 늘었다고 하자.

단계 계산 결과
로짓 증가량 0.0055 × 1000 +5.5
오즈 배율 e^5.5 약 245배
확률 변화 0.006 → 0.586 약 97배

여기서 재밌는 게 하나 보인다. 오즈는 245배가 됐는데 확률은 97배밖에 안 늘었다. 이유는 단순하다. 확률은 1을 넘을 수 없기 때문이다. 0.006에 245를 그대로 곱하면 1.47이 되는데, 그런 확률은 존재할 수 없으니 S자 곡선이 알아서 눌러 담은 것이다.

오즈는 마음껏 커질 수 있고, 확률은 천장이 있다. 그래서 계수를 정직하게 해석하려면 확률이 아니라 오즈 기준으로 말해야 한다.

선형회귀는 “얼마나 더해지는지”를 말하지만, 로지스틱회귀는 “몇 배가 되는지”를 말한다. S자 곡선이니 당연하다. 가운데 구간에서는 조금만 움직여도 확률이 확 변하고, 양 끝에서는 아무리 밀어도 잘 안 변한다.


4. MLE — 계수는 어떻게 정하나

선형회귀에서는 “잔차 제곱합을 최소로”였다. 로지스틱회귀에서는 뭘 최소화하나?

여기서 새로운 개념이 나온다. 우도(Likelihood)다.

우도 = 지금 이 확률 함수가 실제 데이터를 얼마나 잘 설명하는가

이 개념이 이번 강의에서 제일 헷갈렸다. 확률과 뭐가 다른지가 계속 안 잡혔는데, 결국 무엇을 고정하고 무엇을 움직이는지의 차이였다.

  고정된 것 움직이는 것 묻는 것
확률 모델(계수) 결과 “이 모델이 맞다면, 이런 일이 벌어질 확률은?”
우도 결과(데이터) 모델(계수) “이런 일이 실제로 벌어졌는데, 이 모델은 얼마나 그럴듯한가?”

데이터는 이미 일어난 사실이라 못 바꾼다. 바꿀 수 있는 건 모델뿐이다. 그래서 “데이터를 가장 그럴듯하게 설명해주는 모델”을 찾는 것이고, 그 그럴듯함의 척도가 우도다.

숫자로 따라가 보기

말로만 하면 계속 미끄러져서, 작은 예로 직접 계산해봤다. 고객 3명의 실제 결과가 이렇다고 하자. 이건 사실이고 안 바뀐다.

고객 실제  
A 연체함  
B 정상  
C 연체함  

이제 후보 모델 두 개가 각자 연체 확률을 내놓는다.

고객 실제 모델 1이 준 연체 확률 모델 2가 준 연체 확률
A (연체) 1 0.8 0.3
B (정상) 0 0.2 0.6
C (연체) 1 0.7 0.4

우도는 “실제로 일어난 일에 이 모델이 매긴 확률”을 전부 곱한 값이다. 여기서 주의할 게 하나 있다. B는 정상이었으니, B에 대해 봐야 할 값은 연체 확률이 아니라 정상일 확률(1 − 연체 확률)이다.

모델 1의 우도 = 0.8 × (1 − 0.2) × 0.7
              = 0.8 × 0.8 × 0.7 = 0.448

모델 2의 우도 = 0.3 × (1 − 0.6) × 0.4
              = 0.3 × 0.4 × 0.4 = 0.048

모델 1의 우도가 약 9배 크다. 실제로 표를 보면 모델 1은 연체한 사람에게 높은 확률(0.8, 0.7)을, 정상인 사람에게 낮은 확률(0.2)을 줬다. 모델 2는 전부 반대로 찍었다. 계산 결과가 직관과 정확히 일치한다.

그래서 학습이란 이 곱셈 결과가 가장 커지도록 계수를 조정하는 것이고, 이걸 최대우도추정(MLE)이라고 부른다.

  선형회귀 로지스틱회귀
기준 잔차 제곱합(RSS) 우도(Likelihood)
방향 최소화 최대화
덜 빗나가게 더 그럴듯하게

참고로 교차 엔트로피와 사실상 같은 것이다. 지도학습 평가를 정리한 글에서 “정답에 준 확률에 −log를 씌운 벌점”이라고 했는데, 그걸 전부 더한 게 로그우도에 마이너스를 붙인 값이다. 우도를 최대화하는 것 = 교차 엔트로피를 최소화하는 것. 이름만 두 개고 하는 일은 하나였다.

로그를 씌우는 이유 (또 로그다)

우도는 각 데이터의 확률을 전부 곱한 값이라고 했다. 그런데 곱셈이라 실무에서 바로 터진다.

확률은 전부 1보다 작은 수다. 1보다 작은 수를 계속 곱하면 값이 미친 듯이 작아진다.

데이터 3개    : 0.5 × 0.5 × 0.5           = 0.125
데이터 10개   : 0.5를 10번 곱하면          ≈ 0.00098
데이터 2000개 : 0.5를 2000번 곱하면        ≈ 10⁻⁶⁰²

마지막 줄이 문제다. 컴퓨터가 표현할 수 있는 가장 작은 실수보다도 작다. 실제 계산에서는 그냥 0으로 뭉개진다. 0이 되어버리면 어느 모델이 더 나은지 비교 자체가 불가능해진다. 실무에서 말하는 언더플로가 정확히 이 상황이다.

여기에 로그를 씌우면 곱셈이 덧셈으로 바뀐다.

log(a × b) = log a + log b

곱셈 2000번이 덧셈 2000번이 되고, 값도 10⁻⁶⁰² 같은 극단적인 수 대신 −602 정도의 평범한 숫자가 된다. 이제 컴퓨터가 아무 문제 없이 다룬다.

덤으로 미분도 훨씬 쉬워진다. 곱셈을 미분하려면 규칙이 복잡하지만, 덧셈은 항별로 따로 미분해서 더하면 끝이다. 다음 글의 경사 하강법이 이 성질에 기대고 있다.

그래도 답이 같은 이유

여기서 당연히 이런 의문이 든다. “함수를 바꿔놓고 푼 답이 원래 답과 같나?”

답은 같다. 이유는 하나다.

로그는 단조 증가 함수다.순서를 절대 뒤집지 않는다.

우도와 로그우도

A가 B보다 크면, log A도 log B보다 크다. 그러니 가장 큰 값의 위치는 변하지 않는다. 그림에서 두 곡선은 모양이 전혀 다른데 꼭대기의 가로 위치는 같다.

앞의 두 모델로 확인해보면 바로 납득이 된다.

  우도 로그우도
모델 1 0.448 −0.80
모델 2 0.048 −3.04

숫자는 완전히 달라졌지만 여전히 모델 1이 이긴다. (둘 다 음수인 게 어색해 보이는데, 1보다 작은 수에 로그를 씌우면 항상 음수가 나온다. 0에 가까울수록 좋은 것이다.)

더 쉬운 비유로. 키 순서로 줄을 세운 다음 모두를 똑같은 규칙으로 줄여도, 가장 큰 사람은 여전히 가장 크다.

다만 공식으로는 안 풀린다

선형회귀와 결정적으로 다른 점이 여기 있다. 로지스틱회귀에는 닫힌 해가 없다. 공식에 넣어 한 번에 계산할 수가 없다.

그래서 기울기를 보고 조금씩 값을 옮겨가며 반복적으로 찾아간다. 그 방법이 바로 다음 글의 주제인 경사 하강법이다.



정리

  • 분류에 직선을 그대로 쓰면 확률이 0~1 범위를 벗어난다시그모이드로 눌러 담는다
  • 범주에 번호를 매기면 없던 순서와 거리가 생긴다. 범주는 순서 없는 집합이다
  • 로지스틱회귀 = 선형회귀 + 시그모이드. 출력은 0과 1에 닿지 않는 사이값
  • 확률 → 오즈 → 로짓으로 갈수록 범위 제한이 풀린다. 로짓은 0.5를 기준으로 대칭
  • 계수는 오즈의 배율로 읽어야 정확하다. 로짓이 1 오르면 오즈는 e배(약 2.7배)
  • 우도 = 데이터를 고정해두고 모델이 얼마나 그럴듯한지 재는 값. 학습은 이걸 최대화(MLE)
  • 로그를 씌우는 건 언더플로를 피하고 미분을 쉽게 하려는 것. 답은 그대로다
  • 로지스틱회귀에는 닫힌 해가 없다. 값을 조금씩 옮겨가며 찾아야 한다

다음 글에서

다음 글에서는 신경망의 구조를 뜯어보고, 이번 글에서 미뤄둔 “닫힌 해가 없으면 값을 어떻게 찾느냐” — 경사 하강법과 역전파를 정리한다.

한줄 평

  • 어.. 어ㅓㅓ.? ㅓ… 음.. 아하! 의 반복이 지속될 예정이고, 작은 흐름이라도(직관) 읽어가는 걸 추천한다.