x 데이터가 주어졌을 때 확률을 예측하는 로지스틱 회귀 분석은 학습 데이터를 잘 설명하는 선형 판별식 f(x)의 기울기(a)와 절편(b)를 찾는 문제
# 라이브러리 불러오기
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings(action='ignore')
%config InlineBackend.figure_format='retina'
# 데이터 읽어오기
path = 'https://raw.githubusercontent.com/jangrae/csv/master/diabetes.csv'
data = pd.read_csv(path)
# 1단계: 불러오기
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix, classification_report
# 2단계: 선언하기
model = LogisticRegression(max_iter=500, random_state=1)
max_iter : 최대반복 횟수
-> 지정된 최대 반복 횟수 동안에만 모델이 학습 (무한루프, 과적합 방지)
# 3단계: 학습하기
model.fit(x_train,y_train)
# 4단계: 예측하기
y_pred = model.predict(x_test)
# 5단계 평가하기
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))
# 회귀 계수 확인
print(list(x))
print(model.coef_)
print(model.intercept_)
로지스틱 회귀(Logistic Regression)는 이름에 "회귀"가 들어가지만, 실제로는 분류 문제에 사용되는 이유?
- 이 모델이 회귀 분석의 기법을 사용하여 확률을 예측
- 회귀 분석의 기법을 사용하여 확률을 예측하고, 그 확률을 통해 분류를 수행
# 선형 판별식(z or f(x))
z = model.decision_function(x_test)
print(z[:10]) #10개 확인
# 시그모이드 함수 사용
from scipy.special import expit
print(expit(z)[10:21].round(2))
0.5보다 크면 1, 작으면 0이라고 분류
# 확률값 확인
p = model.predict_proba(x_test)
print(p[10:21].round(2))
좌측값은 확인 하지 않아도 됨, 우측값이 확률
# 확률값 얻기
p = model.predict_proba(x_test)
#1의 확률 얻기
p1 =p[:,1] #1번 열만 확인
# 확인
print(p1[:10])
# 임계값 = 0.45
y_pred2 = [1 if x > 0.45 else 0 for x in p1]
print(classification_report(y_test, y_pred2))
정확도가 0.01 증가
...
# 1단계: 불러오기
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix, classification_report
# 2단계: 선언하기
model = LogisticRegression( random_state=1)
# 3단계: 학습하기
model.fit(x_train,y_train)
# 4단계: 예측하기
y_pred = model.predict(x_test)
# 4단계: 예측하기
y_pred = model.predict(x_test)
print(list(x))
print(model.coef_)
print(model.intercept_)
# 선형 판별식(z or f(x)) z1, z2, z3
z = model.decision_function(x_test)
print(z[:5])
-softmax 함수 사용
다중 클래스 분류 문제에서 사용되며, 각 클래스에 속할 확률
# softmax 함수 사용
from scipy.special import softmax
print(softmax(z, axis=1)[:5].round(2))
# 확률값 얻기
p = model.predict_proba(x_test)
# 확인
print(p[:5].round(2))
가장 큰 확률을 가진 클래스로 예측한다.
• 모든 데이터를 학습과 평가에 사용할 수 있음
• 반복 학습과 평가를 통해 정확도를 향상시킬 수 있음
• 데이터가 부족해서 발생하는 과소적합 문제를 방지할 수 있음
• 평가에 사용되는 데이터의 편향을 막을 수 있음
• 좀 더 일반화된 모델을 만들 수 있음
• 평가용 데이터가 따로 있어 가진 데이터가 모두 학습용이면 전체를 K-분할 해도 됨
• 수업에서 사용하는 데이터는 그렇지 않으니 학습용, 평가용으로 분리해 사용해야 함
• 평가용 데이터는 이후 최종 평가에 사용할 데이터이니 성능 검증에 사용하면 안됨
• 그러므로 수업에서의 K-분할은 x_train, y_train 데이터만을 대상으로 함
• 물론 실제 평가에서 얻은 성능이 이 성능보다 더 높거나 낮을 수 있음
...
...
# 모듈 불러오기
from sklearn.preprocessing import MinMaxScaler
# 정규화
scaler = MinMaxScaler()
scaler.fit(x_train)
x_train_s = scaler.transform(x_train)
x_test_s = scaler.transform(x_test)
# 불러오기
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
# 선언하기
model = DecisionTreeClassifier(max_depth=5, random_state=1)
# 검증하기
cv_score = cross_val_score(model, x_train, y_train, cv=10)
# 확인
print(cv_score)
print('평균:', cv_score.mean())
print('표준편차:', cv_score.std())
result={}
result['Decision Tree'] = cv_score.mean()
# 불러오기
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score
# 선언하기
model = KNeighborsClassifier()
# 검증하기 (스케일한 x 사용)
cv_score = cross_val_score(model, x_train_s, y_train, cv=10 )
# 확인
print(cv_score.mean())
# 저장
result['KNN'] = cv_score.mean()
# 불러오기
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
# 선언하기
model = LogisticRegression()
# 검증하기
cv_score = cross_val_score(model, x_train, y_train, cv=10)
# 확인
print(cv_score.mean())
# 저장
result['Logistic Regression'] = cv_score.mean()
현재까지의 과정은 아직 fitting을 하지 않음.
학습데이터에 가장 좋은 성능을 가진 것을 확인 한 것 뿐.
# 예측 및 평가 수행
from sklearn.metrics import classification_report
model = LogisticRegression()
model.fit(x_train, y_train)
y_pred = model.predict(x_test)
print(classification_report(y_test,y_pred))
n_neighbors : (k) 이웃 개수
생각해 볼 수 있는 방법 1 (Grid Search)
① 1~n 구간의 정수를 n_neighbors 값으로 해서 모델 성능 정보 수집
② 수집된 정보에서 가장 성능이 좋았던 때의 n_neighbors 값을 찾음
③ 이 n_neighbors 값을 갖는 KNN 모델을 선언해 학습, 예측 및 평가 과정 진행
→ n 값이 크면 상당히 많은 시간이 소요될 것임
→ 충분한 범위를 옵션 값으로 설정해 확인했으니 다행
생각해 볼 수 있는 방법 2 (Random Search)
① 1~n 구간의 정수 중 무작위로 m개 골라 n_neighbors 값으로 해서 모델 성능 수집
② 수집된 정보에서 가장 성능이 좋았던 때의 n_neighbors 값을 찾음
③ 이 n_neighbors 값을 갖는 KNN 모델을 선언해 학습, 예측 및 평가 과정 진행
→ 임의의 m개만 골라 수행하니 시간 소모는 적을 것임
→ 선택되지 못한 값 중에서 더 좋은 성능을 보이는 값이 있을까 봐 걱정됨
# 파라미터 하나의 경우
param = {'n_neighbors': range(1, 101)}
딕셔너리 형태로 파라미터 두 개의 범위를 지정한 경우
# 파라미터 두 개 경우
param = {'n_neighbors': range(1, 101),
'metric': ['euclidean', 'manhattan']}
# 함수 불러오기
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import RandomizedSearchCV
# 파라미터 선언
param = {'n_neighbors': range(1, 500, 10),
'metric': ['euclidean', 'manhattan']}
# 기본모델 선언
knn_model = KNeighborsClassifier()
# Random Search 선언
model = RandomizedSearchCV(knn_model,
param,
cv=3,
n_iter=20)
# 학습하기
model.fit(x_train, y_train)
# 수행 정보
model.cv_results_
# 최적 파라미터
model.best_params_
# 최고 성능
model.best_score_