본문 바로가기

Project/Kaggle

[Kaggle] 산탄데르 은행 제품 추천 - Baseline

캐글 대회 링크 : https://www.kaggle.com/c/santander-product-recommendation

 

Santander Product Recommendation

Can you pair products with people?

www.kaggle.com

안녕하세요!

오늘은 캐글의 'Santander Product Recommendation' 대회를 주제로 포스팅하려 합니다.

시작하기 앞서 이번 포스팅은 '캐글 우승작으로 배우는 머신러닝 탐구생활' 도서의 베이스라인 코드를 분석한 것임을 밝힙니다. 

 

오늘은 저자의 베이스라인 코드를 자세히 들여다보고 느낀 점과 배운 점을 정리하며 마무리 할 계획입니다.  

바로 시작해볼게요!!


순서

  1. 데이터 구성 파악
  2. 뼈대 구상
  3. 전체 코드 공유
  4. 느낀 점 및 배운 점
    1. 변수 정리 파일 만들기
    2. 목적에 맞는 전처리 (신규 구매)
    3. 지난 달(lag-1) 특성 반영 방법
    4. 타겟 변수(y값) 특성 추가 방법

1. 데이터 구성 파악 

- 목표 : 고객의 상황에 가장 적합한 금융 상품 자동 추천

 

- 주어진 데이터 :

2015-01-28 ~ 2016-06-28 까지 총 1년 6개월사이 월별 데이터

1300만개의 대용량 데이터

고객 관련 변수 24개, 제품 관련 변수 24개로 총 48개의 열로 구성 (train set)

고객 관련 변수 24개 (test set)

2. 뼈대 구상

  1. 타입 변환 및 결측치 처리 등 데이터 전처리
  2. 지난 달(1개월 전)과 이번 달의 정보를 비교하며 신규 구매에 대한 변수 추가
  3. XGBoost를 활용하여 다중 분류 모델 구현

3. 전체 코드 공유

전체 코드는 아래 깃허브를 참고해 주세요.

https://github.com/sanghwi-git/santander_recommendation/blob/master/baseline.ipynb

 

sanghwi-git/santander_recommendation

Contribute to sanghwi-git/santander_recommendation development by creating an account on GitHub.

github.com

과정

  1. 데이터 전처리
    1. 데이터 로드 (Baseline의 간소화를 위해 일단 2016년만 사용)
    2. 범주형 변수 (label encoding + 결측치 처리)
    3. 수치형 변수 (타입 변환 + 결측치 처리)
  2. 피처 엔지니어링
    1. 월, 년도 정보 특성 추가
    2. 1개월 전 데이터 병합 -> 지난 달 데이터 변수 추가
  3. 머신러닝 모델 학습
    1. 신규 구매 건수만 추출
    2. 추천될 타겟 변수 특성 추가
    3. XGBoost 알고리즘을 활용한 모델링

4. 느낀 점 및 배운 점

4-1. 변수 정리 파일 만들기

처음 데이터의 형태를 파악하고 EDA를 할 때, 열의 개수가 많다보니 머리속에 정리가 되지 않았습니다.

예를 들어 성별은 남성이 압도적으로 많거나, 3번 제품의 판매율이 부진하는등 각 열의 특성을 모두 기억할 수 없었고,

값은 숫자인데 object타입으로 입력되어있어 변환을 해주어야 하거나, 결측치가 너무 많아 사용할 수 없는 특성 등  feature 별로 처리해야할 전처리 과정이 다양했습니다.

 

그래서 저자이신 '정권우' 님께서 추천해주신 방법으로 '변수 표'를 제작해봤는데, 

실수를 줄일 수 있고 특성간 관계를 파악하기 쉬운 등 다양한 장점이 있어 앞으로도 쭉 사용하려 합니다.

 

책을 참고해서 직접 만들어본 '변수 표'

4-2. 목적에 맞는 전처리 (신규 구매)

대회의 목적은 '고객에게 상황에 맞는 적합한 금융 상품을 추천'해 주는 것입니다.

