728x90

 

파이토치과정 - 6. 구글드라이브,코랩에서 kaggle-api연동

ref : throwexception.tistory.com/1018

 

 

일단 캐글 api로 데이터 부터 준비하자

 

다운되면 압축 풀고 로드 준비

!kaggle competitions download -c santander-customer-satisfaction

 

 

일단 필요한 모듈들과 데이터부터 로드하자

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from lightgbm import LGBMClassifier
from sklearn.model_selection import GridSearchCV

path = "./res/santander-customer-satisfaction/"
test = pd.read_csv(path+"test.csv")
train = pd.read_csv(path+"train.csv")

 

 

일단 info를 보면

 

총 76020개, 371개 속성

 

마지막 컬럼이 타겟으로 되어있다.

 

 

결측치가 존재하는지 보려고, 했으나

 

속성이 너무많아 잘 보이지가 않는다.

 

 

 

sum에 또 sum해보니 없다고 한다.

 

일단 타겟으로 만족여부를 살펴보자.

 

불만족 고객이 매우 적어보인다.

 

이 문제에서 대부분 고객들이 만족하므로 정확도 대신 ROC-AUC를 사용하여야한다.

train["TARGET"].value_counts()

 

 

 

lgbm 모델로

 

accuracy_score와 roc_auc_score를 살펴보았는데

 

roc-auc score가 많이 낮더라

 

데이터 전처리를 제대로 안해서 그런것같다.

 

from sklearn.metrics import roc_auc_score,accuracy_score
from sklearn.model_selection import train_test_split

X = train.iloc[:,:-1]
y = train.iloc[:,-1]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

lgbm = LGBMClassifier()
lgbm.fit(X_train, y_train)
y_pred = lgbm.predict(X_test)

print("accuracy Score : {}".format(accuracy_score(y_test, y_pred)))
print("ROC-AUC Score : {}".format(roc_auc_score(y_test, y_pred)))

 

 

 

전처리 단계에서

 

결측치를 확인했다.

 

트리 모델이니 스케일링은 필요없고,

 

이상치 문제인것같았다.

 

train.describe()로 다시 살펴보았더니 일부 기술통계량이 이상한 값들이 존재한다.

 

var3의 경우 min인 -9999999인 데이터가 존재하는데 평균과 표준편차를 고려하면 너무 엇나간 값이다.

 

imp_ent_var16_ult1도 마찬가지다.

 

 

 

 

 

 

이상치를 다루는 방법은 제거하거나 이 값을 대치시켜주어야 한다.

 

한 변수에 이상치가 많으면 제거 대신, 평균을 구하여 넣어주곤 한다.

 

평균 +- 3 * std를 기준으로 이상치 갯수부터 살펴보자

 

var3 변수의 경우 이상치가 116개가 존재한다.

 

var = train["var3"]
var_mean = train["var3"].mean()
var_std = train["var3"].std()

lower_bound_idx = var < var_mean - 3* var_std
upper_bound_idx = var > var_mean + 3* var_std

print(lower_bound_idx.sum())
print(upper_bound_idx.sum())

 

이 외에 다른 변수들은 이상치가 몇개씩 있을까 확인해보자

 

mean +- 3* std를 넘어가는걸 아웃라이어로 볼때

 

이상치가 100개 넘어가는 변수들이 총 187개가 있다고 한다.

 

num_over_th = 0
num_outlier_th = 100
columns = train.columns
for col in columns:
    var = train[col]
    var_mean = train[col].mean()
    var_std = train[col].std()

    lower_bound_idx = var < var_mean - 3* var_std
    upper_bound_idx = var > var_mean + 3* var_std

    num_outliers = lower_bound_idx.sum() + upper_bound_idx.sum()
    if num_outliers > num_outlier_th:
        num_over_th += 1
        print("  columns : {}".format(col))
        print("    -> num of oulier : {}\n".format(num_outliers))

print("num over th : []".format(num_over_th))

 

 

 

내가 중간에 빠트린 작업이 있는데

 

"ID"열을 삭제 해주지 않았었다.

 

할일 다시 정리하면

 

1. ID열을 삭제하고

2. 각 열의 아웃라이어들을 해당 열의 최빈값으로 바꿔주자

 

 

아웃라이어 대치 전후를 비교할수 있도록

 

 

우선 바꾸기전에 한번 결과보고

 

