로지스틱 회귀(Logistic regression) : 선형 방정식을 사용한 분류 알고리즘, 선형회귀와 달리 sigmoid/softmax function을 사용하여 class 확률을 출력 가능
다중 분류 : target class가 2개 이상인 분류
Sigmoid function : 선형방정식의 출력을 0과 1 사이의 값으로 압축하여 이진 분류를 위해 사용
Softmax : 다중 분류에서 여러 선형 방정식의 출력 결과를 정규화하여 합이 1이 되도록 만든다.
import pandas as pd
fish = pd.read_csv('https://bit.ly/fish_csv_data')
fish.head()
print(pd.unique(fish['Species']))
fish_input = fish[['Weight','Length','Diagonal','Height','Width']].to_numpy()
print(fish_input[:5])
unique한 species종류를 확인하고 input data의 양이 많으니 5개만 잘 들어갔나 확인해보자
['Bream' 'Roach' 'Whitefish' 'Parkki' 'Perch' 'Pike' 'Smelt']
[[242. 25.4 30. 11.52 4.02 ]
[290. 26.3 31.2 12.48 4.3056]
[340. 26.5 31.1 12.3778 4.6961]
[363. 29. 33.5 12.73 4.4555]
[430. 29. 34. 12.444 5.134 ]]
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, fish_target, random_state=42)
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_input)
train_scaled = ss.transform(train_input)
test_scaled = ss.transform(test_input)
<< 여기까지 이번 장을 위한 data 준비
이번 장은 주어진 data를 가지고 어느 분류에 해당할 지 확률을 구하는 내용이다.
k-최근접 이웃 분류기의 확률 예측
KNeighborsClassifier로 분류해본다. K를 3으로 두어 주변 3개의 값만 확인하도록 해본다. (단순 비교용)
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))
0.8907563025210085
0.85
print(kn.classes_)
print(kn.predict(test_scaled[:5]))
['Bream' 'Parkki' 'Perch' 'Pike' 'Roach' 'Smelt' 'Whitefish']
['Perch' 'Smelt' 'Pike' 'Perch' 'Perch']
import numpy as np
proba = kn.predict_proba(test_scaled[:5])
print(np.round(proba, decimals=4))
[[0. 0. 1. 0. 0. 0. 0. ]
[0. 0. 0. 0. 0. 1. 0. ]
[0. 0. 0. 1. 0. 0. 0. ]
[0. 0. 0.6667 0. 0.3333 0. 0. ]
[0. 0. 0.6667 0. 0.3333 0. 0. ]]
단순에 주변 3개의 이웃 중에 얼마의 비중으로 들어 있는가를 보여준다.
distances, indexes = kn.kneighbors(test_scaled[3:4])
print(train_target[indexes])
[['Roach' 'Perch' 'Perch']]
로지스틱 회귀
import numpy as np
import matplotlib.pyplot as plt
z = np.arange(-5, 5, 0.1)
phi = 1 / (1 + np.exp(-z))
plt.plot(z, phi)
plt.xlabel('z')
plt.ylabel('phi')
plt.show()
로지스틱 회귀로 이진 분류 수행하기
char_arr = np.array(['A', 'B', 'C', 'D', 'E'])
print(char_arr[[True, False, True, False, False]])
['A' 'C'] <<- True인 값만 표시된다.
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]
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()
lr.fit(train_bream_smelt, target_bream_smelt)
print(lr.predict(train_bream_smelt[:5]))
print(lr.predict_proba(train_bream_smelt[:5]))
['Bream' 'Smelt' 'Bream' 'Bream' 'Bream']
[[0.99759855 0.00240145]
[0.02735183 0.97264817]
[0.99486072 0.00513928]
[0.98584202 0.01415798]
[0.99767269 0.00232731]]
두개의 값으로 예측을 했다. 이 두개의 값이 무엇인지 알아보자
print(lr.classes_)
['Bream' 'Smelt']
5개를 예측했는데 두번째가 Smelt일 것으로 예측(양성 클래스가 Smelt)하였고,
나머지 4개는 Bream으로 예측하였다.
로지스틱 회귀가 학습한 계수를 확인해보자
print(lr.coef_, lr.intercept_)
[[-0.4037798 -0.57620209 -0.66280298 -1.01290277 -0.73168947]] [-2.16155132]
decisions = lr.decision_function(train_bream_smelt[:5])
print(decisions)
[-6.02927744 3.57123907 -5.26568906 -4.24321775 -6.0607117 ]
from scipy.special import expit
print(expit(decisions))
[0.00240145 0.97264817 0.00513928 0.01415798 0.00232731]
로지스틱 회귀로 다중 분류 수행하기
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.9327731092436975
0.925
C는 기본값이 1이며 숫자가 적을수록 규제가 강하다.
max_iter는 기본값이 100이며 충분히 훈련하기 위해 값을 늘려줘야 한다.
print(lr.predict(test_scaled[:5]))
proba = lr.predict_proba(test_scaled[:5])
print(lr.classes_)
print(np.round(proba, decimals=3))
['Perch' 'Smelt' 'Pike' 'Roach' 'Perch']
['Bream' 'Parkki' 'Perch' 'Pike' 'Roach' 'Smelt' 'Whitefish']
[[0. 0.014 0.841 0. 0.136 0.007 0.003]
[0. 0.003 0.044 0. 0.007 0.946 0. ]
[0. 0. 0.034 0.935 0.015 0.016 0. ]
[0.011 0.034 0.306 0.007 0.567 0. .076]
[0. 0. 0.904 0.002 0.089 0.002 0.001]]
생선의 종류가 7가지라 열이 7개
print(lr.coef_.shape, lr.intercept_.shape)
(7, 5) (7,) <<- 선형 방정식
decision = lr.decision_function(test_scaled[:5])
print(np.round(decision, decimals=2))
[[ -6.5 1.03 5.16 -2.73 3.34 0.33 -0.63]
[-10.86 1.93 4.77 -2.4 2.98 7.84 -4.26]
[ -4.34 -6.23 3.17 6.49 2.36 2.42 -3.87]
[ -0.68 0.45 2.65 -1.19 3.26 -5.75 1.26]
[ -6.4 -1.99 5.82 -0.11 3.5 -0.11 -0.71]]
from scipy.special import softmax
proba = softmax(decision, axis=1)
print(np.round(proba, decimals=3))
[[0. 0.014 0.841 0. 0.136 0.007 0.003]
[0. 0.003 0.044 0. 0.007 0.946 0. ]
[0. 0. 0.034 0.935 0.015 0.016 0. ]
[0.011 0.034 0.306 0.007 0.567 0. 0.076]
[0. 0. 0.904 0.002 0.089 0.002 0.001]]
'Programming > Machine Learning' 카테고리의 다른 글
[혼공머신] 05-3 트리의 앙상블 (0) | 2022.02.13 |
---|---|
[혼공머신] 05-2 교차 검증과 그리드 서치 (0) | 2022.02.12 |
[혼공머신] 05-1 결정트리 (0) | 2022.02.06 |
[혼공머신] 04-2 확률적 경사 하강법 (0) | 2022.02.05 |
[혼공머신] 용어 03장 (0) | 2022.02.03 |
[혼공머신] 03-3 특성공학과 규제 (0) | 2022.01.22 |
[혼공머신] 03-2 선형 회귀 (0) | 2022.01.16 |
[혼공머신] 용어 02장 (0) | 2022.01.16 |
[혼공머신] 03-1 k-최근접 이웃회귀 (0) | 2022.01.09 |
[혼공머신] 02-2 데이터 전처리(data preprocessing) (0) | 2022.01.08 |