지금까지 데이터 분석을 위해 파이썬 기본문법과 넘파이, 판다스, 맷플랏립 등의 라이브러리를 익혔다. 오늘 소개할 사이킷런(Sckikit-learn)은 이제 지금까지 배운 지식들과 결합해 머신러닝으로 데이터 모델링을 하기 위한 파이썬의 머신러닝 라이브러리다.
사이킷런 라이브러리의 장점은 데이터 샘플을 비롯해 데이터 전처리, 머신러닝 모델링, 모델 평가 등 일련의 머신러닝 모델링을 위한 기능들을 제공한다는 점이다. 사이킷런이 제공하는 상세한 기능들에 대해서는 나중에 공부하도록 하고 우선 지금까지 배운 기초지식과 사이킷런 라이브러리를 사용해 데이터 분석이 어떻게 이뤄지는 지 데이터 분석 과정을 살펴보도록 하자.
데이터 분석의 과정을 이해한다면 데이터 사이언티스트 또는 개발자와의 협업이 수월해질이고 코딩이 필요 없는 래피드마이너 등과 같은 셀프 머신러닝 플랫폼도 배워서 사용해 볼 수 있다. 물론 개별 알고리즘에 대한 이해와 파라미터 수정, 나아가 알고리즘을 수정해서 사용하는 등 머신러닝의 정확도를 높이고 특정 태스크를 처리하기 위한 여러가지 방법들을 공부하고 본인만의 노하우를 쌓아가는 것은 추후의 문제이다.
기초문법을 배우고 무작정 타이타닉 프로젝트에 참여해 본 후 내가 맨 처음 스스로 선택해 분석해 본 데이터 는 캐글에 올라와 있는 IBM에서 제공하는 자동차 보험회사의 고객 데이터였다. 특별한 이유가 있다기보다는 마케팅 관련 데이터를 한 번 분석해 보고 싶다는 생각이었다.
해당 프로젝트는 따로 분석 목표가 주어진 것은 아니고 데이터에 지역, 성별, 소득 등의 고객 데이터와 함께 고객 LTV도 포함되어 있어 고객 LTV 예측을 분석 목표로 잡았다. 실제 LTV를 예측하기 위해서는 이렇게 몇 년 동안 쌓인 데이터가 아니라 신규 고객 또는 가입한 지 얼마 안되는 고객들의 초기 데이터 포인트를 가지고 LTV를 예측해야 할 것 같은데 우선은 주어진 데이터를 가지고 LTV 가치를 예측하기 위한 머신러닝 모델을 한 번 만들어 보기로 했다.
분석 프로세스는 앞서 타이타닉 프로젝트와 마찬가지로 목표정의, 데이터 탐색, 피처 엔지니어링, 모델링 및 평가, 결론 도출 순으로 진행하려고 한다.
첫 번째가 목표정의인데 앞서 말한 것처럼 자동차 보험회사의 고객 LTV를 예측하는 것을 목표로 삼았다. LTV를 포함해 24개의 컬럼 항목이 있고, 예측 목표인 LTV(종속변수)와 나머지 23개 컬럼(독립변수)과의 상관관계를 분석해 LTV를 예측하는 것이 목표다.
참고로 머신러닝의 지도학습은 예측하고자 하는 목표에 따라 생존 또는 불생존 혹은 0, 1, 2와 같은 라벨을 예측하는 분류(Classification)와 날씨나 가격과 같이 실수형 데이터를 예측하는 회귀(Regression) 로 나눌 수 있다. LTV 값을 예측하고자 하므로 회귀 알고리즘을 적용해야 할 것이다.
이제 데이터를 탐색해보자. 이 단계를 EDA (Exploratory Data Analysis)라고 하는데 여기서는 예측 목표와 나머지 변수 항목들과의 상관관계를 파악하게 된다. 앞서 배운 파이썬의 데이터 분석 라이브러리인 판다스와 맷플랏립, 씨본 등을 활용해 데이터를 분석하고 시각화하고 요리조리 뜯어본다.
데이터를 업로드하고 데이터 규모는 어떤지, 데이터 종류는 무엇이고, 빠진 데이터는 없는 지 데이터를 전처리(Preprocessing)하고 LTV와 상관관계를 분석하는 단계이다. 참고로 나는 파이썬 개발환경인 캐글 노트북에서 데이터 분석을 진행했다.
데이터를 살펴보니 총 9134개 행과 24개 열(컬럼)으로 이뤄져 있고 컬럼 항목들을 살펴보면 LTV, 보험 커버리지, 보험 개시일, 보험개수 등 보험관련 정보와 지역, 성별, 소득 등 고객관련 정보들이 있다. 빠진 데이터를 살펴보니 다행히 빠진 데이터는 없다.
데이터의 첫인상을 살펴보았다면 이제 각 항목과 목표 항목인 LTV와의 상관관계를 분석해 보도록 하자. 참고로 분석하고자 하는 데이터도 분석 목표와 마찬가지로 실수형 값을 가진 수치형 데이터 (Numerical Data)와 몇 개 한정된 값으로 나눌 수 있는 범주형 데이터(Categorical Data)로 나눌 수 있다. 범주형 데이터는 다시 라벨들 간에 명확한 순서(order)가 있는 순서형 데이터(Ordinal Data)와 명확한 순위가 없는 명목형 데이터(Nominal Data)로 나눌 수 있다.
이렇게 데이터를 크게 수치형 데이터와 범주형 데이터로 나누고 LTV와의 상관관계를 살펴보았다. 먼저 목표가 되는 LTV값 자체를 씨본 라이브러리를 활용해 살펴보면 LTV가 2만 달러 이하에 집중적으로 분포되어 있고 사분범위의 최대값을 벗어나는 이상치 데이터가 많음을 알 수 있다.
이제 먼저 수치형 항목들과 LTV의 관계를 하나씩 살펴보자. 두 변수 모두 실수형 데이터일 때 두 변수의 상관관계를 파악할 수 있는 스캐터플롯으로 LTV와 수치형 항목들의 상관관계를 파악했다. 수치형 항목 가운데서는 Monthly Premium Auto(월 보험료)가 LTV와 선형의 상관관계를 보였고, Total Claim Amount (총 보험 청구액)도 LTV와 어느 정도 상관관계가 있는 것으로 보였다.
다음으로 범주형 데이터와 LTV의 상관관계를 분석한다. 하나는 범주형 데이터이고 또 하나는 수치형인 경우 범주형 데이터 값에 따라 실수형 데이터의 평균과 표준편차를 표시해주는 바플롯(막대 그래프)을 활용했다.
대부분의 범주형 항목은 LTV와 뚜렷한 상관관계가 없지만 Coverage 항목의 경우 Premium > Extended Premium > Basic 순으로 LTV가 높았다. 또한, Renew Offer Type의 경우 offer 1 > offer 3 > offer 2 > offer 4 순으로 LTV에 다소 차이가 났으며, Vehicle Class의 경우 럭셔리 SUV와 럭셔리 카가 상대적으로 LTV가 높았다.
데이터 탐색이 끝났다면 드롭할 데이터는 드롭하고 새로운 피처를 만들거나 머신러닝 모델에 집어넣을 항목(피처)를 선정해 머신러닝 모델에 적합한 모델로 바꿔주는 단계가 피처 엔지니어링이다. 텍스트 데이터는 머신러닝 모델에 바로 집어넣으면 오류가 나서 숫자로 바꿔주는 인코딩 작업 등을 하게 된다.
인코딩은 텍스트를 단순히 0, 1, 2와 같은 숫자에 매칭시키는 레이블 인코딩(Lable incoding)과 모든 값을 0과 1로만 나타내는 원핫 인코딩(Onehot incoding)으로 나눌 수 있는데, 분석목표가 회귀라 단순히 구분을 위해 사용한 숫자라도 모델에 영향을 줄 수 있어 선정된 범주형 항목들을 원핫 인코딩으로 처리했다.
LTV와 상관이 있다고 선정한 피처 컬럼은 Monthly Premium Auto, Total Claim Amount, Coverage, Number of Open Complaints, Number of Policies, Policy Type, Renew Offer Type, Vehicle Class 등 8개 항목이다.
이제 선정한 피처에 사이킷런 라이브러리를 활용해 알고리즘을 적용해 보자. 가장 대표적인 알고리즘인 의사결정나무 회귀, 랜덤 포레스트 회귀, XGBoost 회귀 알고리즘을 적용해 보기로 했다.
9134개의 행을 임의로 트레이닝 데이터와 테스트 데이터로 나눠 트레이닝 데이터로 각 알고리즘을 학습시키고 테스트 데이터로 결과를 예측해 테스트 데이터의 실제값과 오차를 평가하는 것이다.
사이킷런을 활용한 머신러닝 모델링 과정은 다음과 같다.
1. 정의(Define) : 어떤 모델을 사용할 것인지, 또한 어떤 파라미터들을 사용할 것인가?
2. 핏(Fit): 트레이닝 데이터를 알고리즘에 학습시킨다
3. 예측(Predict): 테스트 데이터를 예측한다.
4. 평가(Evaluate): 테스트 데이터의 실제값과 예측값 차이를 평가한다.
https://www.kaggle.com/dansbecker/your-first-machine-learning-model
먼저 의사결정나무 회귀 알고리즘에 데이터를 트레이닝시키고 테스트 데이터를 예측해서 오차를 확인해 보자. 최종 분기되는 잎사귀의 수 즉, max_leaf_nodes 파라미터의 값을 25, 50, 100, 250, 500 등으로 설정해 테스트를 했다. 맥스 리프노드 수가 2000개일 때 테스트 데이터를 알고리즘으로 예측한 값과 실제값의 오차가 가장 적었다.
이어서 랜덤포레스트 모델 회귀 알고리즘을 적용했는데 랜덤 포레스트는 쉽게 말하면 의사결정나무를 여러 개 동시에 진행해서 그 결과를 평균하는 방식이다. 동시에 진행할 의사결정나무 수, 즉 n_estimators 파라미터를 25, 100, 200, 500개, 1000개로 테스트했고 가장 오차가 작은 경우는 의사결정나무 500개로 진행했을 때였다.
마지막으로 XGBoost 회귀 알고리즘을 적용했는데 XGBoost 역시 의사결정나무를 기반으로 한 알고리즘이다. 랜덤 포레스트와 마찬가지로 n_estimators 파라미터를 100, 250, 500, 1000개로 테스트했는데 100개일 때가 오차가 가장 작았다.
세 알고리즘을 통틀어 오차가 작은 경우는 랜덤 포레스트 모델을 의사결정나무 500개로 진행했을 때였다. 그래서 베스트 모델로 다시 한 번 데이터를 훈련 시키고 예측한 결과 LTV 오차가 위에서 본 것처럼 1,518, 즉 천오백달러 정도였다. 이는 LTV 평균이 약 8,000달러 정도임을 감안하면 약 80%의 정확도라 할 수 있다.
베스트 모델의 LTV 예측값과 실제값으로 다시 그래프를 그려서 살펴봐도 실제 LTV값을 나타내는 파란색 막대 그래프의 경우 분포가 많이 들쭉날쭉 한 것을 알 수 있다. 또한, 두 값의 상관관계를 나타내는 스캐터플롯 역시 선형에서 벗어나는 데이터들이 많음을 알 수 있다.
두 번째 진행해보는 프로젝트지만 역시나 80%의 벽을 넘기기 쉽지 않았다. 이번 분석을 통해 내린 결론은 LTV의 경우 최대값을 벗어나는 이상치 데이터가 819개(전체 데이터의 약 10%)로 너무 많은 것이 테스트 데이터의 예측값과 실제값의 차이를 만드는 주요 원인으로 보였다. 다른 회귀 알고리즘들을 적용해 보는 방법과 함께 이상치를 어떻게 처리할 것인가가 예측의 정확도를 개선할 수 있는 주요 방법일 될 수 있을 것 같다는 생각이 든다.
다음 글에서는 선형 회귀 알고리즘을 적용해 보는 것, LTV 이상치 제거, 보팅 방법 등 머신러닝 정확도를 끌어올리기 위해 내가 시도한 방법들을 소개하고자 한다.
# 참고자료
A Machine Learning Project — LTV Prediction (1)
https://www.kaggle.com/kyungapark/a-machine-learning-project-ltv-prediction-1
박정현의 데이터 사이언스 시작하기 - 데이터 종류 및 관련 용어