아웃라이어를 바꾼 후 결과를 보겠다.

 

 

 

 

 

 

정확도는 0.9632333596421995

roc-auc는 0.8345281581059178

describe()한결과 이상치들이 많아보인다.

 

 

X.drop(columns="ID", inplace=True)


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

lgbm = LGBMClassifier()
lgbm.fit(X_train, y_train)

print("before replace outlier")
print("accuracy Score : {}".format(accuracy_score(y_test, lgbm.predict(X_test))))
print("ROC-AUC Score : {}\n".format(roc_auc_score(y_test, lgbm.predict_proba(X_test)[:, 1])))


X.describe()

 

 

 

 

 

최빈값으로 대치한 결과

 

describe()를 보면 이상치들이 많이 줄어든걸 볼수 있지만

 

정확도와 roc-auc가 많이 줄어들었다.

 

교차 검증이 필요해보인다.

 

 

columns = X.columns
for col in columns:
    var = X[col]
    var_mean = X[col].mean()
    var_std = X[col].std()

    lower_bound_idx = var < var_mean - 5* var_std
    upper_bound_idx = var > var_mean + 5* var_std
    X.loc[lower_bound_idx, col] = X[col].mode()
    X.loc[upper_bound_idx, col] = X[col].mode()



X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

lgbm = LGBMClassifier()
lgbm.fit(X_train, y_train)
print("after replace outlier")
print("accuracy Score : {}".format(accuracy_score(y_test, lgbm.predict(X_test))))
print("ROC-AUC Score : {}".format(roc_auc_score(y_test, lgbm.predict_proba(X_test)[:, 1])))

X.describe()

 

 

 

 

 

 

아까 0.83에서 0.82로 떨어진것보다 정도는 덜하지만

 

여전히 전처리 후 더 줄어들어 있다.

 

아웃라이어를 너무 많이 잡아서 그런것 같아 

 

5 * std 대신 100* std로 심각한 아웃라이어들만 대치시키도록 바꿔보았다.

from sklearn.model_selection import cross_val_score

X = train.iloc[:,:-1]
X.drop(columns="ID", inplace=True)
lgbm = LGBMClassifier()

scores = cross_val_score(lgbm, X, y, cv= 5, scoring="roc_auc")
print("before replace outlier")
print("ROC-AUC Score : {}\n".format(np.mean(scores)))



columns = X.columns
for col in columns:
    var = X[col]
    var_mean = X[col].mean()
    var_std = X[col].std()

    lower_bound_idx = var < var_mean - 5* var_std
    upper_bound_idx = var > var_mean + 5* var_std
    X.loc[lower_bound_idx, col] = X[col].mode()
    X.loc[upper_bound_idx, col] = X[col].mode()



lgbm = LGBMClassifier()
scores = cross_val_score(lgbm, X, y, cv= 5, scoring="roc_auc")
print("after replace outlier")
print("ROC-AUC Score : {}\n".format(np.mean(scores)))

 

 

 

위 코드에서 5를 100으로 바꿧더니

 

아까보다 전처리 후 성능은 좋아졌지만

 

전처리 전보다 떨어지는건 여전하다..

 

describe()로 봤더니

 

100이 너무 커 아웃라이어들을 너무 많이 놓쳣더라

 

대신 15 정도로 바꿔 보았다.

 

    lower_bound_idx = var < var_mean - 100* var_std
    upper_bound_idx = var > var_mean + 100* var_std

 

 

 

 

또 떨어졌다..

    lower_bound_idx = var < var_mean - 15* var_std
    upper_bound_idx = var > var_mean + 15* var_std

 

 

 

std * 300으로 바꿔주었더니

 

바꾸기 전이랑 동일한 결과가 나왔다.

    lower_bound_idx = var < var_mean - 300* var_std
    upper_bound_idx = var > var_mean + 300* var_std

 

 

ID 제거하는것 빼고

 

전처리를 안한 결과를 봐도

 

성능 변화가 없는걸 봐서

* ID 같은 정말 의미없는 데이터를 없애는것 빼곤

 

LightGBM에서 전처리는 큰의미가 없는것 같았다.

X = train.iloc[:,:-1]
X.drop(columns="ID", inplace=True)
lgbm = LGBMClassifier()

scores = cross_val_score(lgbm, X, y, cv= 5, scoring="roc_auc")
print("ROC-AUC Score : {}\n".format(np.mean(scores)))

300x250

+ Recent posts