파이토치과정 - 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)))
'인공지능' 카테고리의 다른 글
파이썬머신러닝 - 17. 스태킹 모델로 유방암 분류하기 (0) | 2020.11.30 |
---|---|
파이썬머신러닝 - 16. 캐글 신용카드 사기 검출 (0) | 2020.11.30 |
파이썬머신러닝 - 14. LightGBM (0) | 2020.11.27 |
파이썬머신러닝 - 13. GBM로 사용자 행동 분류 (0) | 2020.11.26 |
파이썬머신러닝 - 12. 랜덤 포레스트로 사용자 행동 분류하기 (0) | 2020.11.26 |