728x90

uci에서 제공하는 신용 카드 데이터에 PCA를 적용하여 연체 여부를 판단해보자

 

archive.ics.uci.edu/ml/datasets/default+of+credit+card+clients

 

 

이 데이터의 반응 변수로 연체 여부인데 1이면 연체, 0이면 연체 아님

 

 

데이터를 로드하긴 했는데

 

실제 컬럼 이름이 ID 행으로 빠져나와 있다.

 

ID 행의 컬럼 이름들을 다시 컬럼으로 바꿔주자

 

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

#df = pd.read_csv("./res/credit-card-fraud-detection/creditcard.csv")
df = pd.read_excel("./credit_card.xls", sheet_name="Data")
df.head()

 

 

 

0번째 행들의 값으로 컬럼 명을 바꾸고,

 

인덱스 ID 행을 제거

 

 

cols = df.iloc[0,:].values
df.columns = cols
df.drop(index="ID", axis=0, inplace=True)
df.head()

 

 

 

다음달 연체 여부는 이름을

 

default로 줄여주고, pay0은 pay1로 바꾸자

 

df.rename(columns={"PAY_0":"PAY_1", "default payment next month":"default"}, inplace=True)
df.head()

 

PCA 에 앞서

 

상관 계수 행렬로 히트맵을 그리려고하는데

 

corr()이 반환이 안된다.

y = df["default"]
X = df.drop(columns="default", axis=1, inplace=False)

corr = X.corr()
sns.heatmap(corr, annot=True)

 

 

데이터 타입을 보니 다 문자열 처리가 된듯하다

 

가능한 데이터는 수로 바꾸어줘야겟다

 

 

 

float으로 바꿔주고

 

 

 

 

 

히트맵을 살펴보면

 

BILL_AMT1 ~ 6까지는 모두 상관관계가 0.8 이상으로 강한 선형적 관계를 보인다.

 

다중공선성 문제를 해결하기 위해

 

차원 축소를 해주자.

 

y = df["default"]
X = df.drop(columns="default", axis=1, inplace=False)

corr = X.corr()

plt.figure(figsize=(14,14))
sns.heatmap(corr, annot=True)

 

 

BILL_AMT1 ~ 6 6개 속성들을 추출하여

 

표준화 후 주성분 2개로 주성분 분석을 한 결과

 

2개의 주성분 요소 만으로도 95%정도의 설명력을 가짐

from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

cols_bill = ["BILL_AMT" + str(i) for i in range(1, 7)]
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X[cols_bill])
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)
print(pca.explained_variance_ratio_)

 

 

원본 데이터셋과 PCA 적용 데이터셋의 랜덤 포레스트 성능을 비교해보자

 

기존 데이터셋의 경우 81% 였으나 pca를 통해 6개의 주성분 만으로 79%의 성능을 보임

 

from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_val_score

rf = RandomForestRegressor()
scores = cross_val_score(rf, X, y, cv=5, scoring="accuracy", n_jobs=-1)
print("normal dataset : {0:.3f}".format(np.mean(scores)))
rf = RandomForestRegressor()
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
pca = PCA(n_components=6)
X_pca = pca.fit_transform(X_scaled)
scores = cross_val_score(rf, X_pca, y, scoring="accuracy", cv=5, n_jobs=-1)
print("pca dataset : {0:.3f}".format(np.mean(scores)))

 

 

300x250

+ Recent posts