![](https://velog.velcdn.com/images/xswer19/post/d05ea230-2190-45e1-b98b-4787f2395b50/image.png)
project_story
- 나의 역할 : 모델 구축 및 성능 테스트, 데이터 전처리
- 링크 : myGitHub
- 프로젝트의 진행 스토리 및 코드는 github를 통해 알 수 있습니다!
- 이번 프로젝트는 7명이 함께 금융 데이터를 바탕으로 머신러닝 모델을 구축하여 데이터를 통해 예측할 수 있게 진행했습니다.
- 해당 프로젝트는 복수의 데이터를 통해 여러 Label값(범주형, 연속형)을 예측하는 머신러닝 모델 구축을 목적으로 진행했습니다.
1일차, credit_data 분석 시작
- 사전 주제 선정을 위한 미팅, 화상 회의 등을 진행했지만, 본격적으로 시작한 날부터 EDA를 시작했다.
![](https://velog.velcdn.com/images/xswer19/post/3230a0b4-a39c-4c72-8a7d-24e2da6b9259/image.png)
- 가장 먼저 Dacon에서 대출 연체자에 대한 신용등급 데이터셋을 불러왔다.
- 인덱스를 제외한 19개의 컬럼과 26457샘플링 데이터가 존재한다.
index gender: 성별
car: 차량 소유 여부
reality: 부동산 소유 여부
child_num: 자녀 수
income_total: 연간 소득
income_type: 소득 분류 ['Commercial associate', 'Working',
'State servant', 'Pensioner', 'Student']
edu_type: 교육 수준 ['Higher education' ,'Secondary / secondary
special', 'Incomplete higher', 'Lower secondary', 'Academic degree']
family_type: 결혼 여부 ['Married', 'Civil marriage',
'Separated', 'Single / not married', 'Widow']
house_type: 생활 방식 ['Municipal apartment',
'House / apartment', 'With parents', 'Co-op apartment', 'Rented
apartment', 'Office apartment']
DAYS_BIRTH: 출생일 데이터 수집 당시 (0)부터 역으로 셈, 즉,
-1은 데이터 수집일 하루 전에 태어났음을 의미
DAYS_EMPLOYED: 업무 시작일 데이터 수집 당시 (0)부터 역으로 셈, 즉,
-1은 데이터 수집일 하루 전부터 일을 시작함을 의미 양수 값은 고용되지 않은 상태를 의미함
FLAG_MOBIL: 핸드폰 소유 여부
work_phone: 업무용 전화 소유 여부
phone: 전화 소유 여부
email: 이메일 소유 여부
occyp_type: 직업 유형
family_size: 가족 규모
begin_month: 신용카드 발급 월 데이터 수집 당시 (0)부터 역으로 셈,
즉, -1은 데이터 수집일 한 달 전에 신용카드를 발급함을 의미
credit: 사용자의 신용카드 대금 연체를 기준으로 한 신용도
=> 낮을 수록 높은 신용의 신용카드 사용자를 의미함
- 각 컬럼에 대한 설명
![](https://velog.velcdn.com/images/xswer19/post/958d289d-63d5-4529-be9e-fda4950ab446/image.png)
- 컬럼의 숫자를 확인하고, EDA를 위해 사전에 범주형 자료와 연속형 자료를 구분했다.
- 처음에는 DataType을 기준으로 object는 범주형, 나머지는 연속형으로 구분했는데 연속형 자료 중 1과 2 등 이진 자료가 다수 존재해 직접 데이터를 보고 구분했다.
- 그렇게 범주형 자료 12개, 연속형 자료 5개가 나왔고
- FLAG_MOBIL은 휴대폰 소지 여부인데, unuque값이 하나밖에 없어서 머신러닝 모델에 사용할 데이터로 부적합했다.
![](https://velog.velcdn.com/images/xswer19/post/926bb51c-06a7-4a50-8661-7522bd17bbb2/image.png)
- 이제 빈도 및 분포를 확인하기 위해 범주형 자료에 대한 countplot을 그리기 위한 코드이다.
![](https://velog.velcdn.com/images/xswer19/post/9f6fc95b-c827-444e-ae45-88596dafbc5b/image.png)
![](https://velog.velcdn.com/images/xswer19/post/d1c6b593-6aea-45de-a166-48b28536633d/image.png)
![](https://velog.velcdn.com/images/xswer19/post/5576beda-becd-4a68-980f-47590a77a72f/image.png)
- 다양한 색깔로 그려진 것을 보니 더글로리에 전재준이 생각나네...
- 이진 자료도 다수 존재하며, 데이터 한쪽으로 쏠린 데이터 컬럼 또한 존재한다.
- 하우스 타입의 경우 거의 모든 데이터가 아파트에 몰려있다.
![](https://velog.velcdn.com/images/xswer19/post/a4c2a6a8-f35e-4a0f-93b1-89e939b8e13b/image.png)
- 이번에는 연속형 자료를 시각화하기 위한 kdeplot 코드이다.
![](https://velog.velcdn.com/images/xswer19/post/0a159d8b-08d4-4986-ba23-ef9d6d2765b5/image.png)
- 한 표에 다 그려져서 기분이 좋았는데. DAYS_EMPLOYED 데이터의 경우 0이면 취업을 한 경력이 없다는 의미이다
- 또한 income_total의 경우 저소득구간에 몰려 있는 데이터가 많은데 대출 연체를 한다는 것 자체가 소득의 분위가 낮을 가능성이 높다고 생각된다.
![](https://velog.velcdn.com/images/xswer19/post/def10e38-de13-47cf-8d79-3177d9d82943/image.png)
- 라벨값을 사용할 credit 데이터의 경우 2(가장 낮은 신용등급)가 가장 많으며, 0이 가장 적다.
2일차
- 이제 본격적인 분석 작업을 시작했는데, 일단 데이터 전처리 과저부터 시작했다.
![](https://velog.velcdn.com/images/xswer19/post/504905ef-168c-4361-9b8d-1e422d126a08/image.png)
- 일단 고유값이 하나밖에 없는 휴대폰 유무 컬럼을 삭제하고, 전처리한 데이터 변수 pre_data에 저장했다.
![](https://velog.velcdn.com/images/xswer19/post/4f98e28b-6eb8-41ad-a514-44abddbcdf40/image.png)
- 컬럼의 값을 확인하고, 컬럼 중 NaN값이 있는지 확인하기 위해서 for문을 통해 각 컬럼의 NaN값을 확인했는데 occyp_type 컬럼에 NaN이 존재했다.
![](https://velog.velcdn.com/images/xswer19/post/8f6724ed-2269-4b27-8801-6ba40c7f79b4/image.png)
- 다른 컬럼과 Index값을 확인해보니 역시 컬럼의 총합이 다르다.
- 해당 값의 경우 직장이 없거나 직장의 분류가 확실하지 않기 때문에 발생으로 값으로 유추했기 때문에 값을 기타(etc)로 변경
- 그리고 Date 타입의 데이터는 음수값이 기준이기에 양수값으로 변경했다.
![](https://velog.velcdn.com/images/xswer19/post/0db7b3c8-da89-46f2-95f8-e8620baee09b/image.png)
- 이제 각 연속형 자료의 구간을 정하고, 임의로 8개로 구분했다.
- 총수입, 나이(일), 근무기간(월), 카드사용기간(월) 등 4가지 자료를 구간별로 정리했다.
![](https://velog.velcdn.com/images/xswer19/post/8dab160e-9a4f-4f99-ab08-c42d402006d8/image.png)
- 이후 라벨값인 credit과 가족 구성원 컬럼을 int값으로 변경 후,
- 이진 데이터인 성별, 차, 부동산 유무를 lambda를 통해 0과 1로 변경했다.
![](https://velog.velcdn.com/images/xswer19/post/f2a6818c-7c0d-448e-83ee-28451a08fe3a/image.png)
- 이제 머신러닝에 넣은 x, y값으로 구분하고 train_split sklearn으로 8:2로 x_train, x_test, y_train, y_test 4개로 구분했다.
![](https://velog.velcdn.com/images/xswer19/post/7abe265b-7d81-4d10-8934-5b082e74d2e7/image.png)
- 그리고 등급으로 나눈 값에 라벨값을 줬다.
![](https://velog.velcdn.com/images/xswer19/post/7d6fe6a6-f10e-4be5-a1a6-054552064486/image.png)
- 모든 자료의 값을 범주형 자료로 변환했다.
![](https://velog.velcdn.com/images/xswer19/post/765173eb-ad32-4ad7-93fa-05bcf5dcdf12/image.png)
- 이제 Randomforest에 GridSearchCV로 5로 교차검증을 진행했다.
- 결과값은 처참했다. 그래도 EDA도 없고 데이터 전처리만으로 일단 모델링부터 했으니 큰 기대는 안했다.
![](https://velog.velcdn.com/images/xswer19/post/b0d869a4-f0ff-4b0a-b302-f27e9629cb7e/image.png)
- 그냥 시험삼아 test데이터 predict를 해서 넣어보니 역시 결과값이 낮다.
![](https://velog.velcdn.com/images/xswer19/post/49a367fb-b395-48fb-8256-4f5dd6a2d79f/image.png)
- 그러면 이제 제대로 log_loss에 GridSearchCV를 넣어서 결과값을 확인해보자
- 사실 해당 Label값이 3개의 결과값으로 출력되기 때문에 단순히 acuuracy_score로 성능을 테스트하기 어렵다.
![](https://velog.velcdn.com/images/xswer19/post/0c4e6f95-1c28-4a0e-bbb7-b11d1e1f8aa6/image.png)
- 그래서 log_loss 모듈을 사용해 확률에 대한 정확도를 측정해보니 0.955 가까운 값이 출력됐다. 낮은 값일수록 높은 성능이기에 3일차에는 EDA를 기반으로 데이터 스케일 작업과 여러 머신러닝 기법을 통해 성능을 높여야겠다.
3일차
![](https://velog.velcdn.com/images/xswer19/post/642ec608-eb31-49bb-a546-2a91303c175f/image.png)
- 이제 다시 전처리부터 작업을 시작했다.
- 일단 무작정 머신러닝으로 돌려보고 모델 성능을 보니 처참해서 다시 처음부터 천천히 다시 봤다.
![](https://velog.velcdn.com/images/xswer19/post/9ac05363-c9c8-464c-b15b-c26a44417ce8/image.png)
- 일단 가장 Binary type 데이터를 int형태로 바꿨줬다
- 그리고 직업 형태의 NaN값을 etc로 바꿨다. 사실 글을 쓰는 지금도 의문이다. 저 컬럼의 NaN값을 어떻게 처리할지 분명히 일을 한 적이 있는 사람인데 왜 직업의 형태는 NaN일까 그래서 일단 NaN도 결측치를 하나의 데이터로 생각했다.
- 필요없는 휴대폰 유무를 drop하고, int형태의 자료를 음수에서 양수값으로 바꿨다.
![](https://velog.velcdn.com/images/xswer19/post/6f3275c3-8f4b-4f30-bfa9-70eaa8361b52/image.png)
- 이제 남은 object타입의 자료와 연속형 자료만 처리하면 된다.
![](https://velog.velcdn.com/images/xswer19/post/df8819cf-c47b-484f-9118-5e9e878de761/image.png)
- 그전에 먼저 상관계수를 봤는데, 다시 보면서 중요한 사실을 깨달았다.
- 저기 표시한 값들이 상대적으로 높은 상관계수를 가지고 있는데 5개 중 4개 연속형 자료이다.
- 여기서 내가 멍청한 생각을 했다. 분명 라벨값이 범주형인데, 단순히 자료가 연속형이라고 다중회귀분석기법인 OLS를 돌리는 것은 어떨까? 생각한 것이다.
- 다하고 너무 바보 같아서 지워버렸는데 y=β0+β1x1...공식으로 cost function을 가장 낮은 회귀직선을 구하는 기법인데 왜 범주형 라벨에 사용했을까...그래도 acuuracy값은 더 높아졌다.
- 다음으로 생각한 방법은 MCA기법 다중요인분석을 통해 중요 feature값을 찾는 것이다. 하지만 KMO(Kaiser-Meyer-Olkin)값이 너무 낮게 나와서 중간에 그만뒀다. 참고로 0.6미만의 값이 나오면 다중요인분석은 쓰지 않는 것이 좋다.
![](https://velog.velcdn.com/images/xswer19/post/9e0d95d0-5026-4e2d-a970-67631def041c/image.png)
- 내 생각의 흐름인데 음...아직도 참 많이 부족하다. 그래서 더 공부하고 싶다. 정말 많은 기법을 알아서 상황에 맞게 딱딱 문제를 해결할 수 있을 만큼
![](https://velog.velcdn.com/images/xswer19/post/184023a5-1291-44ed-bc6e-3470a4fe71e9/image.png)
- 그래도 소득은 있었는데 저 여러 실패 과정을 통해 5개의 중요 feature값을 얻었고, 그 결과로 5개의 컬럼을 RandomForest에 돌려서 0.77의 log_los값을 얻고 70% 성능의 accuracy값을 얻었다.
- 이제 PipeLine으로 여러 모듈을 한 번에 출력하는 함수를 만들고, 데이터 분석에 중점을 둬서 여러 방면으로 분석하고 성능을 테스트해봐야겠다.
4일차, 함수 생성과 데이터 쪼개기
![](https://velog.velcdn.com/images/xswer19/post/3831137e-281a-47d5-9f73-ac7aa2c5d50c/image.png)
- 이제 다시 처음부터 해보는 마음으로 데이터를 다시 봤다.
- 일단 매번 모델링을 돌릴 수는 없으니까 함수를 만들기로 결심했다.
![](https://velog.velcdn.com/images/xswer19/post/9d532771-1fcc-49cb-a8c5-1004705a4553/image.png)
- 일단 catboost가 좋다는 구글링을 믿고 확인해봤다.
- 0.91...? 내가 잘못 돌린거겠지
![](https://velog.velcdn.com/images/xswer19/post/aaf8b07f-6de0-4c1e-9856-45f7d6b42397/image.png)
- 음...일단 원래 쓰는 RandomForest와 xgbmboost를 써야겠다.
![](https://velog.velcdn.com/images/xswer19/post/45fd29b7-0ab5-4070-9fd5-937cfa908d02/image.png)
def log_loss_gridCv(x_train, y_train, x_test, y_test):
rf_clf = RandomForestClassifier()
xg = XGBClassifier()
# RandomFroest
params = {
"n_estimators" : [100, 500, 1000,2000],
"random_state" : [13]}
clf = GridSearchCV(rf_clf, param_grid=params, cv = 5, scoring="neg_log_loss")
clf.fit(x_train, y_train)
pred = clf.predict_proba(x_test)
print("RandomForest : ",clf.best_estimator_)
print("RandomForest_result : ",log_loss(y_test, pred))
print("=" * 50)
# xgbcBoost
xg = XGBClassifier()
params = {
"n_estimators" : [100, 500, 1000,2000],
"max_depth" : [3, 5, 7, 9],
"random_state" : [13]
}
clf = GridSearchCV(xg, param_grid=params, cv=2, scoring="neg_log_loss")
clf.fit(x_train, y_train)
pred = clf.predict_proba(x_test)
print("xgbm_best : ",clf.best_estimator_)
print("xgbm_result : ",log_loss(y_test, pred))
- 이제 randomForest와 xgbcboost를 한 번에 gridSerchCV부터 최고 parameter로 예측까지 해주는 함수를 만들었다.
- 점점 함수의 위력을 실감한다. 진짜 너무 편하다.
![](https://velog.velcdn.com/images/xswer19/post/2d2b10e6-b04f-4617-8d84-f091298879af/image.png)
- 이제 train, test 데이터를 넣기만 하면 바로 출력된다.
![](https://velog.velcdn.com/images/xswer19/post/d00e7072-41e0-47d0-a722-74bb529949ab/image.png)
- 이번에는 스케일 값을 바꿔봤다.
- 일단 MinMax값으로 바꾸고, 자동차와 부동산 소유 유무를 하나의 컬럼으로 합쳐서 확인해봤다.
![](https://velog.velcdn.com/images/xswer19/post/f0be6c23-7531-4d62-88b7-20de0d2eca39/image.png)
- 음 결과의 큰 변화는 없는 것 같다.
![](https://velog.velcdn.com/images/xswer19/post/a69d73c3-0e00-4d76-8130-05ef83c3906b/image.png)
- 다시 상관계수를 확인하고, 데이터를 꼼꼼히 확인해봤다.
![](https://velog.velcdn.com/images/xswer19/post/21082f15-e080-4730-a21d-5bf5726cada6/image.png)
- 혹시 몰라서 연속형 변수만을 가지고 성능을 테스트해보니까 성능이 조금 더 안좋아졌다.
![](https://velog.velcdn.com/images/xswer19/post/c4e484b5-9abb-4b3a-936b-7f90896eaeef/image.png)
- 그때 이상치값이라도 잡아서 돌려돌까 싶어서 조건을 넣어 검색했는데, 저 3개의 인덱스가 카드를 발급 날짜만 다르고 다른 모든 값이 같았다.
- 이 말은 한 명의 사람이 여러 데이터로 축적된 것을 의미했다.
![](https://velog.velcdn.com/images/xswer19/post/483c0e26-72a2-497a-aeed-a963fe788fde/image.png)
- 바로 확인해보니까 역시나 중복 데이터가 엄청 많았다.
- 그래서 든 생각이 중복값만 돌리거나, 아니면 사람마다 고유 ID를 가질 수 있는 새로운 컬럼을 만들어서 내일 다시 돌려야겠다고 생각했다.
- 머신러닝에서 통계분석을 기반으로 논리적 사고도 물론 중요하지만, 계속 해보고 성능을 테스트해보면서 최선의 분석을 찾고 성능을 높여보자
5일차, 데이터 분석과 모델링의 반복
![](https://velog.velcdn.com/images/xswer19/post/2599ecf8-a1d5-4ce3-9fc0-92e73174d984/image.png)
- 어제 중복값이 많다는 것을 확인하고, 데이터 분석 영역이 더 필요한 것 같아서 데이터를 더 관찰했다.
![](https://velog.velcdn.com/images/xswer19/post/95e40a72-2d43-44fd-9f7f-6ac45ea9ba08/image.png)
- 가장 먼저 이상치 데이터를 발견하고
![](https://velog.velcdn.com/images/xswer19/post/9dddda5d-d4fa-4723-b1c7-664633c260ac/image.png)
- 해당 이상치 데이터를 제거하고, 필요없는 컬럼을 버렸다.
- 그리고 직장 경력이 없는 값을 0으로 통일하고, 직장의 유형이 없는 경우 etc로 바꿨다. 여기서 또 하나 관찰한 것이 직장이 없거나 유형이 없는데 총 수입이 높길래 무엇인지 보니 연금 또한 수입으로 측정된 것이었다.
![](https://velog.velcdn.com/images/xswer19/post/3416ba8d-4abf-4528-935b-fe5035b28a1f/image.png)
- 이제 데이터 가공을 하고 다시 데이터를 관찰했다.
- 참 이 부분에서 진전없는 관찰을 많이 한 것 같다. 그냥 어떻게 하면 label를 특정할 수 있는 feature를 만들 수 있을까 생각했다.
![](https://velog.velcdn.com/images/xswer19/post/f8511362-3ffc-490d-aed5-61de8b66577f/image.png)
- 그래서 다시 데이터 분석 및 시각화로 돌아갔다.
![](https://velog.velcdn.com/images/xswer19/post/166c479d-232e-4ab2-8a68-4791f58254e4/image.png)
- 근무 경력을 기준으로 몇개의 중복 데이터를 찾아봤다.
![](https://velog.velcdn.com/images/xswer19/post/ab625319-939a-4dce-a6d6-f9b641ebe955/image.png)
- 생각보다 한 사람의 ID값으로 많은 카드가 발급이 된 것인지, 아니면 데이터가 중복으로 축적이 되었는지는 모르겠다. 다만, begin_month를 제외한 데이터를 하나의 값으로 모으면 한 사람의 고유 값을 얻을 수 있겠다 생각했다.
![](https://velog.velcdn.com/images/xswer19/post/93ddd211-fce0-437b-9d1e-5d95516c37bc/image.png)
- 일단 분석을 위해 반복작업을 간단하게 함수로 만드록
![](https://velog.velcdn.com/images/xswer19/post/f7b8ee8d-ce04-468a-8de4-8a62bf99b377/image.png)
- 이번에는 credit(라벨값)에 따라 시각화를 분석했다.
![](https://velog.velcdn.com/images/xswer19/post/04fff54f-6d73-4f93-b648-179ed98ff6cc/image.png)
- 이건 연속형 데이터 시각화를 위한 함수이다.
![](https://velog.velcdn.com/images/xswer19/post/ac76b7d8-5126-4022-bba2-b0afdac74405/image.png)
- 참 비슷하다.
- 어떻게 이 주어진 데이터로 구분을 할 수 있을까 고민한 것 같다.
- 여기서 여담으로 나는 머신러닝과 데이터 분석의 별개의 영역이라고 생각했는데, 결국 분석을 토대로 머신러닝을 돌리니 결국 하나의 세트구나 많이 생각하고, 분석의 중요성을 다시 생각했다.
![](https://velog.velcdn.com/images/xswer19/post/5785d8a1-1d6b-4c87-b1dc-3c8098e9268e/image.png)
- 이제 범주형 자료를 Label로 인코딩하고
![](https://velog.velcdn.com/images/xswer19/post/31dd5ee0-e152-40dd-8f7a-e3a7d563687a/image.png)
- 이제 아까 말한 개인의 고유ID 컬럼을 만들어서 관찰을 해보자
![](https://velog.velcdn.com/images/xswer19/post/6f6f4262-ff10-4f2d-9719-c731e5d8fbf2/image.png)
- 이제 개인 번호 22인 데이터인 사람은 credit이 2로 관찰된다.
![](https://velog.velcdn.com/images/xswer19/post/9d0be501-7692-4426-9198-f5ef6a17946f/image.png)
- 이제 나눠서 분석을 해보자
![](https://velog.velcdn.com/images/xswer19/post/3c38e58e-c97b-4f19-89c9-31f6a11b01a0/image.png)
- 근데 한발자국 더 나가서 다른 생각을 했다.
- 총수입, 연생, 근무경력을 연속형 자료 그대로 고유ID에 쓰면 너무 과적합한 컬럼이 아닐까?
- 여기서 머신러닝의 목적을 다시 한 번 생각해봤다. 내가 어떤 데이터로 교육시켜야 컴퓨터가 똑똑하게 label를 구분할까? 그래서 수입과 나이, 근무경력 등을 도수분포화 시켜서 고유ID(사실 이제 고유는 아니지만)값으로 넣었다.
![](https://velog.velcdn.com/images/xswer19/post/062e7af1-08b0-49de-825e-57bb0c599ceb/image.png)
- 이제 해당 데이터셋을 RandomForest, xgbcBoost, lgbmBoost에 돌려보자
- 돌려봤는데 에러가 뜨고 성능이 낮아졌네....내일 다시 다르게 돌려봐야겠다.
![](https://velog.velcdn.com/images/xswer19/post/452cec5b-5348-4400-b05b-8903c32268f9/image.png)
- 됐다. log_loss 값이 0.67로 엄청 낮게 나왔다.
- catBoost를 사용하니 엄청난 성능을 보였다.
- 이제 회귀분석을 사용하는 데이터를 분석해보고 싶다.
6일차, feature_analysis
- 6일차에는 feature들을 활용해 여러 방면으로 사용해봤다.
def log_loss_gridCv(x_train, y_train, x_test, y_test):
xg = XGBClassifier()
lgbm = LGBMClassifier()
# xgbcBoost
xg = XGBClassifier()
params = {
"n_estimators" : [1000, 2000],
"max_depth" : [5, 9],
"random_state" : [13]
}
clf_grid = GridSearchCV(xg, param_grid=params, cv=2, scoring="neg_log_loss")
clf_grid.fit(x_train, y_train)
df_importance = pd.DataFrame(columns=clf_grid.feature_names_in_)
pred = clf_grid.predict_proba(x_test)
print("xgbm_best : ",clf_grid.best_estimator_)
print("xgbm_result_loss: ",log_loss(y_test, pred))
pred = clf_grid.predict(x_test)
print("xgbm_result_ac : ", accuracy_score(y_test, pred))
df_importance.loc[0] = clf_grid.best_estimator_.feature_importances_.tolist()
print("=" * 50)
#lgbm
params = {
"n_estimators" : [1000, 1500, 2000],
"random_state" : [13]
}
clf_grid = GridSearchCV(lgbm, param_grid=params, cv=2, scoring="neg_log_loss")
clf_grid.fit(x_train, y_train)
pred = clf_grid.predict_proba(x_test)
print("lgbm_best : ",clf_grid.best_estimator_)
print("lgbm_result_loss : ",log_loss(y_test, pred))
pred = clf_grid.predict(x_test)
print("lgbm_result_ac : ", accuracy_score(y_test, pred))
df_importance.loc[1] = clf_grid.best_estimator_.feature_importances_.tolist()
print("=" * 50)
cat = CatBoostClassifier(n_estimators=3000, max_depth=10, random_seed=1000, learning_rate=0.04, bootstrap_type ='Bernoulli')
cat.fit(x_train, y_train,
eval_set=[(x_train, y_train), (x_test, y_test)],
early_stopping_rounds=50,
verbose=100)
pred = cat.predict_proba(x_test)
print("cat_log_loss : ",log_loss(y_test, pred))
pred = cat.predict(x_test)
print("cat_ac_score : ",accuracy_score(y_test, pred))
df_importance.loc[2] = cat.feature_importances_.tolist()
df_importance.rename(index={0 : "XGBC", 1 : "LGBMC", 2 : "Cat"})
return df_importance
- 위 코드는 3개의 모델링을 학습하고, 출력하며 feature들의 중요도를 return하도록 만들었다.
- 함수의 위대함일까...정말 너무 편하다...파이썬 최고
![](https://velog.velcdn.com/images/xswer19/post/b8db9787-a436-42eb-ba79-b3fcaab8eff1/image.png)
- 다시 원본 데이터를 보면서 어떻게 처리할지 고민을 해봤다.
- 이 단계가 정말 힘든 것 같다. 가정을 세우고 데이터를 전처리하고 분석하는 것은 구굴링, 기존의 알던 함수를 통해 할 수 있지만 가정을 세우고 결과를 만든다는 것은 정말 힘들다.
![](https://velog.velcdn.com/images/xswer19/post/455482a1-60b4-42c7-9497-0db76b347b64/image.png)
- 이제 앞에 필요없는 두 개의 컬럼을 삭제했다.
![](https://velog.velcdn.com/images/xswer19/post/1aa3d8fb-be02-46bc-9b72-7b39bcbb354a/image.png)
- 그리고 binary형태의 자료를 int형태로 변환했다.
![](https://velog.velcdn.com/images/xswer19/post/8c192cc0-6b22-453a-9aeb-f0f660a49a98/image.png)
- 결측치를 찾기 위해 value_counts를 통해 각 컬럼의 결측치를 search했다.
- 연속형 자료의 경우 모든 컬럼이 feature중요도가 높게 나와서 일단 결측값을 함부로 삭제하기 애매해서 나뒀다.
- 여기서 찾은 점은 income_type에서 학생은 7개밖에 없으며, child_num도 5명 이상인 경우는 적기에 삭제했다.
![](https://velog.velcdn.com/images/xswer19/post/2d8cc170-05e1-455f-bd6b-d62846d9a56d/image.png)
- 두 조건을 통해 index를 검색하고 해당 인덱스의 행을 삭제했다.
![](https://velog.velcdn.com/images/xswer19/post/a1f5e4ef-89e2-49f2-bda9-bfdbdd037d3b/image.png)
- 이제 occupy에서 Nan값인 데이터만 뽑아봤다.
- 총 8169개의 데이터가 존재하는데 저 Nan값을 어떻게 처리할까 고민을 많이 했다.
![](https://velog.velcdn.com/images/xswer19/post/492cbed5-d33d-4243-8404-6fa5e499cba7/image.png)
- 그래서 연관성이 높은 income_type과 살펴보니 Nan값이 있는 행의 income_type은 보통 연금수령자가 많은데, 다른 직업도 있었다.
- 그래서 생각한 가정은 공무원이지만 occupy_type이 여러 종류가 있고 분류가 애매한 경우 Nan값을 준 것이 아닐까 생각해서 두 개의 컬럼을 응용해봤다.
![](https://velog.velcdn.com/images/xswer19/post/48ef7344-c886-49e1-891e-a6ef12283a4a/image.png)
- 그리고 연금수령자면서 직업 유형이 있는 경우도 있다.
![](https://velog.velcdn.com/images/xswer19/post/b912124b-3904-4c79-9813-5dae2eb0c2c3/image.png)
- 컬럼을 합치기 전에 두 개의 컬럼을 통해 group by로 데이터를 살펴보니 공무원 income_type의 평균 크레딧이 확실히 높았다.
![](https://velog.velcdn.com/images/xswer19/post/7f8d9894-77cb-4977-ac9e-03daf447518f/image.png)
- 이제 두개의 컬럼을 합치고, 차와 부동산 유무 또한 크레딧에 영향을 미칠 것이라고 판단하여 합쳐서 두 개의 새로운 컬럼을 만들고 불필요한 binary형태의 컬럼을 drop했다.
![](https://velog.velcdn.com/images/xswer19/post/3e2b3316-069d-4fa2-a7e4-7661aea93bf2/image.png)
- 10개의 컬럼을 통해 새로운 데이터셋을 만들었다.
![](https://velog.velcdn.com/images/xswer19/post/a91a5d0c-26ab-4dbb-a9cb-e4c3dbb4646b/image.png)
- 이번에는 일한 개월 수에 카드를 발급 받은 개월 수를 빼서 카드 발급 받은 날을 기준으로 일한 개월 수 컬럼을 추가했다. 양수일 경우 카드를 발급 받기 전부터 일했으며, 음수의 경우 카드를 발급 받고 일을 하지 않은 것이다.
![](https://velog.velcdn.com/images/xswer19/post/5ba12ef3-e584-467f-afeb-5cc0b81d27f6/image.png)
- card_begin 컬럼의 중앙값 평균 등을 찾아서 분석해봤다.
- 중앙값, 평균 등을 기준으로 구분해서 라벨값을 분석해봤으나, 뚜렷한 두 데이터의 차이점을 발견하지는 못했다.
![](https://velog.velcdn.com/images/xswer19/post/5e28c15f-149b-4a72-9e65-12609b1db8e1/image.png)
- 이제 데이터의 가독성과 단위를 위해 연속형 자료를 처리하고,
![](https://velog.velcdn.com/images/xswer19/post/72a9a4af-ebb7-44af-8b1a-c90bb549d5f4/image.png)
- object형 데이터는 labelEncorder작업을 했다.
![](https://velog.velcdn.com/images/xswer19/post/bb1df633-b640-44e7-8d85-a7bd036cddfc/image.png)
- 이제 x데이터에 라벨값을 뺀 데이터를 주고, y데이터에는 라벨값을 주고 8:2로 데이터를 구분했다.
![](https://velog.velcdn.com/images/xswer19/post/b3f40197-218a-4aaa-9e4c-5e1e729f9072/image.png)
- 먼저 해당 데이터를 그대로 돌려보니 catboost가 가장 좋은 log_loss값을 출력했다.
![](https://velog.velcdn.com/images/xswer19/post/d0ad3b9f-1453-406d-87cf-7b1019a741a3/image.png)
- 그리고 feature 중요도를 프레임 변환받았는데, 연속형 자료의 중요도가 대체로 높게 나왔다.
![](https://velog.velcdn.com/images/xswer19/post/8dee443d-00e1-4f11-a62d-a5d1e0278232/image.png)
- 이번에는 scale값을 표준화하고 다시 테스트해봤다.
![](https://velog.velcdn.com/images/xswer19/post/d2d79541-b591-4695-afa3-846983225828/image.png)
- 이렇게 데이터를 표준화해서 돌려보니
![](https://velog.velcdn.com/images/xswer19/post/a7c4cd80-5c2d-409c-b3b1-4e9783439f5f/image.png)
- 정말 큰 차이가 없다. 허탈하지만 뭐 큰 기대를 안 했다.
- 이제 다른 방식으로 feature 구분을 해보고, 분석을 해봐야겠다.
7일차, credit_data 마무리 및 새데이터 탐색
- 이제 해당 데이터를 마무리하기 위해서 두 가지 방법을 통해 머신러닝을 성능을 테스트해보고 마무리했다.
![](https://velog.velcdn.com/images/xswer19/post/562382c8-dc2c-4c98-9755-aab42c470899/image.png)
- 먼저 데이터셋을 불러왔다.
![](https://velog.velcdn.com/images/xswer19/post/085b7be6-847e-4244-b753-94d2f755ed05/image.png)
- 필요없는 column인 인덱스를 삭제하고, binary data를 int형태로 변환했다.
- 그리고 DAYS_EMPLOYED컬럼의 경우 양수는 일한 경험이 없는 데이터이기 때문에 0이상일 경우 모두 0의 값으로 바꿔주고
- 연속형 자료의 기준이 음수값이라 양수값으로 바꾸기 위해 절대값으로 변환했다.
![](https://velog.velcdn.com/images/xswer19/post/eb855f47-4f55-4c79-bfdf-4696d193ed28/image.png)
- 그리고 데이터 분석 시 발견한 이상치 데이터를 drop했다.
- FLAG_MOBIL 컬럼의 경우 고유값이 하나이기 때문에 모델 성능에 유의미한 차이를 만들 수 없어서 drop했다.
![](https://velog.velcdn.com/images/xswer19/post/6bf9e809-e897-4c44-8f93-c0d5ba439086/image.png)
- 이제 가공한 데이터를 통해 두 가지 방법으로 진행했다.
- 카드 발급 날짜만 다르고, 나머지 데이터 동일한 중복 데이터가 다수 발견되서 두 가지 가정을 세웠다.
- 한 사람의 데이터가 중복적으로 중첩되서 쌓였다.
- 한 사람이 자신의 정보를 토대로 복수의 신용카드를 발급했다.
- 위 문제의 가정을 해결하기 위해 두 가지 해결방안을 모색했다.
- 여러 컬럼의 조합으로 한 사람의 데이터라는 것을 식별할 수 있는 고유 ID값을 생성
- 중복 데이터를 삭제함으로써 고유 데이터만을 가지고 모델링 구축
- 위 두 가지 방법을 모두 사용해서 성능을 테스트해봤다.
![](https://velog.velcdn.com/images/xswer19/post/4516ec39-5eda-4a38-86cf-9c9bb8cdea65/image.png)
- 가장 먼저 데이터 처리 과정이다.
- 카드 발급 날짜를 제외한 나머지 데이터를 모두 string형태로 조합하고, 조합한 데이터를 통해 새로운 SSN(고유식별번호) 컬럼을 만들었다.
- 두 번째는 income_type과 occupy_type을 합쳐서 수입과 발생 유형을 나타내느 새로운 컬럼과 자동차와 부동산을 합친 두 범주형 컬럼을 만들었다.
- 그리고 분석에 유의미한 차이를 만들지 못하는 feature을 drop했다.
- 카드 발급 날짜를 기준으로 일한 개월 수를 나타내는 컬럼 생성
- 연속형 데이터의 단위를 조정했다.
![](https://velog.velcdn.com/images/xswer19/post/0aedaa54-900c-4e1b-be6b-b80ff10be6cc/image.png)
- 그리고 범주형 자료를 머신러닝에 돌리기 위해 LabelEncoder작업을 하고
![](https://velog.velcdn.com/images/xswer19/post/cd1ff4c4-e4f8-4f25-8b0b-b896713b37e9/image.png)
- x변수에는 Label를 제외한 데이터를, y에는 label값을 줬다.
- 그리고 train, test 데이터로 구분하고 위에 만든 함수로 결과를 확인했다.
![](https://velog.velcdn.com/images/xswer19/post/55053c01-5a62-4fc6-ad20-ccc04e263ad1/image.png)
- 기대한 만큼 썩 좋은 결과는 아니지만, 그래도 catBoost의 경우 꽤 낮은 log_loss값이 나왔다.
![](https://velog.velcdn.com/images/xswer19/post/cd21cae2-453b-48ff-8f07-f19855814b73/image.png)
- 각 feature의 중요도를 프레임으로 만들어서 보니 역시 연곡형 자료의 중요도가 높았다.
![](https://velog.velcdn.com/images/xswer19/post/754b21c0-eda4-4811-979c-81c2d92984a5/image.png)
- 그리고 catBoost의 경우 데이터셋에 따라 Parameter 값을 바꿔줘야해서 따로 parameter값을 주고 다시 돌려보니 log_loss값이 0.66으로 좋은 성능이 나왔다!
xgbm_result_loss: 0.8062094451587699
xgbm_result_ac : 0.712880650652544
lgbm_result_loss : 0.7933091701301722
lgbm_result_ac : 0.7062606393039531
log_loss : 0.6684856538442059
ac_score : 0.7359561187819179
![](https://velog.velcdn.com/images/xswer19/post/d426dac0-f0f6-4184-883a-203c1e4e297c/image.png)
- 이번에는 위에 한 작업 중 SSN데이터 과정만 제외하고 똑같이 데이터 처리 과정을 수행했다.
![](https://velog.velcdn.com/images/xswer19/post/2d114e8d-913c-482a-88bf-9e5d6e1ee32a/image.png)
- 그리고 함수를 통해 확인해보니 확실히 중복값을 제거해서 좋은 성능이 나왔다.
![](https://velog.velcdn.com/images/xswer19/post/e628fe09-9d73-47c5-aed1-97209fb02d9b/image.png)
- catBoost의 Parameter 값을 바꿔서 돌려보니 가장 좋은 0.61 성능이 나왔다.
xgbm_result_loss: 0.7335782866206809
xgbm_result_ac : 0.7662835249042146
lgbm_result_loss : 0.734862324234023
lgbm_result_ac : 0.7701149425287356
log_loss : 0.6175400500281912
ac_score : 0.7659352142110762
- 정확도도 77% 괜찮게 나왔고, 여기서 이 데이터를 끝냈다.
Credit_data 마무리
- 팀원과 함께 처음으로 수행한 프로젝트의 느낀점은 협업의 위대함이었다.
- 물론 소통과 커뮤니케이션 과정에서 시간과 노력 등 많은 부분을 소모해야했지만, 서로의 결과를 공유하고 매일 다른 측면의 분석이 발견됐다.
- 또한, 분석의 결과가 가장 좋은 데이터 전처리 및 모델링을 토대로 탑을 쌓는 과정처럼 층층이 노력해서 성능을 높여가면서 프로젝트의 매력을 느꼈다.
- 물론 많이 부족하지만, 해당 경험을 통해 앞으로 더 좋은 협업의 모습을 갖춰야겠다고 생각했다.
- 이제 해당 데이터를 마무리하고, 다른 금융 데이터셋을 통해 머신러닝을 돌려보자
8일차, New_Data
![](https://velog.velcdn.com/images/xswer19/post/28418362-df32-4669-adae-d8225d7e9c31/image.png)
- 기존의 데이터를 끝내고, 새로운 데이터를 분석 및 모델링 작업을 시작했다.
- 먼저 필요한 module을 불러왔다.
![](https://velog.velcdn.com/images/xswer19/post/8e326fee-1de4-4b4f-89c4-59f44884ce5b/image.png)
- 불러온 데이터의 각 feature에 대한 설명이다.
![](https://velog.velcdn.com/images/xswer19/post/e007e839-a9f1-4857-a5ed-8437fa26c384/image.png)
- 이제 데이터를 불러오고, 불러온 데이터를 프레임 형태로 정리했다.
![](https://velog.velcdn.com/images/xswer19/post/d5f9e7b0-9601-4c87-84e6-fdd9a3f8a699/image.png)
- 불필요한 feature를 drop하고, target 컬럼을 마지막에 배치했다.
![](https://velog.velcdn.com/images/xswer19/post/81a86700-9869-4294-bb2f-681f7aaa5f94/image.png)
- 데이터의 정보를 살펴보니 일단 결측값 즉 Nan은 없어보인다.
![](https://velog.velcdn.com/images/xswer19/post/13b6421f-2b99-4207-9dda-30e0e3aa0c0a/image.png)
- 데이터의 분포를 확인 및 모델 테스트를 위해 범주형 자료를 LabelEncoder를 통해 int형태로 변환했다.
- 그리고 target의 분포를 확인해보니 1 즉 떠나지 않은 고객의 데이터가 많이 있었다.
![](https://velog.velcdn.com/images/xswer19/post/e1f1c9d9-d104-4c32-9da0-62ad443b0d96/image.png)
- 그리고 target값에 대해 유의미한 차이를 만드는 feature이 있는지 확인하기 위해 상관계수를 확인한 결과 12개월 내에 거래 횟수가 많은 고객의 경우 이탈하지 않을 확률이 높게 나왔다
![](https://velog.velcdn.com/images/xswer19/post/6bfef912-dcce-4c48-ae7e-92c83555ce08/image.png)
- 그리고 각 Feature의 분포를 확인하기 위해 범주형 자료와 연속형 자료 리스트를 만들었다.
![](https://velog.velcdn.com/images/xswer19/post/a09920e5-cc22-40a2-87cb-c2c9ef80d4a2/image.png)
- 먼저 범주형 자료의 분포를 확인해보니 card_category데이터에서 platinum 고객의 데이터 다소 부족해보인다.
![](https://velog.velcdn.com/images/xswer19/post/337e3e6a-64ac-48a9-8023-cb66998c091d/image.png)
![](https://velog.velcdn.com/images/xswer19/post/34d38da0-a443-4fbb-8548-035ab95fe3f8/image.png)
![](https://velog.velcdn.com/images/xswer19/post/3b117b29-b46e-46e8-83ec-ff97f8ae53d7/image.png)
![](https://velog.velcdn.com/images/xswer19/post/b9798757-91ae-41de-b3a7-9ccf73191ca5/image.png)
- 연속형 자료의 경우 전체적으로 이상치 데이터는 없어보이나, 12개월 내 비활성화된 횟수에서 5와 6에 해당하는 데이터의 수가 상대적으로 부족해보인다.
![](https://velog.velcdn.com/images/xswer19/post/0e27cfe2-712e-44bc-b5b6-c92924845a3f/image.png)
- 그리고 target데이터를 시각화해보니 떠난 고객의 데이터가 확실히 부족하다.
![](https://velog.velcdn.com/images/xswer19/post/80956c60-b648-44b7-952c-a02dfd2a8bf7/image.png)
- 일단 기존의 데이터를 그대로 성능을 테스트하기 위해 train, test로 나눠주고
- 떠난 고객의 수가 부족하기 때문에 떠난 고객을 stratify 매소드를 이용해 같은 비율로 train, test에 할당했다.
- 확인해보니 정상적으로 구분되서 나뉘어졌다.
![](https://velog.velcdn.com/images/xswer19/post/f62c513a-e482-495a-a16d-ecdf4e76d678/image.png)
- 이제 4개의 모델 DecisionTree, RandomForest, xgbcBoost, lgbmBoost를 이용해 성능을 테스트하는 함수를 만들었다.
def print_modeling(x_train, x_test, y_train, y_test):
dc = DecisionTreeClassifier()
rf = RandomForestClassifier()
xb = XGBClassifier()
lg = LGBMClassifier()
acc = []
#DecisionTreeClassifier
params = {
"max_depth" : [3, 5, 7, 9, 11],
'random_state' : [13]
}
dc_grid_model = GridSearchCV(dc_model, param_grid=params, cv = 5, scoring='accuracy')
dc_grid_model.fit(x_train, y_train)
pred = dc_grid_model.predict(x_test)
acc.append(accuracy_score(y_test, pred))
dc_report = pd.DataFrame(classification_report(y_test, pred, output_dict=True)).transpose()
# RandomForest
params = {
"n_estimators" : [100, 500, 1000, 1500, 2000],
"max_depth" : [3, 5, 7 ,9],
"random_state" : [13]
}
rf_grid = GridSearchCV(rf, param_grid=params, cv=5, scoring="accuracy")
rf_grid.fit(x_train, y_train)
pred = rf_grid.predict(x_test)
acc.append(accuracy_score(y_test, pred))
rf_report = pd.DataFrame(classification_report(y_test, pred, output_dict=True)).transpose()
# xgbcBoost
params = {
"n_estimators" : [100, 500, 1000, 1500, 2000],
"max_depth" : [3, 5, 7 ,9],
"random_state" : [13]
}
xb_grid = GridSearchCV(xb, param_grid=params, cv=5, scoring="accuracy")
xb_grid.fit(x_train, y_train)
pred = xb_grid.predict(x_test)
acc.append(accuracy_score(y_test, pred))
xb_report = pd.DataFrame(classification_report(y_test, pred, output_dict=True)).transpose()
# lgbm
params = {
"n_estimators" : [100, 500, 1000, 1500, 2000],
'application' : ['binary'],
"max_depth" : [3, 5, 7, 9],
"random_state" : [13]
}
lg_grid = GridSearchCV(lg, param_grid=params, cv=5, scoring="accuracy")
lg_grid.fit(x_train, y_train)
pred = lg_grid.predict(x_test)
acc.append(accuracy_score(y_test, pred))
lg_report = pd.DataFrame(classification_report(y_test, pred, output_dict=True)).transpose()
df = pd.DataFrame(data={"accuracy" : acc})
df.rename(index={0 : "Decision", 1 : 'Randomforest', 2 : "XGBC", 3 : 'LGBMC'}, inplace = True)
return pd.DataFrame(data={"accuracy" : acc}), dc_report, rf_report, xb_report, lg_report
![](https://velog.velcdn.com/images/xswer19/post/c2f7a025-6c3b-401a-8ca4-144e4dafc41d/image.png)
- 어라라...정확도가 왜 이렇게 좋지...0에 대한 Precision이라도 성능을 높여봐야겠다...!
9일차, 0에 대한 Recall값 개선
- 9일차에는 0에 대한 recall값을 개선하기 위해 PCA, clustering, SMOTE 세 가지 기법을 사용했다.
![](https://velog.velcdn.com/images/xswer19/post/d1d6452a-0dc3-4dfd-a3c7-6c780ed6c59b/image.png)
- 먼저 기존의 데이터는 20개의 컬럼을 가지고 있다.
![](https://velog.velcdn.com/images/xswer19/post/7afab5e6-4fea-4c8c-90e0-d46e0c19c22e/image.png)
- 그리고 train데이터에 clustering을 형성하고, 학습시킨 내용을 통해 test데이터에도 군집을 형성했다.
- 일단 10개의 군집을 통해 0~9까지 군집을 만들었다.
- 군집 형성 데이터의 기준은 범주형 자료를 바탕으로 만들었다.
![](https://velog.velcdn.com/images/xswer19/post/b280a7a4-f987-4b64-997e-1f5cd4479340/image.png)
- test데이터에도 정상적으로 군집이 형성됐다.
![](https://velog.velcdn.com/images/xswer19/post/caec8fb2-3e11-4411-b08a-f0aac44ea2ab/image.png)
- 이번에는 PCA기법을 통해 연속형 데이터를 바탕으로 2개의 차원으로 축소해서 새로운 Feature를 만들었다.
- 그리고 train데이터로 학습한 내용을 바탕으로 test데이터도 2개 차원으로 만들었다.
![](https://velog.velcdn.com/images/xswer19/post/b2b6dc66-11dd-4c0c-b9ba-9463811afc13/image.png)
- train데이터를 확인 결과 두 개의 차원 데이터가 정상적으로 나왔고
![](https://velog.velcdn.com/images/xswer19/post/c69af8ab-bab9-4e2f-836c-cf4faad664b7/image.png)
- test데이터에도 2개의 차원이 정상적으로 만들어졌다.
![](https://velog.velcdn.com/images/xswer19/post/bbde1d24-1dbe-464c-8f47-0dbbe874026f/image.png)
- 정확도를 기준으로 결과를 확인해보니 0.01정도의 accuracy가 증가했다.
![](https://velog.velcdn.com/images/xswer19/post/b7e4e175-adda-4263-b857-e55d16f3e97a/image.png)
- 그리고 목적인 0에 대한 recall값은 0.01정도 올라갔으며, f1-score의 값은 0.01~0.02정도 올라갔다.
![](https://velog.velcdn.com/images/xswer19/post/63692a56-a74b-48bd-ab36-b91380b7ac52/image.png)
- 다음으로 0에 대한 train데이터를 SMOTE를 통해 0과 1에 대한 값을 똑같이 만들었다.
![](https://velog.velcdn.com/images/xswer19/post/844ca0cc-5571-4c60-96f6-a8ffba4f5423/image.png)
- accuracy값은 조금 떨어지고, lgbm의 결과에서 Recall값이 정말 조금 올라갔지만, 전체적인 0에 대한 Precision값이 크게 떨어짐
- 하지만, OverSampling을 통해 과적합이 해결될 수 있기 때문에 해당 Oversampling데이터로 성능 개선 시도
10일차, OverSampling데이터 성능 개선
![](https://velog.velcdn.com/images/xswer19/post/0f19e983-57e4-47af-a8a0-91355d021716/image.png)
- 이전의 만든 OverSamplig 데이터를 불러와 Label값의 counts확인 결과 정상적으로 나왔다.
![](https://velog.velcdn.com/images/xswer19/post/e9d26ba6-a92c-46c3-ac12-75baa0829f59/image.png)
- 먼저 Feature 중 필요없는 고객번호와 Binary형태의 성별을 제거 후 성능을 테스트했다.
![](https://velog.velcdn.com/images/xswer19/post/84d9970c-c9b5-4512-ae68-794986b752ba/image.png)
- 성능을 테스트한 결과 1%정도 떨어졌는데, 주관적인 생각에 성별이 영향을 미친 것 같다.
![](https://velog.velcdn.com/images/xswer19/post/3eb7bafa-7012-4fde-b571-098bd5dfe26b/image.png)
- 이제 성능을 테스트하기 전에 데이터를 불러오고, LabelEncoder작업과 Scale(Standard)작업을 진행했다.
- 그리고 train, test 데이터로 나눠주고
![](https://velog.velcdn.com/images/xswer19/post/c4b2a417-7b24-46ca-88c9-5a7fe11212ac/image.png)
- 이후 위에와 같이 Clustering과 PCA작업을 진행했다.
![](https://velog.velcdn.com/images/xswer19/post/a0661d6a-c5dc-419d-94c4-9a6ff4218dd4/image.png)
- 성능을 테스트한 결과 Scale값을 조정한다고 성능의 큰 개선이 이루어지지 않았다.
![](https://velog.velcdn.com/images/xswer19/post/23c69136-1718-4965-bbda-2ffbc735d6ca/image.png)
- 이번에는 cat_boost를 통해 성능을 테스트 한 후
![](https://velog.velcdn.com/images/xswer19/post/4c91e6e4-692a-4b15-b054-0a2a9b8b63cb/image.png)
- Feature 중요성을 확인해보니 5개의 Feature가 눈에 띄게 중요성을 보이기에 해당 5개의 Feature만 가지고 성능을 테스트해봤다.
![](https://velog.velcdn.com/images/xswer19/post/9e3c165c-b342-4519-ae44-1cb77105e781/image.png)
- 아무래도 Feature개수를 줄임으로써 성능이 다소 떨어졌다.
![](https://velog.velcdn.com/images/xswer19/post/9bb639e3-b2b6-476a-84da-18847738eecc/image.png)
- 결과적으로 기존의 데이터는 이탈 고객의 데이터가 부족한 상태에서 accuracy가 높기 때문에 과적합이 있을 수 있다.
- 그래서 PCA, Clustering, SMOTE_overSampling 등 방법을 사용해서 데이터의 수를 늘리고 성능을 유지하면서 결과를 도출했다.
![](https://velog.velcdn.com/images/xswer19/post/2cacf627-5533-497d-b2fb-e40df5ff7f50/image.png)