본문 바로가기
Kaggle 대회

[Santander Product Recommendation] Baseline 구축하기①

by 사자처럼 우아하게 2019. 12. 25.

 

이번 포스팅에서는 Baseline 구축을 위한 삽질을 공유해보고자 합니다.

먼저 이번 포스팅은 최종적인 Baseline을 만들기 전 실패한 경우를 이야기 하고 있음을 알려드립니다.

 

Santander Product Recommendation 대회의 주된 목적은 고객이 신규로 구매할 것 같은 상품을 예측하는 것입니다.

하지만 주어진 데이터는 월별 고객이 보유한 상품 데이터입니다. 이를 인지하는 것이  Baseline을 구축하는데 중요한

포인트입니다. 저는 이것을 나중에 인지하고 기계적으로 Baseline을 구축하여 제출했다가 처참한 LB Score를 받았네요

 

아래는 월별 고객 보유 상품 데이터로 Baseline을 구축했던 과정입니다. 신규 구매 상품 예측 모델은 다음 포스팅에서

이야기하도록 하겠습니다.

 

ㅁ Baseline 구축하기

  1. Data Cleaning

     - age / antiguedad / indre1_1mes / renta 데이터의 경우 공백이 포함되어 있거나 'NA' 라는 Null을 나타내는 string

       값이 포함되어 있거나 정수와 문자가 뒤섞여있는 등 많은 형태로 데이터가 표현되어 있는데 이걸 클리닝하여 

       일정한 Datatype으로 변경하는 작업을 먼저 진행했습니다.

x_train['age'] = x_train['age'].astype('str').map(str.strip).replace(['NA'],value=-999).astype(float)
x_test['age'] = x_test['age'].astype('str').map(str.strip).replace(['NA'],value=-999).astype(float)

# antiguedad 전처리

x_train['antiguedad'] = x_train['antiguedad'].astype('str').map(str.strip)
x_train['antiguedad'] = x_train['antiguedad'].replace(['NA'],value=-999).astype('float')
x_test['antiguedad'] = x_test['antiguedad'].astype('str').map(str.strip)
x_test['antiguedad'] = x_test['antiguedad'].replace(['NA'],value=-999).astype('float')

# indrel_1mes 전처리
x_train['indrel_1mes'] = x_train['indrel_1mes'].astype('str').map(str.strip)
x_train['indrel_1mes'] = x_train['indrel_1mes'].replace(['P'],value=999)
x_train['indrel_1mes'] = x_train['indrel_1mes'].replace(['NA'],value=-999).astype('float')
x_test['indrel_1mes'] = x_test['indrel_1mes'].astype('str').map(str.strip)
x_test['indrel_1mes'] = x_test['indrel_1mes'].replace(['P'],value=999)
x_test['indrel_1mes'] = x_test['indrel_1mes'].replace(['NA'],value=-999).astype('float')

# test renta value 처리

x_train['renta']= x_train['renta'].astype('str').map(str.strip).replace(['NA'],value = np.nan).astype(float64)
x_test['renta']= x_test['renta'].astype('str').map(str.strip).replace(['NA'],value = np.nan).astype(float64)

 

2. 중복된 데이터 제거

    - Clearing 된 데이터를 기반으로 보면 fecha_dato를 제외하고 고객ID 부터 Target Value(24개)까지 모두 동일한 값

      즉, 월별로 변동이 없는 데이터가 꽤나 있는 것으로 파악하고 drop_duplicates() 함수로 중복 row 제거를 했습니다.

     - 그 결과 1360만개의 Training 데이터가 99만 row로 약 27% 감소했습니다.

     ( 뒤에서 Target 값을 보유 기준이 아닌 신규 구매 기준으로 변경할 때 이 로직은 제외할 수도 있습니다.)

 

# 중복 row 제거
distinct = list(pd.concat([x_train.drop(['fecha_dato','age'],axis = 1),y_train], axis =1 ).drop_duplicates().index)
x_train = x_train.loc[distinct]
y_train = y_train.loc[distinct]
print(x_train.shape)

 

3. 기본 Feature 뽑아내기

   - 날짜 데이터로부터 연도/월 Feature를 뽑아낸 후에 날짜 데이터(fecha_dato,fecha_alta)는 제거하였습니다.

# 
x_train['month'] = pd.DatetimeIndex(x_train['fecha_dato']).month
x_test['month'] = pd.DatetimeIndex(x_test['fecha_dato']).month

x_train['year'] = pd.DatetimeIndex(x_train['fecha_dato']).year
x_test['year'] = pd.DatetimeIndex(x_test['fecha_dato']).year


# fecha_ alta 로 월 주 
# 
x_train['start_month'] = pd.DatetimeIndex(x_train['fecha_alta']).month
x_test['start_month'] = pd.DatetimeIndex(x_test['fecha_alta']).month

x_train['start_year'] = pd.DatetimeIndex(x_train['fecha_alta']).year
x_test['start_year'] = pd.DatetimeIndex(x_test['fecha_alta']).year

#추가하기 

4. 불필요 컬럼 삭제하기

   - 앞선 포스팅에서 언급했던대로 값이 모두 1인 컬럼(tipodom), 다른 컬럼과 정확히 값이 일치하는 컬럼(cod_prov)를

     삭제하여 모델링 시 불필요한 작업을 하지 않도록 했습니다.

 

5. Modeling

    - 적절히 Labelencoding을 실시한 후에 xgboost_gpu로 모델링을 실시했습니다. Lightgbm이었다면 Label encoding

      하지 않고 Categorical feature로 지정해주었을겁니다.

    - Modeling 하여 제출한 결과, LB Score 0.00698(Best score 0.03140)으로 거의 뒤에서 100등안에 포함될 정도의

      점수를 얻었습니다. 이 결과에 대해 분석을 하다 위에서 언급한 Taget Value 설정이 잘못되었음을 알게되었습니다.

    - 다음 포스팅에서  문제점을 보완해보도록 하겠습니다.

 

 

 

 

댓글