알파카징징이 알파카징징이 코딩하는 알파카

혼공머_4_1 로지스틱 회귀 알아보기

» writing

혼자공부하는머신러닝+딥러닝 수업을 참고하여 작성하였습니다

4_1_로지스틱 회귀 알아보기

정의


로지스틱 회귀 알아보기

1. 럭키백에 포함된 생선의 확률 구하기
2. 데이터 준비
import pandas as pd

fish = pd.read_csv("http://bit.ly/fish_csv_data")
fish.head()

fish_input = fish[['Weight', 'Length', 'Diagonal', 'Height', 'Width']].to_numpy()
fish_target = fish['Species'].to_numpy()
3. 훈련세트, 데이터 세트 나누기 & 표준화 전처리
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)
4. k-최근접 이웃의 다중분류
from sklearn.neighbors import KNeighborsClassifier

kn = KNeighborsClassifier(n_neighbors = 3)
kn.fit(train_scaled, train_target)

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

proba = kn.predict_proba(test_scaled[:5])
print(np.round(proba, decimals = 4))    # round -> 소수점 첫째 반올림,
                                        # decimals -> 소수점 아래 자릿수 지정

#  [[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.    ]]
5. 로지스틱 회귀
    : 분류 모델, 선형 회귀와 동일하게 선형 방정식 학습한다
    : z = a * (Weight) + b * (Length) + c * (Diagonal)
            + d * (Height) + e * (Width) + f

6. 시그모이드 함수 (sigmoid function) or 로지스틱 함수(logistic function)
    : 선형 방정식의 출력 z의 음수를 사용해 자연 상수 e를 거듭제곱하고
     1을 더한 값의 역수를 취한다
    : z가 아주 큰 음수 일 때 0, 큰 양수 일 때 1 (확률 0~1 사이)
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()

sigmoid function

8. 로지스틱 회귀로 이진 분류 시행하기
    - 불리언 인덱싱 (boolean indexing) : T, F 값 전달하여 행 선택 가능
    - 도미(Bream) 과 빙어 (Smelt) 의 행만 골라 비교
    - 2개의 확률에서 어떤 것이 0, 1 클래스에 대한 확률일까?
    - Bream 도미가 음성, Smelt 빙어가 양성
print(lr.classes_)
['Bream' 'Smelt']

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]))
# ['Bream' 'Smelt' 'Bream' 'Bream' 'Bream']
print(lr.predict_proba(train_bream_smelt[:5]))
# [[0.99759855 0.00240145]
#  [0.02735183 0.97264817]
#  [0.99486072 0.00513928]
#  [0.98584202 0.01415798]
#  [0.99767269 0.00232731]]
9. 로지스틱 회귀 계수 확인
    - decision_fucntion : 양성 클래스에 대한 z 계산
    - expit() : 시그모이드 함수
print(lr.coef_, lr.intercept_)
# [[-0.4037798  -0.57620209 -0.66280298 -1.01290277 -0.73168947]] [-2.16155132]
# z = -0.404 * 무게 -0.576 * 길이 - 0.063 * 대각선 - 0.013 * 높이 - 0.732 * 두께 - 2.161
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]
10. 로지스틱 회귀 (다중분류)
    - Logistic Regression
    : 반복적인 알고리즘
    : max_iter(기본 100) 매개변수 반복횟수 지정 
     릿지회귀 -> 계수의 제곱 규제, alpha 커지면 규제 커짐
                규제 제어하는 C(기본 1), C 작으면 규제 커짐
    - 다중분류는 클래스마다 z 값을 하나씩 계산
    - 가장 높은 z 값을 출력하는 클래스가 예측 클래스
    - 소프트맥스 (softmax) : 7개의 z값을 확률로 변환
                           : 여러 개의 선형방정식 출력값 0~1, 전체 합 1
    - 시그모이드 함수 : 하나의 선형 방정식 출력값 0~1 압축
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
proba = lr.predict_proba(test_scaled[:5])
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]]
print(lr.coef_.shape, lr.intercept_.shape)
# (7, 5) (7,)
11. 소프트맥스 함수
    - softmax 의 axis 는 계산할 축 지정
        (axis = 1 : 각 행, 각 샘플에 대해 계산)
        (지정 안하면 배열 전체 계산)
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]]
# z0 ~ z6

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]]
12. 로지스틱 회귀로 확률 예측
    - 로지스틱 회귀는 0~1 사이로 압축
    - 이진 분류에서는 하나의 선형방정식 훈련
    - 이 방정식의 출력값을 시그모이드 함수에 통과하여 0~1로 만든다
    (값 양성 클래스에 대한 확률, 1-양 = 음성 클래스 확률)
    - 다중 분류일 경우 클래스 개수 만큼 방정식 훈련
    - 출력값을 소프트 맥스 함수로 통과시켜 전체 합 1로 만든다