여름방학을 맞아 데이콘에서 진행하는 경진대회에 지난대회에 이어 다시 한 번 참가했다.
지난 대회에서는 아쉽게 Private에서 등수가 많이 하락해 수상을 하지 못했지만 이번 대회에서는 2등으로 수상할 수 있었다 !
분석 초보자들을 위한 Basic대회이기 때문에 드라마틱한 분석과정이나 결론은 없지만, 머신러닝을 공부해가는 입장에서 이러한 성과는 나름대로 동기부여가 되는 것 같다.
전반적인 코드와 진행 과정은 github에 올려놓았다.
https://dacon.io/competitions/official/235959/overview/description
* 대회 설명
1. 개요 : 나이, 성별, 월 수입 등의 고객 데이터를 이용해서 여행 상품 신청 여부를 예측
2. 평가 기준 : Accuracy
* 데이터 설명
- id : 샘플 아이디
- Age : 나이
- TypeofContact : 고객의 제품 인지 방법 (회사의 홍보 or 스스로 검색)
- CityTier : 주거 중인 도시의 등급. (인구, 시설, 생활 수준 기준) (1등급 > 2등급 > 3등급)
- DurationOfPitch : 영업 사원이 고객에게 제공하는 프레젠테이션 기간
- Occupation : 직업
- Gender : 성별
- NumberOfPersonVisiting : 고객과 함께 여행을 계획 중인 총 인원
- NumberOfFollowups : 영업 사원의 프레젠테이션 후 이루어진 후속 조치 수
- ProductPitched : 영업 사원이 제시한 상품
- PreferredPropertyStar : 선호 호텔 숙박업소 등급
- MaritalStatus : 결혼여부
- NumberOfTrips : 평균 연간 여행 횟수
- Passport : 여권 보유 여부 (0: 없음, 1: 있음)
- PitchSatisfactionScore : 영업 사원의 프레젠테이션 만족도
- OwnCar : 자동차 보유 여부 (0: 없음, 1: 있음)
- NumberOfChildrenVisiting : 함께 여행을 계획 중인 5세 미만의 어린이 수
- Designation : (직업의) 직급
- MonthlyIncome : 월 급여
- ProdTaken : 여행 패키지 신청 여부 (0: 신청 안 함, 1: 신청함)
* 코드 공유
https://github.com/seopp/DACON_Travel
* 모델링 전략
전체적인 EDA와 모델링 과정은 깃허브에 올려놓았다.
데이터 전처리 흐름을 요약해보자면
결측치 살려서 인코딩 -> 로그변환 -> 이상치 처리 -> knn으로 결측치 처리 -> Age 범주 변환 -> Age_level 인코딩
으로 진행된다.
처음에는 전처리 순서에 크게 신경쓰지 않고 진행하다가 중간중간 이상한 점들을 발견해서 전처리 순서를 변경해주었다.
결정적으로 전처리 순서에 영향을 끼친 이유는 결측치 처리때문이었다.
본 대회는 제공되는 Test Data에도 결측치가 존재했기 때문에 결측치를 삭제하는 방법은 사용할 수 없었다.
따라서 결측치를 대체하는 방법을 사용했기에 결측치를 유지하면서 처리하는 과정이 중요했던 것 같다.(사실 이 부분은 경험부족으로 인해 애를 먹었던 것 같다. 돌이켜 생각해보면 당연하면서도 기본적인 내용..)
또한 결측치를 KNN을 이용해 처리해보았는데, 나름대로 좋은 성능을 이끌어낼 수 있었다.
* 마주쳤던 문제들
OverSampling
클래스 불균형 문제를 해결하기 위해 여러가지 방법을 시도해보았다.
그 중 Oversampling 기법을 사용했었는데 성능 향상을 기록하지 못했다.
그 이유에 대해 알아보고자 한다.
먼저 Oversampling이란?
적은 수의 데이터를 복원 추출해 class간 데이터 수의 균형을 맞추는 방법이다.
SMOTE, ADASYN등의 알고리즘을 활용해 오버샘플링을 진행했다.
처음에는 막연히 불균형 데이터이기 때문에 오버샘플링을 하면 성능이 향상될 것이라는 기대를 했다.
하지만 실제 해본 결과는 그렇지 않았다. 데이터의 분포에 따라 좋은 성능을 낼 수도, 성능이 떨어질 수도 있다는 점을 항상 인지해야겠다.
KNNImputer
이번 대회에서 결측치를 처리하면서 KNNImputer라는 것을 처음 알게 되었고, 사용해보았다.
KNNImputer는 sklearn의 패키지 중 하나로, 결측치를 채우는 방법으로 실무에서도 많이 쓰인다는 방법이다.
df.fillna(), df.interpolate 또는 SimpleImputer와 다르게 마땅히 결측치를 채울 방법이 떠오르지 않을 때 사용한다.
KNNImputer는 KNN 알고리즘을 사용하여 결측치를 채우는 방식이다.
즉, 가까운 이웃의 수를 정하고 그 이웃들을 이용하여 결측치를 채우는 방식이다. 따라서 KNN 알고리즘은 거리가 중요하다.
KNN을 이용해 결측치들을 채우는 방식이 가장 성능이 좋았기에 채택했지만 약간의 찝찝한 부분이 남았다.
KNN알고리즘의 전개 과정은 알지만 정확히 어떤 방식으로 결측치를 채우는 지에 대해서는 제대로 알 지 못했기 때문이다.
특정 결측치를 채울 때 모든 칼럼의 정보를 반영하는 것인지, 아니면 관련있는 몇 개의 칼럼들로만 반영되는 것인지 등에 대한 궁금점들이 남았다.