2023. 3. 8. 15:39ㆍ데이터 엔지니어링 과정/python
1. 로지스틱 회귀
💻 데이터 준비
import pandas as pd
fish = pd.read_csv('https://bit.ly/fish_csv_data')
📍 read_csv() : pandas의 CSV 파일을 데이터프레임으로 변환해주는 함수
📌 k-최근접 이웃 분류기의 단점 : 훈련 세트의 범위를 벗어나면, 예측이 불가하다.
# 어떤 종류의 생선 있는지 확인
print(pd.unique(fish['Species']))
>>> ['Bream' 'Roach' 'Whitefish' 'Parkki' 'Perch' 'Pike' 'Smelt']
💻 종류를 제외한 나머지를 훈련 데이터로 넘파이 배열로 생성
fish_input = fish[['Weight', 'Length', 'Diagonal', 'Height', 'Width']].to_numpy()
fish_input[:5]
>>> array([[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()
💻 데이터 세트 2개 생성
# 데이터 세트 2개 만들기
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)
1. k-최근접 이웃 분류기의 확률 예측
💻 사이킷런의 KNeighborsClassifier 클래스 객체 만든 후, 훈련 후 score 확인
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
📌 다중 분류(multi-class classfication): 타깃 데이터에 2개 이상의 클래스가 포함된 문제
📍 classes_ : KNeighborsClassifier에서 정렬된 타깃값을 알파벳 순으로 정렬
print(kn.classes_)
>>> ['Bream' 'Parkki' 'Perch' 'Pike' 'Roach' 'Smelt' 'Whitefish']
💻 test_scaled 5개 데이터 확인 후 예측 종류 확인
test_scaled[:5]
>>> array([[-0.88741352, -0.91804565, -1.03098914, -0.90464451, -0.80762518],
[-1.06924656, -1.50842035, -1.54345461, -1.58849582, -1.93803151],
[-0.54401367, 0.35641402, 0.30663259, -0.8135697 , -0.65388895],
[-0.34698097, -0.23396068, -0.22320459, -0.11905019, -0.12233464],
[-0.68475132, -0.51509149, -0.58801052, -0.8998784 , -0.50124996]])
print(kn.predict(test_scaled[:5]))
>>> ['Perch' 'Smelt' 'Pike' 'Perch' 'Perch']
📍 predict_proba() 메서드 : 클래스별 확률값 반환
📍 round() 함수 : 넘파이의 함수로, 기본적으로 소수점 첫째 자리에서 반올림. decimals 매개변수로 유지할 소수점 아래 자릿수를 지정할 수 있음
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. ]]
2. 로지스틱 회귀
- 이름은 회귀이지만 분류 모델
- 선형 방정식 학습 (선형 회귀와 동일)
- 확률이 되려면 0~1 사이의 값이어야 함
➡ 가장 큰 음수일 때는 0, 가장 큰 양수일 때는 1이 되도록 해야 함
➡시그모이드 함수를 사용하면 가능 (이중분류하려면!! 다중분류를 원하면 소프트맥스를 사용해야 함)
3. 로지스틱 회귀로 이진 분류 수행하기
💻 도미와 빙어에 대한 행 골라내기 feat.불리언 인덱싱
# 도미와 빙어 데이터로 이진분류
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]]
💻 타깃값 확인
print(lr.classes_)
>>> ['Bream' 'Smelt']
🔎 첫 번째 열이 음성 클래스(0)이니까, Smelt(빙어)가 양성 클래스이군!
💻 계수 확인
print(lr.coef_,lr.intercept_)
>>> [[-0.4037798 -0.57620209 -0.66280298 -1.01290277 -0.73168947]] [-2.16155132]
💻 처음 5개의 샘플 z값
decisions = lr.decision_function(train_bream_smelt[:5])
print(decisions)
>>> [-6.02927744 3.57123907 -5.26568906 -4.24321775 -6.0607117 ]
📍 expit() : 사이파이의 시그모이드 함수
4. 로지스틱 회귀로 다중 분류 수행
📍 LogisticRegression 클래스
- 반복적인 알고리즘 사용
- max_iter 매개변수 : 반복 횟수 지정, 기본값은 100
- 계수의 제곱 규제 (L2 규제)
- 규제를 제어하는 매개변수는 C
: C는 alpha와 반대로, 작을수록 규제 커짐
- 규제를 제어하는 매개변수는 C
💻 로직스틱회귀 클래스로 다중 분류 모델 훈련 후 예측
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
# 예측
# predict는 문자열로 반환
print(lr.predict(test_scaled[:5]))
>>> 'Perch' 'Smelt' 'Pike' 'Roach' 'Perch']
# predict_proba는 확률로 반환
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.classes_)
>>> ['Bream' 'Parkki' 'Perch' 'Pike' 'Roach' 'Smelt' 'Whitefish']
print(lr.coef_.shape, lr.intercept_.shape)
>>> (7, 5) (7,)
🔎 5개의 특성을 사용하므로 coef_ 배열의 열은 5개. 7은 z를 7개 계산한다는 의미
📍 softmax 함수 : 다중 분류에서 시그모이드 함수와 같은 역할
💻 테스트 세트의 처음 5개 샘플에 대한 z1~z7 값 구하기
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]]
2. 확률적 경사 하강법
1. 확률적 경사 하강법
: 훈련 세트에서 랜덤하게 하나의 샘플을 고르는 것
📌 에포크 epoch : 훈련 세트를 한 번 모두 사용하는 과정
2. 손실 함수
: 어떤 문제에서 머신러닝 알고리즘이 얼마나 엉터리인지 측정하는 기준, 손실 함수의 값이 작을수록 좋음
3. 로지스틱 손실 함수
: 이진 분류에서 사용, 다중 분류는 크로스엔트로피 손실 함수 사용
4. SGDClassifier
💻 판다스 데이터프레임 만들기
import pandas as pd
fish=pd.read_csv('https://bit.ly/fish_csv_data')
💻 입력 데이터와 타깃 데이터 정의 후 훈련 세트와 테스트 세트 분류
# Species 열을 제외한 남저ㅣ 5개 입력 데이터로 사용
# Species는 타깃데이터
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)
📍 SGDClassifier : 사이킷런에서 확률적 경사 하강법을 제공하는 대표적인 분류용 클래스
sc = SGDClassifier(loss='log', max_iter=10, random_state=42) # 로지스틱 손실 함수로 10번 훈련
sc.fit(train_scaled, train_target)
# 훈련 세트와 테스트 세트에서 정확도 점수 출력
print(sc.score(train_scaled, train_target))
print(sc.score(test_scaled, test_target))
>>> 0.773109243697479
>>> 0.775
📍 loss : 손실 함수의 종류 지정 (여기서는 로지스틱 손실 함수 지정)
기본값은 'hinge'
max_iter : 수행할 에포크 횟수 지정
📌 ConvergenceWarning 경고 : 훈련 부족. 모델이 충분히 수렴하지 않았다는 경고
📍 partial_fit() : 모델을 이어서 훈련
sc.partial_fit(train_scaled, train_target)
print(sc.score(train_scaled, train_target))
print(sc.score(test_scaled, test_target))
>>> 0.8151260504201681
>>> 0.85
5. 에포크와 과대/과소적합
📌 에포프가 진행됨에 따라, 훈련 세트 점수는 꾸준히 증가하지만 테스트 세트 점수는 어느 순간부터 감소한다. 이 지점이 과대적합되기 시작하는 때. 과대적합이 시작하기 전에 훈련을 멈추는 것을 조기종료라고 한다.
💻 에포크마다 훈련 세트와 테스트 세트에 대한 점수 기록하기 위해 2개의 리스트 준비
import numpy as np
sc = SGDClassifier(loss='log', random_state=42)
train_score = []
test_score = []
classes = np.unique(train_target)
💻 300번의 에포크 동안 훈련 반복
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))
💻 300번의 에포크 동안 기록한 훈련 세트와 테스트 세트의 점수 그래프
import matplotlib.pyplot as plt
plt.plot(train_score)
plt.plot(test_score)
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.show()
🔎 백 번째 이후로는 과대적합이 시작된다. 백 번째 에포크가 적절한 반복 횟수..!🧐
💻 반복 횟수 100에 맞추고 모델 재훈련 후, 훈련 세트와 테스트 세트 평가
sc=SGDClassifier(loss='log', max_iter=100, tol=None, random_state=42)
sc.fit(train_scaled, train_target)
print(sc.score(train_scaled, train_target))
print(sc.score(test_scaled, test_target))
>>> 0.957983193277311
>>> 0.925
'데이터 엔지니어링 과정 > python' 카테고리의 다른 글
[51일차] 회귀 알고리즘과 모델 규제 (0) | 2023.03.07 |
---|---|
[50일차] 나의 첫 머신러닝 & 데이터 다루기 (0) | 2023.03.06 |
[47일차] 데이터 분석하기 (0) | 2023.02.28 |
[15일차] 실전 데이터 분석 프로젝트 (0) | 2023.01.11 |
[14일차] 웹 API (0) | 2023.01.09 |