박가방
2. 모델링 간단 요약 - (이진 분류) 본문
회사 이직률 예측 - 분류(0 , 1)
1. 환경 준비
① 라이브러리
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.metrics import *
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import Dense
from keras.backend import clear_session
from keras.optimizers import Adam
② 학습 곡선 함수
# 학습곡선 함수
def dl_history_plot(history):
plt.figure(figsize=(10,6))
plt.plot(history['loss'], label='train_err', marker = '.')
plt.plot(history['val_loss'], label='val_err', marker = '.')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend()
plt.grid()
plt.show()
③ 데이터 로딩
# data 읽기
path = "https://raw.githubusercontent.com/DA4BAM/dataset/master/Attrition_train_validation.CSV"
data = pd.read_csv(path)
#np.where함수를 사용하여 삼항연산자를 통해 Yes 를 1 NO를 0
data['Attrition'] = np.where(data['Attrition']=='Yes', 1, 0)
data.head(10)
④ 불필요한 열 제거
# 불필요한 변수 제거
data.drop('EmployeeNumber', axis = 1, inplace = True)
2. 데이터 전처리
①결측치 조회
②데이터 정리
# target 설정
target = 'Attrition'
# 데이터 분리
x = data.drop(target, axis = 1)
y = data.loc[:, target]
③가변수화
- 먼저 data.info()를 통해 object 열을 찾아준 후 모든 열에 대해 가변수화를 진행하였다.
# 가변수화
dum_cols = ['BusinessTravel','Department','Education','EducationField','EnvironmentSatisfaction','Gender',
'JobRole', 'JobInvolvement', 'JobSatisfaction', 'MaritalStatus', 'OverTime', 'RelationshipSatisfaction',
'StockOptionLevel','WorkLifeBalance' ]
x = pd.get_dummies(x, columns = dum_cols ,drop_first = True)
x.head()
④데이터 분할
# 학습데이터 ==> train : val
# test_size & train_size = 0.??? -> 비율로 분할, = 1보다 큰 자연수 - 개수로 분할
x_train, x_val, y_train, y_val = train_test_split(x, y, test_size=200, random_state = 2022)
⑤스케일링
#스케일링 0~1
scaler = MinMaxScaler()
x_train = scaler.fit_transform(x_train)
x_val = scaler.transform(x_val)
# 비율로 보자. 이직률이 16%
y_train.value_counts() / len(y_train)
#일반적으로 클래스 unbalnced는 y에 대해서다.
3. 모델
① features 입력
nfeatures = x_train.shape[1]
# nfeatures : 53
② 구조 설계
#메모리 정리
clear_session()
#모델 선언
# relu 대신 다른 활성화 함수를 쓰면 좋아질 순 있으나, 급격히 좋아지진 않을 것.
# output 레이어는 이진분류이므로 sigmoid, 0과 1의 확률값으로 변경하기 위해서 사용
model1 = Sequential([Dense(16,input_shape=(nfeatures,), activation = 'relu'),
Dense(8, activation = 'relu'),
Dense(4, activation = 'relu'),
Dense(1, activation= 'sigmoid')])
#모델 요약
model1.summary()
# 이번 목표 : 히든레이어를 늘리고 줄이고, 하면서 여러 기법으로 성능을 확인해볼 것.
③ 컴파일
model1.compile( optimizer = Adam(learning_rate = 0.1), loss = 'binary_crossentropy')
# binary_crossentrophy 유의
④ 학습
history = model1.fit(x_train, y_train, epochs = 100, validation_split = 0.2).history
⑤ 학습 곡선
- 과대 적합된 결과 확인 가능, learing_rate를 줄여서 이를 막는걸 기대해볼 수도 있음.
dl_history_plot(history)
4. 검증
- activation fuction인 sigmoid를 output layer에 넣었고 sigmoid가 결과를 0~1 사이의 확률값으로 변환시켜줌.
- 예측 평가 시 이를 분류 문제이므로 np.where로 0과 1함수로 변환해줄 것임
# 예측 값 할당
pred1 = model1.predict(x_val)
# np.where(조건문이 , 참 , 거짓) - pred1이 0.5이상이면 1
pred1 = np.where(pred1 >= 0.5, 1 ,0)
# 성능 결과 표 확인
print(classification_report(y_val, pred1))
- class가 극도로 unbalance한 상황에서 Accuracy를 보면 좋지 않다.
- 이런 데이터 셋은 많을 것이다. 이유는 일반적으로 소수의 클래스를 맞추는게 대게의 목표기 떄문 - 이직, 사기 등
- 이럴 때는 f1_score를 보는게 중요
5. Resampling
- 앞 데이터 셋의 Target 클래스가 불균형한지 보고, oversampling으로 개수를 맞춰주고 학습시켜보자.
y_train.value_counts()
OverSampling에는 Up과 Smote가 있다.
· up 방식 - 0의 881에 맞춰서 1의 169를 881로 맞춰줌
5.1 라이브러리 불러오기
# 라이브러리 불러오기
from imblearn.over_sampling import RandomOverSampler
5.2 데이터 셋을 OverSampling으로 ReSampling하기.
#샘플링 함수 할당
ros = RandomOverSampler()
# transform() 과 같이. fitting 하면서 resample을 적용하라는 뜻
x_train_ros, y_train_ros = ros.fit_resample(x_train, y_train)
5.3 모델링 선언 & 컴파일 & 학습
# 메모리 정리
clear_session()
# 모델 선언
model2 = Sequential([Dense(16,input_shape=(nfeatures,), activation = 'relu'),
Dense(8, activation = 'relu'),
Dense(4, activation = 'relu'),
Dense(1, activation= 'sigmoid')])
# 컴파일
model2.compile( optimizer = Adam(learning_rate = 0.001), loss = 'binary_crossentropy')
# 학습
history = model2.fit(x_train_ros, y_train_ros, epochs = 150, validation_split = 0.2).history
5.4 학습곡선
5.5 검증
- 예측을 위한 Validation 값은 OverSampling 하지 않는다.
# 예측값 전처리 후 할당
pred2 = model2.predict(x_val)
pred2 = np.where( pred2>= 0.5, 1, 0)
# 성능 결과
print(classification_report(y_val, pred2))
기존 변경 후
결론 : 큰 차이는 없지만 결과적으로 정확도와 f1_score는 증가하였다.
'데이터 마이닝 > 딥러닝' 카테고리의 다른 글
3. 모델링 간단 요약 - 다중 분류 (방법1, 방법2) (0) | 2023.03.23 |
---|---|
3.1 softmax (0) | 2023.03.22 |
1.1 활성화 함수 Sigmoid, Relu (0) | 2023.03.22 |
Relu (0) | 2023.03.22 |
1. 모델링 간단 요약(선형 회귀) (0) | 2023.03.22 |