선형회귀의 경우 예측하고자 하는 타깃변수가 급식량이나 가격과 같이 연속적인 수치였다. 로지스틱 회귀 역시 회귀라는 말이 포함되서 실수형 숫자를 예측하는 것이라 생각할 수도 있지만 로지스틱 회귀는 선형회귀식을 사용하기는 사용하되 연속형 숫자의 예측이 아니라 선을 그어 데이터를 분류하기 위한 알고리즘이다.
그럼, 로지스틱 회귀가 선형회귀식을 이용해 어떻게 데이터를 분류하는 지 알아보도록 하자.
시그모이드(Sigmoid) 함수에 대해 알아보기
우선 로지스틱 회귀에서 사용되는 시그모이드 함수에 대해 알아보자. 시그모이드 함수는 0을 기준으로 양수든 음수든 어떤 수를 집어넣든 그 결과값을 0과 1사이의 확률로 변환시킨다. 아래 시그모이드 함수의 구조를 살펴보자.
시그모이드 함수
시그모이드 함수에 x를 넣으면 밑이 자연상수(약 2.718)인 지수함수의 지수로 사용되어 지수함수값을 만든다. 시그모이드 함수 구조상 x가 양수로 점차 커지면 e^(-x)는 0에 가까워져 결과적으로 시그모이드 함수는 1에 가까워진다.
반대로 x가 음수로 점차 작아지면 e^(-x)는 무한대(inf)에 가까워져 시그모이드 함수는 0에 가까워진다. 넘파이의 np.exp() 함수를 사용하면 밑이 자연상수인 지수함수 값을 계산해 주는 데 아래 예에서 보듯 시그모이드 함수에 -100을 입력하면 np.exp(-(-100)) = np.exp(100))은 2.6881171418161356 곱하기 10의 43승이 되어 결국 시그모이드 함수의 분모가 엄청 켜서서 0에 가까워지는 것이다.
지수함수 결과값
x가 0이 될 때를 np.exp(0)은 1이 되어 시그모이드 함수는 0.5이 되는데, x >0 이면 시그모이드 값은 0.5보다 큰 값이 나오고 x<0이면 0.5보다 작아지게 된다. 이렇게 음의 무한대에서부터 양의 무한대까지 모든 숫자를 확률로 바꿀 수 있음에 따라 시그모이드 함수는 데이터를 분류하는 데 중요한 역할을 하게 된다. 기준을 정의하기 나름이지만 확률(시그모이드 값)이 0.5보다 크거나 같으면 1로 분류하고 0.5보다 작으면 0으로 분류하는 것이다.
로지스틱 회귀는 어떻게 최적의 가중치를 찾을까?
이제 x라는 입력값 대신에 가중치와 편향을 가진 선형 회귀식을 사용해 보자. 선형 회귀 연산에서 나온 결과값을 시그모이드 함수에 통과시켜 0과 1사이의 값으로 변환하는 것이다.
앞에서 이해한 시그모이드 함수의 성질대로라면 wx+b=0 일 때 시그모이드 값이 0.5이 되고 wx+b > 0이면 시그모이드 값은 0.5보다 크고, wx+b < 0 이라면 0.5보다 작은 값이 나온다. 즉, 로지스틱 회귀에서 임의의 가중치와 편차를 가진 직선을 그으면 선을 기준으로 wx+b >= 0인 쪽은 1로 분류될 것이고, wx+b < 0 인 쪽은 0으로 분류될 것이다.
참고로 선형회귀의 w와 b의 값에 따라 시그모이드 함수의 모양도 조금씩 달라지는 것을 볼 수 있다. w(기울기)가 커지면 커질수록 시그모이드 값이 0과 1에 각각 빨리 수렴되는 것을 알 수 있다. 역시 우리가 구해야 할 것은 주어진 데이터를 가장 잘 분류할 수 있는 w와 b를 찾는 것이다. 그렇다면 어떻게 데이터를 가장 잘 분류하기 위한w와 b를 찾을 수 있을까?
선형회귀에서는 평균제곱오차(MSE)를 손실함수로 정의하고 이를 최소화하는 가중치와 편향을 찾았는데 로지스틱 회귀에서 손실은 무엇으로 정의할 수 있을까?
실제값이 1일 때 시그모이드를 통과한 예측 확률값이 1에 가까우면 오차가 작고 0에 가까우면 오차가 커지는 손실함수가 필요하다. 반대로 실제값이 0일 때 예측 확률값이 0에 가까우면 오차가 작고 1에 가까우면 오차가 커져야 한다. 이를 반영하기 위해 로그함수를 손실함수로 정의해 사용하는데 이를 로지스틱 손실함수 또는 이진크로스 엔트로피 함수라고 한다.
아래 로지스틱 손실함수 그래프를 보면 실제값이 1일 때 시그모이드를 통과한 예측 확률값이 1에 가까울 수록 손실이 0에 가까움을 알 수 있다. 실제값이 0이라면 예측 확률값이 1에 가까울수록 손실이 무한대로 커진다.
이진 크로스 엔트로피 함수 그래프 (출처 https://wikidocs.net/165219)
이를 합쳐서 한 번에 나타내면 손실함수는 L=−(ylog(y^)+(1−y)log(1−y^))로 나타낼 수 있다. 여기서 y는 실제 라벨값을 말하고 y^는 시그모이드 함수를 통과한 예측 확률값을 말한다. y=1일 때는 (1-y) 이하 부분이 0이 되어 y가 1일 때의 손실값인 −(ylog(y^)만 계산되고, y=0일 때는 ylog(y^) 부분이 0 되어 y가 0일 때의 손실값인 −(1−y)log(1−y^)만 계산된다.
이제 전체 훈련 데이터에 대해 손실함수값을 더하고 데이터 개수로 나누면 선형회귀의 손실함수인 평균제곱오차(MSE) 와 같은 평균 로그손실값이 나오게 된다.
이진 크로스 엔트로피 방정식 (손실함수)
그렇다면 이 손실함수가 최소가 될 때 가중치를 찾으면 될 것이다. 선형회귀와 마찬가지로 손실함수를 미분해 손실함수 미분값이 0에 가까워지는 지점을 향해 w와 b를 업데이트 해가며 최적의 가중치를 찾는다.
선형회귀에서는 최소자승법, 경사하강법 등으로 손실함수가 최소가 되는 가중치를 찾아갔는데 로지스틱 회귀에서도 역시 경사하강법 등을 이용해 최적의 가중치를 찾아 나간다. 사이킷런에는 로지스틱 회귀를 위한 라이브러리로 LogisticRegresion, SGDClassifier 등이 있는데 LogisticRegresion는 최적화 방법으로 헤시안 행렬, 경사하강법 등을 선택할 수 있다. (solver 인수)
SGDClassifier는 경사하강법으로 로지스틱 회귀, SVM, 퍼셉트론과 같은 분류 알고리즘을 구현할 수 있는 라이브러리인데 loss='log loss'로 사용하면 손실함수로 로그 로스를 선택해 경사하강법으로 로지스틱 회귀를 구현할 수 있다.
다음 글에서는 사이킷런에서 제공하는 붓꽃 데이터셋을 가지고 로지스틱 알고리즘을 적용해 보고 어떻게 결과가 나오는 지 다양하게 결과도 분석해 보자.