💠 분류 - 캐글 신용카드 사기 검출 💠
2023. 11. 7. 12:00ㆍ개발/💠 Alchemist
< 캐글 신용카드 사기 검출 >
1. 데이터세트 로딩 및 분석
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore")
%matplotlib inline
card_df = pd.read_csv('./creditcard.csv')
# dataset 앞 세 줄 출력
card_df.head(3)
데이터세트 분석 1 - 왜곡된 분포도
import seaborn as sns
plt.figure(figsize=(8,4))
plt.xticks(range(0,30000,1000), rotation=60)
sns.histplot(card_df['Amount'], bins=100, kde=True)
plt.show()
Amount( 카드 사용 금액 )가 1000불 이하인 데이터가 대부분
꼬리가 긴 형태의 분포 곡선
데이터세트 분석 2 - 이상치
import seaborn as sns
plt.figure(figsize=(9,9))
corr = card_df.corr()
sns.heatmap(corr, cmap='RdBu')
2. 데이터세트 전처리
전처리1 - 불필요한 칼럼 삭제
from sklearn.model_selection import train_test_split
# 인자로 입력받은 DataFrame을 복사한 뒤 Time 칼럼만 삭제하고 복사된 DataFrame 반환
def get_preprocessed_df(df = None):
df_copy = df.copy()
df_copy.drop('Time', axis=1, inplace=True)
return df_copy
< 왜곡된 분포도 처리 >
전처리 2 - StandardScaler로 피처를 정규 분포 형태로
from sklearn.preprocessing import StandardScaler
# 사이킷런의 StandardScaler를 이용해 정규 분포 형태로 Amount 피처값 변환하는 로직으로 수정
def get_preprocessed_df(df=None):
df_copy = df.copy()
scaler = StandardScaler()
amount_n = scaler.fit_transform(df_copy['Amount'].values.reshape(-1,1))
# 변환된 Amount를 Amount_Scaled로 피처명 변경 후 DataFrame 맨 앞 칼럼으로 입력
df_copy.insert(0, 'Amount_Scaled', amount_n)
# 기존 Time, Amount 피처 삭제
df_copy.drop(['Time', 'Amount'], axis=1, inplace=True)
return df_copy
전처리 3 - 로그 변환으로 왜곡된 분포도 개선
def get_preprocessed_df(df=None):
df_copy = df.copy()
#넘파이의 log1p()를 이용해 Amout를 로그 변환
amount_n = np.log1p(df_copy['Amount'])
df_copy.insert(0, 'Amount_Scaled', amount_n)
df_copy.drop(['Time', 'Amount'], axis=1, inplace=True)
return df_copy
<이상치 처리>
전처리 4 - IQR로 이상치 제거
import numpy as np
def get_outlier(df=None, column=None, weight=1.5):
# fraud에 해당하는 column 데이터만 추출, 1/4분위와 3/4분위 지점을 np.percentile로 구함
fraud = df[df['Class']==1][column]
quantile_25 = np.percentile(fraud.values, 25)
quantile_75 = np.percentile(fraud.values, 75)
#IQR을 구하고, IQR에 1.5를 곱해 최댓값과 최솟값 지점 구함
iqr = quantile_75 - quantile_25
iqr_weight = iqr * weight
lowest_val = quantile_25 - iqr_weight
highest_val = quantile_75 + iqr_weight
#최댓값보다 크거나, 최솟값보다 작은 값을 이상치 데이터로 설정하고 DataFrame index 반환
outlier_index = fraud[(fraud<lowest_val) | (fraud>highest_val)].index
return outlier_index
outlier_index = get_outlier(df=card_df, column='V14', weight=1.5)
print('이상치 데이터 인덱스::',outlier_index)
# get_processed_df()를 로그 변환 후 V14 피처의 이상치 데이터를 삭제하는 로직으로 변경
def get_processed_df(df=None):
df_copy = df.copy()
# 로그 변환
amount_n = np.log1p(df_copy['Amount'])
df_copy.insert(0, 'Amount_Scaled', amount_n)
df_copy.drop(['Time', 'Amount'], axis=1, inplace=True)
# 이상치 데이터 삭제하는 로직 추가
outlier_index = get_outlier(df=df_copy, column='V14', weight=1.5)
df_copy.drop(outlier_index, axis=0, inplace=True)
return df_copy
SMOTE 오버샘플링 - 이상치 데이터세트 증식
SMOTE package 설치
conda install -c conda-forge imbalanced-learn
from imblearn.over_sampling import SMOTE
smote=SMOTE(random_state=0)
X_train_over, y_train_over = smote.fit_resample(X_train, y_train)
print('SMOTE 적용 전 학습용 피처/레이블 데이터 세트: ', X_train.shape, y_train.shape)
print('SMOTE 적용 후 학습용 피처/레이블 데이터 세트: ', X_train_over.shape, y_train_over.shape)
print('SMOTE 적용 후 레이블 값 분포: \n', pd.Series(y_train_over).value_counts())
3. 학습 / 테스트 데이터 분리
학습/테스트 데이터 분리
# 사전 데이터 가공 후 학습과 테스트 데이터 세트를 반환하는 함수
def get_train_test_dataset(df = None):
# 인자로 입력된 DataFrame의 사전 데이터 가공이 완료된 복사 DataFrame 반환
df_copy = get_preprocessed_df(df)
# DataFrame의 맨 마지막 칼럼이 레이블, 나머지는 피처들
X_features = df_copy.iloc[:, :-1]
y_target = df_copy.iloc[:, -1]
# train_test_split()으로 학습과 테스트 데이터 분할
# stratify=y_target으로 Stratified 기반 분할
X_train, X_test, y_train, y_test = \
train_test_split(X_features, y_target, test_size=0.3, random_state=0, stratify=y_target)
return X_train, X_test, y_train, y_test
X_train, X_test, y_train, y_test = get_train_test_dataset(card_df)
학습/테스트 레이블값 비율 확인
print('학습 데이터 레이블 값 비율')
print(y_train.value_counts()/y_train.shape[0]*100)
print('테스트 데이터 레이블 값 비율')
print(y_test.value_counts()/y_test.shape[0]*100)
학습/테스트 데이터의 레이블 값의 비율이 거의 동일하므로 잘 분할되었음을 알 수 있다
4. 모델 학습 / 예측 / 평가 수행
#인자로 사이킷런의 Estimator 객체와 학습/테스트 세트를 입력받아서 학습/예측/평가 수행
def get_model_train_eval(model, ftr_train=None, ftr_test=None, tgt_train=None, tgt_test=None):
model.fit(ftr_train, tgt_train)
pred = model.predict(ftr_test)
pred_proba = model.predict_proba(ftr_test)[:, 1]
get_clf_eval(tgt_test, pred, pred_proba)
5. 데이터 전처리 후 모델(LGBM, 로지스틱 회귀)의 성능 변화 관찰
데이터 전처리 전
StandardScaler로 피처를 정규 분포로 변환
로그 변환
로그 변환 후 IQR로 이상치 제거
SMOTE로 오버샘플링
'개발 > 💠 Alchemist' 카테고리의 다른 글
💠 머신러닝 회귀 모델 💠 (4) | 2023.11.07 |
---|---|
💠 AIchemist 5주차 💠 (1) | 2023.11.07 |
💠 분류 - 캐글 산탄데르 고객 만족 예측 💠 (0) | 2023.10.31 |
💠 AIchemist 4주차 💠 (0) | 2023.10.31 |
💠 머신러닝 분류 모델 ( 2 ) 💠 (1) | 2023.10.09 |