로지스틱 회귀(Logistic Regression)는 회귀 문제가 아니라 분류 문제에 사용되는 알고리즘 중 하나이다. 주로 이진 분류(binary classification)에 적용되며, 두 개의 클래스 중 하나에 속하는지 여부를 예측하는데 사용된다. 다중 클래스 분류(multiclass classification)로 확장하여 여러 개의 클래스로 분류할 수도 있다.
로지스틱 회귀는 선형 회귀와 유사하게 입력 특성과 가중치의 선형 결합을 계산하지만, 출력을 특정 범위로 제한하는 로지스틱 함수 또는 시그모이드 함수를 사용하여 결과를 반환한다.
# 필요한 module import
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn import linear_model
from sklearn.model_selection import cross_val_score
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Flatten, Dense
from tensorflow.keras.optimizers import Adam
load_breast_cancerMinMaxScalertrain_test_splitcross_val_scoreSequential, Flatten, DenseAdam # Raw Data Loading
cancer = load_breast_cancer()
# x_data(feature): 세포 특징 | t_data: 악성종양이냐, 양성종양이냐(0,1) | 데이터의 설명
# x_data => cancer.data
# t_data => cancer.target
print(cancer.data.shape, cancer.target.shape) # 데이터 shape 확인
# (569, 30) : x_data는 총 569개의 행으로 구성, 컬럼(feature)은 30개
# (569,) : t_data 역시 총 569개, 0과 1로 구성!
# return_counts = True : 각각의 unique한 값의 빈도수를 세어줌
print(np.unique(cancer.target, return_counts = True))
# (array([0, 1]), array([212, 357]))
# 0.37, 0.63 (0과 1의 비율)
# 0(악성종양)과 1(양성종양)로 구성
# 약간의 데이터 불균형 존재(imbalanced data) ==> 0: 212개 , 1: 357개
# 데이터셋 저장
x_data = cancer.data
t_data = cancer.target
# boxplot으로 이상치와 데이터 분포를 간단하게 확인!
plt.boxplot(x_data)
plt.show()
scaler = MinMaxScaler()
scaler.fit(x_data)
x_data_norm = scaler.transform(x_data)
# plt.boxplot(x_data_norm)
# plt.show()
# 박스플롯으로 확인해보니 0과 1로 데이터들이 정규화된 것을 알 수 있음

