Post

[머신러닝] 4-1. 로지스틱 회귀

[머신러닝] 4-1. 로지스틱 회귀

로지스틱 회귀 알고리즘을 배우고 이진 분류 문제에서 클래스 확률을 예측하자

럭키백의 확률

k-최근접 이웃은 주변 이웃을 찾아주니까 이웃의 클래스 비율을 확률이라고 출력하면 되지 않을까?

데이터 준비하기

1
2
3
import pandas as pd
fish=pd.read_csv('https://bit.ly/fish_csv')# csv파일을 데이터 프레임으로 변환
fish.head()#처음 5개 행 출력
1
2
3
print(pd.unique(fish['Species']))

#['Bream','Roach','Whitefish','Parkki','Perch','Pike','Smelt']

species열에서 고유한 값 추출!

1
2
#넘파이 배열로 바꾸어 fish_input에 저장
fish_input=fish[['Weight','Length','Diagonal','Height','Width']].to_numpy()

이제 뭘 할지 알겠지?! 훈련 세트와 테스트 세트로 나누자

머신러닝에서는 기본으로 데이터 세트 2개가 필요하다

1
2
3
4
fish_target=fish['Species'].to_numpy()

from sklearn.model_selection import train_test_split
train_input,test_input, train_target, test_target=train_test_split(fish_input, fush_target, random_state=42)

훈련 세트와 테스트 세트를 표준화 전처리도 해야지

1
2
3
4
5
from sklearn.preprocessing import StandardScaler
ss=StandardScaler()
ss.fit(train_input)
train_scaled=ss.transform(train_input)
test_scaled=ss.transform(test_input)

k-최근접 이웃 분류기의 확률 예측

1
2
3
4
5
from sklearn.neighbors import KNeighborsClassifier
kn=KNeighborsClassifier(n_neighbors=3)
kn.fit(train_scaled, train_target)
print(kn.score(train_scaled, train_target))
print(kn.score(test_scaled, test_target))

fish 데이터 프레임에 7개의 생선이 있었다. 타깃 데이터 만들 때 fish[‘Species’]를 사용했으니 훈련 세트와 테스트 세트의 타깃 데이터에 7개의 생선 종류가 들어가 있다! 타깃 데이터에 2개 이상 클래스니까 이것은 다중분류

이진 분류 사용했을 때는 양성 클래스와 음성 클래스를 각각 1과 0으로 지정하여 타깃 데이터를 만들었다. 다중 분류에서 타깃 값을 숫자로 바꾸어 입력할 수 있지만 사이킷런에서는 편하게 문자열을 사용할 수 있다

하나 주의할 것! 순서가 자동으로 알파벳 순으로 매겨진다! 그래서 우리가 위에서 본 순서랑 다르다. 정렬된 것은

1
2
print(kn.classes_)
#['Bream','Parkki','Perch','Pike','Roach','Smelt','Whitefish']

이렇게 확인할 수 있다!

이제 predict_proba()로 클래스별 확률을 확인해보자
round()는 기본으로 소수점 첫째 자리에서 반올림한다. decimals 매개변수로 유지할 소수점 아래 자릿수를 지정할 수 있다

1
2
3
import numpy as np
proba=kn.predict_proba(test_scaled[:5])
print(np.round(proba, dicimals=4))# 소수점 네 번째 자리까지 표기! 다섯번째 자리에서 반올림

alt

최근접 이웃도 확인해보자

1
2
3
4
fistances,indexes=kn.kneighbors(test_scaled[3:4])
print(train_target[indexes])

#[['Roach','Perch','Perch']]

kneighbors()메서드 입력은 2차원 배열이어야 한다. 넘파이 배열의 슬라이싱을 사용하면된다. 슬라이싱은 하나 샘플만 선택해도 항상 2차원 배열이 만들어진다!

Roach 1개, Perch 2개 그래서어 2/3=0.6667!, 1/3=0.333!

앞에서 본 수랑 같다 굳!

