본문 바로가기
Study/혼자 공부하는 머신러닝 + 딥러닝

[혼자 공부하는 머신러닝 + 딥러닝] 로지스틱 회귀(Logistic regression)

by kimdaepadata 2024. 10. 22.

 

 

오늘은 로지스틱 회귀에 대해서 알아보자.

 

생선이 랜덤으로 들어있는 럭키백이라는 가방이 있다고 가정하자.

이 럭키백에 들어갈 수 있는 생선은 7마리까지이다.

이 럭키백에 들어간 생선의 크기, 무게 등이 주어졌을 때 7개 생선에 대한 확률을 출력해야 한다.

(정확히는 길이, 높이, 두께, 대각선 길이, 무게가 주어진다)

 

이를 위해 로지스틱 회귀를 사용할 것이다.

 

사용하기 전에 로지스틱 회귀에 대해서 알아보자!


로지스틱 회귀는 이름은 회귀이지만 분류 모델이다.

Z = a *(Weight) + b * (Length) + c * (Diagonal) + d * (Height) + e * (width) + f

여기서 a, b, c, d, e는 가중치 혹은 계수이다. 그리고 z는 어떤 값도 가능하다.

하지만 확률이 되려면 z는 0~1(또는 0~100%)사이 값이 되어야 한다.

 

그렇다면 z가 아주 큰 음수일 때 0이 되고, z가 아주 큰 양수일 때 1이 되도록  바꾸는 방법은 없을까?

이는 시그모이드 함수(Sigmoid Function)를 사용하면 가능하다.

 

시그모이드 함수
Python으로 그린 시그모이드 그래프

 

시그모이드 함수는 선형 방정식의 출력 z의 음수를 사용해 자연 상수 e를 거듭제곱하고 1을 더한 값의 역수를 취합니다.

이렇게 복잡하게 계산하면 밑의 그래프를 만들 수 있습니다.

z가 무한하게 큰 음수일 경우 이 함수는 0에 가까워지고, z가 무한하게 큰 양수가 될 때는 1에 가까워집니다.

그리고 z가 0이 될 때는 0.5가 됩니다.

이렇게 z의 범위는 0~1 사이 값이 되고, 0~100%까지 확률로도 해석할 수 있게 됩니다.

 

 

여기까지 완료되었다면 사이킷런에 있는 로지스틱 회귀 모델인 LogisticRegression 클래스를
사용하여 간단한 이진 분류를 수행해보자!


이진 분류이므로 시그모이드 함수의 출력이 0.5보다 크면 양성 클래스, 0.5보다 작으면 음성 클래스로 판단을 할 것이다.

더보기

여기서 잠깐!

정확히 0.5일 때는 라이브러마다 다르다고 한다.

사이킷런은 0.5일 때 음성 클래스로 판단한다고 한다.

사용할 데이터는 생선 데이터이다.

fish_data의 head()
클래스는 총 7개이다.

 

 

 

이진 분류이기 때문에 클래스는 'Bream', 'Smelt'만 사용할 것이다.

불리언 인덱싱을 활용하여 'Bream'과 'Smelt'에 대한 행만 골라내기

 

 

 

분류된 데이터로 모델을 훈련하여 5개 샘플의 값을 예측해보자.

 

두 번째 샘플을 제외하고는 모두 도미로 예측했다.

 

 

 

이번엔 예측확률을 확인해보자.

predict_proba()는 예측확률을 보여주고 classes_는 클래스 속성을 알려준다.

 

샘플마다 2개의 확률이 출력된 것을 볼 수 있다.

첫 번째 열은 음성 클래스(0)에 대한 확률이고 두 번째 열은 양성 클래스(1)에 대한 확률이다.

이 때, lr.classes_ 결과를 보면 'Bream'이 음성 클래스, 'Smelt'가 양성 클래스임을 알 수 있다.

 

 

 

여기까지 성공적으로 이진 분류를 수행했다!

 

 

 

추가적으로 로지스틱 회귀가 학습한 계수를 확인하자.

 

 

 

이에 따라서 로지스틱 회귀 모델이 학습한 방정식은 다음과 같다!

Z = -0.404 * (Weight) - 0.576 * (Length) - 0.663 * (Diagonal) - 1.013 * (Height) - 0.732 * (width) - 2.161

 

 

 

여기서 LogisticRegression 모델로 Z값도 계산할 수 있다.

처음 5개 샘플 z값을 출력

 