기존에 사용하지 않던 제품을 사용하도록 추천하는, 즉 신규 상품에 대한 추천입니다.

 

그렇다면 현재 가지고 있는 모든 데이터를 훈련 데이터로 사용하는것보다

신규 구매에 대한 데이터만을 따로 추출해서 훈련 데이터로 사용하는 것이 더 예측을 잘 할 것 같네요.

 

따라서 지난 달의 제품 변수값이 0에서 이번 달에 1로 바뀐 데이터만을 선별하는 작업을 해줍니다.

(코드와 관련해서는 위에 첨부한 깃허브에서 확인하실 수 있습니다.)

 

이번 포스팅을 통해 데이터 전처리 혹은 EDA를 하기 이전에 

반드시 분석의 목적을 파악하고 그에 상응하는 준비작업을 해야할 필요성을 느꼈습니다!

4-3. 지난 달(lag-1) 특성 반영 방법

    * 이걸 왜 해주느냐? 신규 구매에 대한 데이터를 선별하기 위해서!! 지난달에는 0인데 이번달에는 1인 고객!!

 

쉽게 말해 똑같은 데이터를 복사하고 1개월씩 더한 후, 기존의 데이터와 병합해주는게 핵심입니다.

병합하는데 왜 merge()를 사용하냐구요? 안겹치는 데이터는 어떻게 되냐구요?

헷갈리신다면 일단 merge() 함수에 대해 읽어보시고 코드를 따라와보세요!

# 1. 날짜를 숫자로 변환(15년 2월은 2, 16년 2월은 12+2=14)
def date_to_int(str_date):
    Y, M, D = [int(a) for a in str_date.strip().split('-')]
    int_date = (Y-2015)*12 + M
    return int_date
df['int_date'] = df['fecha_dato'].map(date_to_int).astype(np.int8)

# 2. int_date에 1을 더한 df를 복사하여 합치기 - 기존과 지난달의 데이터 비교 가능
df_lag = df.copy()
df_lag.columns = [col+'_prev' if col not in ['ncodpers','int_date'] else col for col in df.columns]
df_lag['int_date'] += 1

# 3. 지난 달과 기존 데이터 병합
df_trn = df.merge(df_lag, on=['ncodpers','int_date'], how='left')

# 4. 지난 달의 제품정보가 없다면 0으로 대체
for prod in prods:
    prev = prod + '_prev'
    df_trn[prev].fillna(0, inplace=True)
df_trn.fillna(-99, inplace=True)

4-4. 타겟 변수(y값) 특성 추가 방법

모델링을 하기 위해서는 지난달 0에서 이번달 1로 바뀐 내용 뿐만 아니라, 어떤 제품이 바뀌었는지도 알아야 합니다. 

그래야 제품을 추천할 때 특정 제품을 추천할 수 있으니까요!!

 

베이스라인에서는 반복문과 np.zeros() 함수를 통해 제품 순서에 따른 y값을 만들어냈습니다.

그리고 마지막으로는 np.hstack() 함수를 통해 하나의 리스트로 이어 붙였습니다.

# 훈련 및 검증 데이터에서 신규 구매 건수만 추출
X = []
Y = []
for i, prod in enumerate(prods):
    prev = prod + '_prev'
    prX = trn[(trn[prod] == 1) & (trn[prev] == 0)]
    prY = np.zeros(prX.shape[0], dtype=np.int8) + i # ex. 다섯번째 신규구매가 100건이라면 4가 100번 반복되는 배열이 만들어짐
    X.append(prX) # n번째 제품변수에 대한 신규 구매 건수
    Y.append(prY) # n번째임을 숫자로 표현

XY = pd.concat(X) # 24개의 모든 제품 변수에 대한 신규 구매 건수 추출 
Y = np.hstack(Y) # 다 옆으로 이어붙임
XY['y'] = Y # 각 신규 구매 건수에 어떤 제품 변수인지 표시