import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split, KFold
from sklearn.feature_selection import  RFECV
X_train = pd.read_csv("../input/kaistbme587/X_train.csv")
X_test = pd.read_csv("../input/kaistbme587/X_test.csv")
X_test.head()
X_train = X_train.fillna(-1)
X_test = X_test.fillna(-1)
for col in (X_train.columns):
    if X_train[col].dtype == 'object':
        enc = LabelEncoder()
        enc.fit(list(X_train[col].values) + list(X_test[col].values))
        X_train[col] = enc.transform(list(X_train[col].values))
        X_test[col] = enc.transform(list(X_test[col].values)) 

X = X_train.iloc[:,1:]
y = X_train.iloc[:,0]

X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)
model = RandomForestClassifier()
clf = model.fit(X_train, y_train)
"""
Feature Selection 방법 :

우선 이 코드에서는 아주 편하게 Feature Selection을 하는 방법을 소개한다.

RFECV(Recursive feature elimination with cross-validation) 이라고 불리는 이 방법론은, 처음에 N개의 feature를 가지고 학습을 진행한뒤
feature importance를 보고 필요없는 x개의 feature를 지우고 학습 ->을 반복해서 가장 최적의 feature 갯수를 찾는 알고리즘이라고 생각하면된다.
"cross-validation" 이 붙기 때문에 fold 방법론을 적용해서 데이터를 fold로 쪼갠 뒤, fold마다 model 결과의 평균으로 최적의 feature 갯수를 정해주는 알고리즘이다.

이렇게 편하게 feature를 selection 하는 방법도 있지만,

경험상 편하게 selection 하지 않고, 자신의 모델의 feature importance를 추출한뒤, 필요없는 feature ( importance가 적은 애들)을 사용자가 빼주는 것도 경험상 결과가 더 좋아지는 경우가 많다.

이번 Sample code 모음에는 다루지 않지만,

Feature를 Selection하는 것도 중요하지만, 이는 데이터를 빼는 행위이기 때문에 안좋을 확률도 큰 방법이다.

내가 추천하는 방법은 Selection 하기전에 feature를 만들어주는 것이다.

기본적으로 boosting 방법론을 수학적인 걸 배제하고 얘기하면, feature들을 선 하나로 가를 수 있을 수록! 좋은 알고리즘이라고 생각하면 아주편하다..

따라서 같은특징을 가진애들끼리 뭉쳐주는것이 중요하다..

이러한 과정을 Feature engineering이라고 하며 정말 많은 방법이있다.

그중에서 Scaling은 다른 sample code에서 살짝다룬다.

이외에도 feature들을 합해보고 곱해보고.. 빼보고.. 다양한 수치형 feature의 max, min.. 다양한걸 전처리해보는것을 무조건 추천한다. 

우선 RFECV 코드를 보고 가겠다.
Feature Selection은 오차가 크지만, 기존의 Starter code에 비해 약간의 상승 (auc 0.1~ 0.3) 정도를 수반한다.
학습을 엄청 많이해봐야해서, 시간이 엄청 걸린다..(이래서 그냥 feature 보고 선택하는거같다..)



"""
rfe = RFECV(estimator=clf, step=4,min_features_to_select = 70,cv=KFold(n_splits=2, shuffle=False), scoring='roc_auc', verbose=2)
rfe.fit(X, y)
X = X.iloc[:,rfe.ranking_ == 1]
X_test = X_test.iloc[:,1:]
X_test = X_test.iloc[:,rfe.ranking_ == 1]

X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)
model = RandomForestClassifier()
model.fit(X_train, y_train)
y_pred=model.predict_proba(X_test)[:,1]
sub = pd.read_csv("../input/kaistbme587/sample_submission.csv")
sub['Fraud'] = y_pred
sub.to_csv('baseline5.csv', index=False)

