[Study]Category, One-Hot encoding이 모델에 미치는 영향 테스트
Kaggle 에서 notebook들을 보다보면 학습 데이터를 만들때 범주형 데이터를 사용하는 방법이 다 다릅니다.
One-Hot encoding을 주로 사용했는데 이번에 시계열 데이터를 다루면서 날짜별로 One-Hot encoding을 진행하면 Feature 의 수가 너무너무 많아져 이 부분에 대해 관심가지게 됐습니다.
그래서
- 변주형 변수를 아무 처리 하지않고 그냥 사용
- 변주형 변수를 category 타입으로 변경해 사용
- 변주형 변수를 One-Hot encoding 한 후 사용
이 3가지 방법이 모델에 미치는 영향을 테스트 해봅시다.
데이터 준비
-
테스트에 사용할 데이터는 Kaggle 에 있는 Titanic을 사용합니다.
-
이전 포스팅 에서 Titanic 전처리를 다뤘기 때문에 전처리 과정은 생략합니다.
-
범주형 변수는
Pclass
,Sex
,Embarked
,Title
을 사용합니다.
1. 아무 처리를 하지 않은 데이터 셋 (normal_train)
normal_train.info()
-------------------------------------
0 Pclass 891 non-null int64
1 Sex 891 non-null int32
2 Age 891 non-null int32
3 SibSp 891 non-null int64
4 Parch 891 non-null int64
5 Fare 891 non-null int32
6 Embarked 891 non-null int32
7 Title 891 non-null int32
8 Familysize 891 non-null int64
2. category 탑으로 변경 (cg_train)
cg_train.info()
-------------------------------------
0 Pclass 891 non-null category
1 Sex 891 non-null category
2 Age 891 non-null int32
3 SibSp 891 non-null int64
4 Parch 891 non-null int64
5 Fare 891 non-null int32
6 Embarked 891 non-null category
7 Title 891 non-null category
8 Familysize 891 non-null int64
3. One-Hot encoding (oh_train)
oh_train.info()
-------------------------------------
0 Age 891 non-null int32
1 SibSp 891 non-null int64
2 Parch 891 non-null int64
3 Fare 891 non-null int32
4 Familysize 891 non-null int64
5 Pclass_1 891 non-null uint8
6 Pclass_2 891 non-null uint8
7 Pclass_3 891 non-null uint8
8 Sex_0 891 non-null uint8
9 Sex_1 891 non-null uint8
10 Embarked_0 891 non-null uint8
11 Embarked_1 891 non-null uint8
12 Embarked_2 891 non-null uint8
13 Title_0 891 non-null uint8
14 Title_1 891 non-null uint8
15 Title_2 891 non-null uint8
16 Title_3 891 non-null uint8
17 Title_4 891 non-null uint8
K-Fold 교차검증(Random Forest)
- 모델은 Random Forest의 default 값을 사용합니다.
- K-Fold 교차 검증을 통해 정확도를 측정해 비교합니다.
1. 아무 처리를 하지 않은 데이터 셋 (normal_train)
In
model = RandomForestClassifier()
score1 = cross_val_score(model, normal_train, target, cv=kfold, scoring='accuracy')
mean1 = score1.mean()
print(f'normal train 의 정확도는 {mean1 * 100 :.2f}% 입니다.')
Out
normal train 의 정확도는 80.26% 입니다.
2. category 탑으로 변경 (cg_train)
In
model = RandomForestClassifier()
score2 = cross_val_score(model, cg_train, target, cv=kfold, scoring='accuracy')
mean2 = score2.mean()
print(f'category train 의 정확도는 {mean2 * 100 :.2f}% 입니다.')
Out
category train 의 정확도는 80.71% 입니다.
3. One-Hot encoding (oh_train)
In
model = RandomForestClassifier()
score3 = cross_val_score(model,oh_train, target, cv=kfold, scoring='accuracy')
mean3 = score3.mean()
print(f'one-hot encoding train 의 정확도는 {mean3 * 100 :.2f}% 입니다.')
Out
one-hot encoding train 의 정확도는 80.37% 입니다.
- 정확도가 차이나 보이지만 판단을 하기가 애매합니다.
실행할 때 마다 값이 달라지기 때문..- 혹시 모르니까 모델을 바꿔서 진행해봅니다.
K-Fold 교차검증(Support VectorClassification)
- SVC (Support Vector Calssification) 을 이용해 테스트 해봅니다.
1. 아무 처리를 하지 않은 데이터 셋 (normal_train)
In
model = SVC()
score1 = cross_val_score(model, normal_train, target, cv=kfold, scoring='accuracy')
mean1 = score1.mean()
print(f'normal train 의 정확도는 {mean1 * 100 :.2f}% 입니다.')
Out
normal train 의 정확도는 82.50% 입니다.
2. category 탑으로 변경 (cg_train)
In
model = SVC()
score2 = cross_val_score(model, cg_train, target, cv=kfold, scoring='accuracy')
mean2 = score2.mean()
print(f'category train 의 정확도는 {mean2 * 100 :.2f}% 입니다.')
Out
category train 의 정확도는 82.50% 입니다.
3. One-Hot encoding (oh_train)
In
model = SVC()
score3 = cross_val_score(model,oh_train, target, cv=kfold, scoring='accuracy')
mean3 = score3.mean()
print(f'one-hot encoding train 의 정확도는 {mean3 * 100 :.2f}% 입니다.')
Out
one-hot encoding train 의 정확도는 83.40% 입니다.
- SVC 에서는 One-Hot encoding 을 진행한 데이터셋이 약간더 높은 정확도를 보였습니다.
- category 타입은 효과를 보지 못했습니다.
결과
-
범주형 변수를 int 로 사용하나 category 로 사용하나 One-Hot encoding을 사용하나 Score에는 큰 영향을 주지 못했습니다.
-
그래도 SVC 모델에서는 근소한 차이를 보였습니다.
-
괜히 있는 기능이 아닐텐데 뭔가 이상합니다.
-
생각해 볼 수 있는 점은
- 데이터의 양이 적다.
- Feature 의 영향이 크지 않다.
- Feature 의 개수가 변화를 줄 정도로 크지않다.
- 모델마다 영향을 받는 정도는 다르다.
-
결론 : One-Hot encoding 은 아주 약간의 성능 향상을 기대 해 볼 수 있는 것 같습니다. category 타입은 의미 없는것 같습니다. 전체적으로 큰 성능향상은 모르겠습니다.
뭔가 뻘짓을 한 것 같지만 궁금증은 어느정도 해소됐습니다. 이 부분은 추가로 알게된 사실이 있다면 내용추가를 할 예정입니다.