kang's study
7일차 : 로지스틱 회귀분석 (분류) 본문
로지스틱 회귀¶
럭키백의 확률¶
데이터 준비하기¶
In [1]:
import pandas as pd
fish = pd.read_csv('https://bit.ly/fish_csv_data')
fish.head()
Out[1]:
In [2]:
print(pd.unique(fish['Species']))
In [3]:
# 데이터 프레임에서 열 선택 : 원하는 열을 리스트로 나열
fish_input = fish[['Weight','Length','Diagonal','Height','Width']].to_numpy()
In [4]:
print(fish_input[:5])
In [5]:
fish_target = fish['Species'].to_numpy()
In [6]:
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)
In [7]:
from sklearn.preprocessing import StandardScaler # 특성마다 스케일이 다른걸 정규화
ss = StandardScaler()
ss.fit(train_input)
train_scaled = ss.transform(train_input)
test_scaled = ss.transform(test_input)
k-최근접 이웃 분류기의 확률 예측¶
In [8]:
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))
In [9]:
print(kn.classes_) # 알파벳 순서로 나옴
In [10]:
print(kn.predict(test_scaled[:5]))
In [11]:
import numpy as np
proba = kn.predict_proba(test_scaled[:5])
print(np.round(proba, decimals=4))
In [12]:
distances, indexes = kn.kneighbors(test_scaled[3:4])
print(train_target[indexes])
최근접 이웃은 가능한 확률이 이웃의 개수에 제한되어있는 한계가 있다.
위처럼 3개의 최근접이웃은 0/3, 1/3, 2/3, 3/3이 전부이다.
로지스틱 회귀 (분류)
분류를 위해 츨력값의 범위를 0~1로 바꿈
시그모이드 함수를 이용해서 로지스틱을 구한다.
시그모이드 함수¶

In [13]:
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()
로지스틱 회귀로 이진 분류 수행하기
도미와 빙어만 분류해보기
In [14]:
char_arr = np.array(['A', 'B', 'C', 'D', 'E'])
print(char_arr[[True, False, True, False, False]])
In [15]:
bream_smelt_indexes = (train_target == 'Bream') | (train_target == 'Smelt') # 불리언 인덱싱
train_bream_smelt = train_scaled[bream_smelt_indexes] # bream, smelt만 뽑힘
target_bream_smelt = train_target[bream_smelt_indexes]
In [16]:
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()
lr.fit(train_bream_smelt, target_bream_smelt)
Out[16]:
In [17]:
print(lr.predict(train_bream_smelt[:5]))
In [18]:
print(lr.predict_proba(train_bream_smelt[:5])) # 첫열 음성, 두번째열 양성
In [19]:
print(lr.classes_)
# 알파벳 순서로 레이블 됨 0 bream 1 smelt
# 음성클래스(0): 도미, 양성클래스(1) : 빙어
In [20]:
# 모델이 학습한 계수 확인
print(lr.coef_, lr.intercept_) # 무게, 길이 , 대각선, 높이, 두께
로지스틱 회귀 모델이 학습한 방정식
z = -0.404 × (weight) -0.576 × (length) -0.663 × (diagonal) -1.013 × (height) -0.732 × (width) -2.161
In [21]:
# 처음5개 샘플의 z값을 출력
# decision_function()메서드는 양성 클래스에 대한 z값을 반환
decisions = lr.decision_function(train_bream_smelt[:5])
print(decisions)
In [22]:
from scipy.special import expit # 시그모이드 함수 제공
print(expit(decisions))
# 결과적으로 양성 클래스만 나옴
# 앞선 prob 값이랑 동일, 이진분류는 하나의 함수만 학습해도 나머지는 1에서 빼면됨
로지스틱 회귀로 다중 분류 수행하기¶
In [23]:
lr = LogisticRegression(C=20, max_iter=1000)
# 반복적인 알고리즘을 사용하며 반복횟수 기본 100,
# 릿지 회귀와 같이 계수의 제곱을 규제한다 (L2규제)
# 규제를 제어하는 매개변수 C는 alpha와 반대로 작을수록 규제가 큼 default=1
lr.fit(train_scaled, train_target)
print(lr.score(train_scaled, train_target))
print(lr.score(test_scaled, test_target))
In [24]:
print(lr.predict(test_scaled[:5]))
In [25]:
proba = lr.predict_proba(test_scaled[:5]) # softmax함수가 이용된다.
print(np.round(proba, decimals=3))
In [26]:
print(lr.classes_)
In [27]:
print(lr.coef_.shape, lr.intercept_.shape)
# 다중 분류는 클래스마다 z값을 하나씩 계산한다.
# 7개의 클래스 마다 선형함수가 1개씩 만들어짐 (이진분류 하나 양성 나머지 음성)
In [28]:
decision = lr.decision_function(test_scaled[:5])
# 이진 분류 여러 번 실행 z값 7개 출력
print(np.round(decision, decimals=2))
# 7개의 시그모이드의 합이 1이 되게 출력하려면 새로운 함수가 필요하다
In [29]:
from scipy.special import softmax # 다중분류의 z값 확률을 표현
proba = softmax(decision, axis=1) # 각 샘플에 대한 소프트맥스
print(np.round(proba, decimals=3))
출처 : 박해선, 『혼자공부하는머신러닝+딥러닝』, 한빛미디어(2021), p176-196
'[학습 공간] > [혼공머신러닝]' 카테고리의 다른 글
9일차 : 결정트리 (Decision tree) (0) | 2022.03.03 |
---|---|
8일차 : 확률적 경사 하강법 (Stochastic Gradient Descent) (0) | 2022.03.03 |
6일차 ② : 다중회귀_규제 (0) | 2022.03.02 |
6일차 ② : 다중회귀_규제 (0) | 2022.03.02 |
6일차 ① : 다중회귀_특성공학 (0) | 2022.03.02 |
Comments