그런데 잠시만 3개 최근접 이웃 사용하니까 0/3, 1/3, 2/3, 3/3 확률만 가능하겠네. 만족할 수 없다! 다시 찾자

로지스틱 회귀

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

선형 회귀와 동일하게 선형 방정식을 학습한다

alt

z는 어떤 값도 가능하다. 하지만 확률이 되려면 0에서 1사이 값이 돼야 한다

z가 아주 큰 음수일때 0, z가 아주 큰 양수일 때 1이 되도록 바꾸는 방법이 뭘까?

시그모이드함수(로지스틱 함수)를 사용하면 가능하지!

alt

z가 무한하게 큰 음수일 때는 0! 무한하게 큰 양수일 때는 1!
z가 0일 때는? 0.5!
0과 1을 벗어날 수 없다!!
그러면 0~100%까지 확률로 해석할 수 있겠네! 굳

1
2
3
4
5
6
7
8
9
10
import numpy as np
import matplotlib.pyplot as plt

#-5와 5사이에 0.1간격으로 배열 z만들기
z=np.arange(-5,5,0.1)

#z위치마다 시그모이드 함수 계산하기
phi=1/(1+np.exp(-z))
plt.plot(z,phi)
plt.show()

alt

이진 분류일 경우 시그모이드 함수의 출력이 0.5보다 크면 양성 클래스, 0.5보다 작으면 음성 클래스

0.5일때는? 사이킷런에서는 음성클래스

로지스틱 회귀로 이진 분류 수행하기

불리언 인덱싱 True, False값을 전달하여 행을 선택할 수 있다

도미(bream)이랑 방어(smelt)만 뽑아내야지!

1
2
3
bream_smelt_indexes=(train_target=='Bream')|(train_target=='Smelt')
train_bream_smelt=train_scaled[bream_smelt_indexes]
target_bream_smelt=train_target[bream_smelt_indexes]

z값을 시그모이드 함수에 통과시키면 확률을 얻을 수 있다. 파이썬에서는 expit()!

1
2
form scipy.special import expit
print(expit(decisions))

이진 분류를 위해 생선 샘플을 골라냈고 로지스틱 회귀 모델도 훈련했다!
이진 분류일 경우 predict_proba()메서드는 음성 클래스와 양성 클래스에 대한 확률을 출력한다.
dicision_function()메서드는 양성 클래스에 대한 z값을 계산한다
coef_속성과 intercept_속성에는 로지스틱 모델이 학습한 선형 방정식의 계수가 들어 있다

여기까지 이진 분류를 위한 로지스틱 회귀 모델 훈련이었습니다!

로지스틱 회귀로 다중 분류 수행하기

이제 다중 분류도 해봐야겠다

LogisticRegression클래스는 기본적으로 반복 알고리즘을 사용한다. max_iter매개 변수에서 반복획수를 지정한다.
또한 릿지 회귀와 같이 계수의 제곱을 규제한다. L2규제라고 부르고 C가 매개변수이다.

1
2
3
4
5
6
7
lr=LogisticRegression(C=20, max_iter=1000)
lr.fit(train_scaled, train_target)
print(lr.score(train_scaled, train_target))
print(lr.score(test_scaled, test_target))

#0.932
#0.925

이진 분류에서는 시그모이드 함수를 사용해 z를 0과 1 사이의 값으로 변환한다. 다중분류는 이와 달리 소프트맥스함수를 사용해 7개의 z 값을 확률로 변환한다.

소프트맥스 함수는 여러 개의 선형 방정식의 출력 값을 0에서 1사이로 압축하고 전체 합이 1이 되도록 만든다. 이를 위해 지수 함수를 사용하기 때문에 정규화된 지수 함수라고도 부른다. {: .prompt-tip }


마무리

키워드

로지스틱 회귀 다중 분류 시그모이드 함수 소프트맥스 함수

핵심 패키지와 함수

scikit-learn

LogisticRegression predict_proba() decision_function()


참고: 혼자 공부하는 머신러닝+딥러닝

This post is licensed under CC BY 4.0 by the author.