# 데이터 분리
# train data와 test data로 분리(데이터를 섞어서 분리)
x_data_train_norm, x_data_test_norm, t_data_train, t_data_test = \
train_test_split(x_data_norm,
t_data,
stratify=t_data,
test_size=0.2, # default값은 0.25
random_state=3)
# 섞어서 분리했기 때문에 데이터의 편향이 없을거라 생각되나
# 확인해보기
np.unique(t_data_test, return_counts=True )
# (array([0, 1]), array([42, 75])) # 35% , 65%
# 원 데이터 0과 1의 비율(37%, 63%)과 유사
sklearn_model: 평가하려는 scikit-learn 모델 객체입니다. 이 모델은 이미 훈련되어 있어야 하며, 교차 검증을 통해 평가됩니다.
x_data_train_norm:모델의 입력 데이터로 사용되는 훈련용 특성 데이터입니다. 일반적으로는 모델을 훈련시키기 위한 특성들이 정규화(normalization)되어 있습니다.
t_data_train: 모델의 훈련용 타겟 데이터입니다. 모델이 예측하려는 목표값 또는 레이블이 들어갑니다.
cv: 교차 검증을 몇 번(fold) 수행할지를 결정하는 매개변수입니다. 여기에서 cv=5는 5-폴드 교차 검증을 의미하며, 데이터를 5개 부분으로 나누어 5번의 훈련 및 평가를 수행합니다.
반환값 (score): 교차 검증의 각 폴드에서 모델의 성능을 나타내는 점수(스코어)들의 배열이 반환됩니다. 이 점수들은 각 폴드에서의 테스트 데이터에 대한 모델의 성능을 나타냅니다.
# sklearn model 구현
sklearn_model = linear_model.LogisticRegression()
# 학습하기 전에 cross validation(교차검증)을 한번 수행해 볼꺼예요!
# train data를 가지고 수행해요!
score = cross_val_score(sklearn_model,
x_data_train_norm,
t_data_train,
cv = 5) # 다섯번의 accuracy 구하기
# 5-폴드 교차 검증을 의미하며, 데이터를 5개 부분으로 나누어 5번의 훈련 및 평가를 수행
print(score)
# [0.97802198 0.94505495 0.95604396 0.98901099 0.94505495]
print(f'sklearn의 평균 validation accuracy : {np.mean(score)}')
# 0.9626373626373625
# 학습 진행
# 학습 시 train 데이터 사용!!
sklearn_model.fit(x_data_train_norm,
t_data_train)
# 모델 최종 평가
# 평가 시 test 데이터 사용!!
test_score = sklearn_model.score(x_data_test_norm,
t_data_test)
print(f'모델의 최종 score : {test_score}') # 0.9649
activation = 'sigmoid'
optimizer=Adam
# Tensorflow 구현
# 1. 모델 생성
keras_model = Sequential() # 박스 그리기
# 2. 레이어 생성
# 박스 안에 레이어 두 개 (Flatten, Dense)
# # input_shape는 피쳐개수와 동일하게 설정
keras_model.add(Flatten(input_shape=(30, ))) # 독립변수(feature)가 30개니까 동글뱅이(node)도 30개로 설정
keras_model.add(Dense(units = 1, # units은 target변수, 즉 t_data와 동일한 개수로 설정
activation = 'sigmoid'))
# 3. 모델 설정
keras_model.compile(optimizer=Adam(learning_rate=1e-2), # 학습 결과가 영 별로면 하이퍼파라미터인 learning_rate를 바꿔보기
loss='binary_crossentropy',
metrics=['acc']) # metircs = ['acc']: 학습 시 매 epoch마다 validation(모델 학습 시 임시평가하는 것)을 수행하고,
# 해당 validation의 평가기준은 accuracy를 사용하겠다는 의미
# 4. 학습 진행
keras_model.fit(x_data_train_norm,
t_data_train,
epochs=300,
verbose = 1, # 매 epoch 마다 학습 결과 출력
validation_split = 0.2) # 학습데이터 중 20%를 validation 하는 데 사용하겠다.
# Epoch 300/300
# 12/12 [==============================] - 0s 5ms/step
# - loss: 0.0785 - acc: 0.9808 - val_loss: 0.0917 - val_acc: 0.9560
# training data로 학습한 후
# training data로 평가 vs. validation data로 평가
# loss : training data로 학습한 후 training data를 이용해서 계산한 loss
# val_loss : validation data로 계산한 loss
"-loss: 0.0785 - acc: 0.9808"는 train 데이터에 대한 손실이 0.0785이며 정확도가 0.9808이라는 의미
"val_loss: 0.0917 - val_acc: 0.9560"는 test 데이터에 대한 손실이 0.0917이며 정확도가 0.9560이라는 의미
- validation data로 계산한 val_loss와 val_accuracy로 평가
- loss와 acc는 train 데이터로 학습하고 train데이터로 답을 맞추는 것과 다름없기 때문에 이를 평가 지표로 사용하는건 무쓸모.
loss (손실)
acc (정확도)
val_loss (검증 손실)
✅val_acc (검증 정확도)
keras_model.evaluate(x_data_test_norm, t_data_test)# 학습이 다 끝났으니
# Evaluation(평가)!
# !! test 데이터 사용해야 함!!
result = keras_model.evaluate(x_data_test_norm,
t_data_test)
print(result)
# [0.08987449109554291, 0.9736841917037964]
# loss값 accuracy값