"K 최근접 이웃은 주변 이웃을 찾아주니까 이웃의 클래스 비율을 확률이라고 출력하면 되지 않을까?"
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])
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)
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))
print(kn.classes_)
print(kn.predict(test_scaled[:5]))
import numpy as np
proba = kn.predict_proba(test_scaled[:5])
print(np.round(proba, decimals=4))
distances, indexes = kn.kneighbors(test_scaled[3:4])
print(train_target[indexes])
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.classes_)
print(lr.coef_, lr.intercept_)
decisions = lr.decision_function(train_bream_smelt[:5])
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))
print(lr.score(test_scaled, test_target))
print(lr.predict(test_scaled[:5]))
print(lr.predict_proba(test_scaled[:5]))
proba = lr.predict_proba(test_scaled[:5])
print(np.round(proba,decimals=3))
decision = lr.decision_function(test_scaled[:5])
from scipy.special import softmax
proba = softmax(decision, axis=1)
print(np.round(proba,decimals=3))

- 로지스틱 회귀는 선형 방정식을 사용한 분류 알고리즘. 선형 회귀와 달리 시그모이드나 소프트맥스를 사용하여 클래스 확률을 출력
- 다중 분류 : 타깃 클래스가 2개 이상인 분류 문제. 로지스틱 회귀는 다중 분류를 위해 소프트맥스 함수를 사용하여 클래스를 예측.
- 시그모이드 함수 : 선형 방정식의 출력을 0과1 사이의 값으로 압축하며 이진 분류를 위해 사용.
- 소프트맥스 함수 : 다중 분류에서 여러 선형 방정식의 출력 결과를 정규화하여 합이 1이 되도록 만듬.
scikit-learn
- LogisticRegression : 선형 분류 알고리즘인 로지스틱 회귀를 위한 클래스. penalty 매개변수에서 L2규제(릿지 방식)와 L1규제(라쏘 방식)선택 가능. c 매개변수에서 규제의 강도를 제어
- predict_proba() : 예측 확률을 반환. 이진 분류의 경우에는 샘플마다 음성 클래스와 양성 클래스에 대한 확률을 반환. 다중 분류의 경우에는 샘플마다 모든 클래스에 대한 확률을 반환.
- decision_function() : 모델이 학습한 선형 방정식의 출력을 반환
로지스틱 손실함수(logitic loss function) : -log(예측확률)
= 크로스엔트로피 손실함수(cross-entropy loss function)
이진 분류는 로지스틱 손실 함수를 사용하고 다중 분류는 크로스엔트로피 손실 함수를 사용. 회귀에서는 평균 제곱 오차를 많이사용(mean squared error)
표준화 전처리 팁 : 꼭 훈련 세트에서 학습한 통계값으로 테스트 세트도 변환해야함.
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)
from sklearn.linear_model import SGDClassifier
sc = SGDClassifier(loss='log',max_iter=100, tol=None, random_state=42)
sc.fit(train_scaled, train_target)
print(sc.score(test_scaled,test_target))
print(sc.score(train_scaled, train_target))

적은 에포크 횟수 동안에 훈련한 모델은 훈련세트와 테스트 세트에 잘 안맞는 과소적합된 모델일 가능성 높음
많은 에포크 동안 훈련한 모델은 훈련세트에 너무 잘맞아 테스트 세트에는 오히려 점수가 나쁜 과대적합된 모델일 가능성이 높음.
조기종료 : 과대적합이 시작하기 전에 훈련을 멈추는 것
힌지손실(hinge loss) : 서포트 벡터 머신이라 불리는 또다른 머신러닝 알고리즘을 위한 손실 함수
scikit-learn
- SGDClassifier : 확률적 경사 하강법을 사용한 분류 모델을 만듬. loss 매개변수는 확률적 경사 하강법으로 최적화할 손실 함수를 지정. 로지스틱 회귀를 위해서는 'log'로 지정. max_iter 매개변수는 에포크 횟수를 지정
- SGDRegressor : 확률적 경사 하강법을 사용한 회귀모델을 만듬.