위와 같이 decision_function() 메서드를 사용하여 z값을 출력할 수 있다.

이 Z값을 시그모이드 함수에 통과시키면 확률을 얻을 수 있다.

물론 파이썬 메서드를 사용해서 얻을 것이다.

 

 

 

5개 z값의 확률을 출력

 

파이썬의 scipy 라이브러리에도 시그모이드 함수가 있는데 바로 expit()이다.

이를 사용하면 z값에 대한 확률 값을 얻을 수 있고 이는 predict_proba() 메서드 출력의 값과 같다!

 

 

 

 

여기까지 정리하면

1. 이진 분류를 위해 2개의 생선 샘플 골라내기

2. 이를 사용해 로지스틱 회귀 모델 훈련

3. 이진 분류이므로 predict_proba() 메서드를 사용하여 음성 클래스와 양성 클래스에 대한 확률 출력

4. decision_function() 메서드를 사용하여 양성 클래스에 대한 z값 계산

을 진행했다.

 

이제 이를 바탕으로 7개의 생선을 분류하는 다중 분류 문제를 풀어보자!


LogisticRegression 클래스는 기본적으로 반복적인 알고리즘을 사용합니다.

max_iter 매개변수에서 반복 횟수를 지정하며 기본값은 100인데, 충분히 반복하기 위해 횟수를 1,000으로 늘리도록 하겠습니다.

 

또한 기본적으로 릿지 회귀와 같이 계수의 제곱을 규제합니다. 이런 규제를 L2 규제라고도 부릅니다.

릿지 회귀에서는 alpha 매개변수로 규제의 양을 조절하는데, alpha가 커지면 규제도 커집니다.

LogisticRegression에서 규제를 제어하는 매개변수는 C입니다.
하지만 C는 alpha와 반대로 작을수록 규제가 커집니다.

C의 기본값은 1인데 규제를 조금 온화하기 위해 20으로 늘리도록 하겠습니다.

 

 

이제 모델을 훈련해보자

C = 20, max_iter = 100으로 설정

훈련 세트와 테스트 세트에 대한 점수가 높고 과대적합이나 과소적합은 아닌 것 같습니다.

그럼 테스트 세트의 처음 5개 샘플에 대한 예측과 확률, 클래스 정보를 출력해보자.

 

 

7개 생선에 대한 확률을 계산했으므로 7개의 열이 출력되었습니다.

첫 번째 샘플을 보면 세 번째 열의 확률이 가장 높습니다.

세 번째 열은 Perch이므로 첫 번째 샘플은 Perch를 가장 높은 확률로 예측했습니다.

이런식으로 가장 높은 확률이 예측 클래스가 됩니다.

 

 

그럼 다중 분류인 경우, 선형 방정식은 어떤 모습일까?

다중 분류의 coef와 intercept이다.

 

이 데이터는 5개의 특성을 사용하므로 coef_ 배열의 열은 5개입니다.

그런데 coef_ 행이 7개이고, intercept_ 행도 7개입니다.

이는 클래스마다 z값을 하나씩 계산하는 것입니다.

당연히 가장 높은 z값을 출력하는 클래스가 예측 클래스가 됩니다.

 

그럼 확률은 어떻게 계산한 것일까?

바로 소프트맥스 함수를 사용하여 7개의 z값을 확률로 변환시킵니다.

더보기

여기서 잠깐!

시그모이드 함수는 하나의 선형 방정식의 출력값을 0~1 사이로 압축한다면,

소프트맥스 함수는 여러 개의 선형 방정식의 출력값을 0~1 사이로 압축하고 전체 합이 1이 되도록 만듭니다.

이를 위해 지수 함수를 사용하기 때문에 정규화된 지수 함수라고도 부릅니다.

소프트맥스 함수

 

자, 그러면 이진 분류와 마찬가지로 decision_function() 메서드를 사용하여 z1 ~z7값을 출력해보자.

 

 

 

 

그리고 scipy에는 소프트맥스 함수도 제공이 됩니다.

softmax()함수를 사용하면

axis 매개변수는 소프트맥스를 계산할 축을 지정해준다. axis = 1은 행이다.

 

이 결과는 마찬가지로 proba와 일치하는 것을 알 수 있다.

 

 

출처 : 혼자 공부하는 머신러닝 + 딥러닝

https://product.kyobobook.co.kr/detail/S000001810330

 

다음은 또 다른 머신러닝 알고리즘인 확률적 경사 하강법에 대해 포스팅 하겠습니다.