Group Study (2024-2025)/Machine Learning 입문

[ML 입문] 3주차 스터디

qorbaexk 2024. 10. 16. 15:14

Chapter 04 다양한 분류 알고리즘

04-1 로지스틱 회귀

럭키백의 확률

  • 도미일 확률
  • 빙어일 확률

K-최근접 이웃 알고리즘 사용

데이터 준비하기

import pandas as pd

fish = pd.read_csv('<https://bit.ly/fish_csv_data>')
fish.head() // 처음 몇개의 행을 출력

fish_input = fish[['Weight', 'Lengh', 'Diagonal', 'Height', 'Width']].to_numpy()
fish_target = fish['Species'].to_numpy()

 

species - 타깃, 그 외 - 특성

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

from sklearn.neighbors import KNeighborsClassifier

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


print(kn.classes_)

print(kn.predict(test_scaled[:5]))

import numpy as np

proba = kn.predict_proba(test_scaled[:5]) // 5개의 샘플을 뽑아 예측
print(np.round(proba, decimals=4))

 

로지스틱 회귀

로지스틱 회귀(logistic regression)

로지스틱 회귀는 이름은 회귀이지만 사실상 분류 모델이다. 이 알고리즘은 선형 회귀와 동일하게 선형 방정식을 학습한다.

해당 예에서는 아래와 같다.

z = a * (Weight) + b * (Length) + c * (Diagonal) + d * (Height) + e * (Width) + f

a,b,c,d,e는 가중치 혹은 계수.


확률로 바꾸기 위해 → 시그모이드 함수(sigmoid function) 또는 로지스틱 함수(logistic fuction)


 

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

불리언 인덱싱(boolean indexing)

넘파이 배열은 True, False 값을 전달하여 행을 선택할 수 있음


# 이진분류를 하기위해 도미와 빙어 가져오기
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]))

print(lr.coef_, lr.intercept_)

decisions = lr.decision_function(train_bream_smelt[:5]) # z값 출력
print(decisions)

from scipy.special import expit # 시그모이드 함수 계산

print(expit(decisions))

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

lr = LogisticRegression(C=20, max_iter=1000)
lr.fit(train_scaled, train_target)

print(lr.score(train_scaled, train_target))
0.9327731092436975
print(lr.score(test_scaled, test_target))
0.925
print(lr.predict(test_scaled[:5]))

proba = lr.predict_proba(test_scaled[:5])
print(np.round(proba, decimals=3))

 

print(lr.classes_)

print(lr.coef_.shape, lr.intercept_.shape)
(7, 5) (7,)
(클래스, 특성에 곱해지는 계수)
# 7개의 z값

소프트맥스(softmax)함수

시그모이드 함수는 하나의 선형 방정식의 출력값을 0~1 사이로 압축. 이와 달리 소프트맥스 함수는 여러 개의 선형 방정식의 출력값을 0~1 사이로 압축하고, 전체 합이 1이 되도록 만든다. 이를 위해 지수함수를 사용하기 때문에 정규화된 지수 함수라고도 부른다.


decision = lr.decision_function(test_scaled[:5])
print(np.round(decision, decimals=2))

from scipy.special import softmax

proba = softmax(decision, axis=1)
print(np.round(proba, decimals=3))

04-2 확률적 경사 하강법

점진적인 학습

확률적 경사 하강법

확률적 경사 하강법

훈련 세트에서 샘플 하나씩 꺼내 손실 함수의 경사를 따라 최적의 모델을 찾는 알고리즘

샘플을 하나씩 사용하지 않고 여러 개를 사용하면 미니배치 경사 하강법이 된다.

한 번에 전체 샘플을 사용하면 배치 경사 하강법이 된다.


손실 함수

손실 함수

손실 함수는 확률적 경사 하강법이 최적화할 대상이다. 대부분의 문제에 잘 맞는 손실 함수가 이미 정의되어 있다. 이진 분류에는 로지스틱 회귀 손실 함수 또는 이진 크로스엔트로피 손실 함수를 사용하고, 다중 분류에는 크로스엔트로피 손실 함수를 사용한다. 회귀 문제에는 평균 절댓값 오차, 평균 제곱 오차 손실 함수를 사용한다.


로지스틱 손실 함수

SGDClassifier

데이터 전처리

import pandas as pd

fish = pd.read_csv('<https://bit.ly/fish_csv_data>')

fish_input = fish[['Weight','Length','Diagonal','Height','Width']].to_numpy()
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)

## SGD Classifier

from sklearn.linear_model import SGDClassifier

sc = SGDClassifier(loss='log', max_iter=10, random_state=42)
sc.fit(train_scaled, train_target)

print(sc.score(train_scaled, train_target))
#0.773109243697479
print(sc.score(test_scaled, test_target))
#0.775
sc.partial_fit(train_scaled, train_target)

print(sc.score(train_scaled, train_target))
print(sc.score(test_scaled, test_target))

에포크와 과대/과소적합

조기 종료 (early stopping)

과대적합이 시작하기 전에 훈련을 멈추는 것


import numpy as np

sc = SGDClassifier(loss='log', random_state=42)

train_score = []
test_score = []

classes = np.unique(train_target)

for _ in range(0, 300):
    sc.partial_fit(train_scaled, train_target, classes=classes)

    train_score.append(sc.score(train_scaled, train_target))
    test_score.append(sc.score(test_scaled, test_target))
    
sc = SGDClassifier(loss = 'log_loss', max_iter = 100, tol = None, random_state = 42)
sc.fit(train_scaled, train_target)

print(sc.score(train_scaled, train_target))
#0.957983193277311

print(sc.score(test_scaled, test_target))
#0.925

참고자료 : '혼자 공부하는 머신러닝 딥러닝' 인프런 강의

혼자 공부하는 머신러닝+딥러닝 강의 | 대시보드 - 인프런 (inflearn.com)

'Group Study (2024-2025) > Machine Learning 입문' 카테고리의 다른 글

[ML 입문] 6주차 스터디  (3) 2024.11.10
[ML 입문] 5주차 스터디  (1) 2024.11.06
[ML 입문] 4주차 스터디  (0) 2024.10.30
[ML 입문] 2주차 스터디  (0) 2024.10.07
[ML 입문] 1주차 스터디  (0) 2024.10.02