이전 포스트
2023.01.12 - [분류 전체보기] - 타이타닉 생존자 예측 분석 (3-2) 데이터 정리 - v.1.0.1
타이타닉 생존자 예측 분석 (3-2) 데이터 정리 - v.1.0.1
이전 포스트 2023.01.09 - [Kaggle/타이타닉] - 타이타닉 생존자 예측 분석 (3-1) 전처리 (나이예측) - v.1.0.1 타이타닉 생존자 예측 분석 (3-1) 전처리 (나이예측) - v.1.0.1 이전 포스트 2023.01.09 - [분류 전체
drewvvv.tistory.com
1. 데이터 인코딩
- 모델에 학습을 하기 위해선 사실 몇가지 준비가 필요하다.
- 모델에 학습시킬 데이터에 대한 내용인데,
- 1. 데이터프레임 안의 데이터는 숫자여야 하며(could not convert string to float)
- 이때 범주형 변수를 숫자로 나타내게될 때, 사실 서로 아무 의미가 없지만 모델이 의미를 갖는 경우가 생기는 것에 주의해야 한다. (참고링크)
- 위의 차이를 확인해보고자, 레이블 인코딩과 원핫 인코딩으로 비교 제출해 볼 것이다.
- 2. 원핫인코딩의 경우 값을 기준으로 분류하기 때문에, 값을 컬럼명으로 사용하는 경우가 발생한다.
- 이때 원핫인코딩은 컬럼명을 도출하지만, 각기 다른 컬럼에 값이 같은 경우 문제가 될 수 있으며,
- 가장 중요한 모델의 학습의 경우 컬럼명이 숫자인 경우 워링이 발생한다. (FutureWarning: Feature names only support names that are all strings. Got feature names with dtypes: ['int64'])
- 경우의 따라 숫자 컬럼명을 문자로 변경해주면 되긴하지만, 그것은 모델의 학습에 대해 의도한 바가 아니다.
- 3. scikit-learn의 onehot-encoding과 pandas의 get_dummies()
- 겉으로 보기엔 둘은 똑같은 역할을 하는 것처럼 보이지만 둘은 공통점과 명확한 차이가 존재한다.
- 우선 공통점을 보자면 두 메서드는 각 값에 해당하는 컬럼을 새로 생성한 후 컬럼에 해당하는 값일 경우 1 아닐 경우 0으로 둔다. (참고링크)
- 히지만 명확한 차이는 모델 학습에서 들어난다.
- 판다스의 get_dummies()는 그저 위의 공통사항을 분류만 할 뿐이지만,
- 사이킷 런의 원핫인코딩은 train 데이터 셋에 맞게 test 셋을 맞추는 것이다.
- 이 차이를 다시 풀자면, train 셋에는 해당하는 컬럼이 없지만 test 셋에는 컬럼이 있을 경우 모델은 학습을 할 수 없어 에러가 나게된다.
- 하지만 원핫인코딩의 경우 데이터 뿐만이 아니라, 컬럼명까지 참조하기 때문에 get_dummies()와 같은 문제가 발생하지 않는다. (단 encoding시 handle_unknown='ignore' 파라미터 추가 필요)
- 하지만 get_dummies()도 위의 문제를 해결하고 사용할 수 있는 방법이 있는데, 파이프라인을 구축하여 encoding시 원핫인코딩의 handle_unknown 기능을 간접적으로 구현하는 방법이 있다. (참고링크)
- (이외의 다른 차이도 존재하지만 생략)
- 1. 데이터프레임 안의 데이터는 숫자여야 하며(could not convert string to float)
- 따라 본 v1.0.1 버전에선 다음과 같은 계획을 갖고 비교해가며 모델 학습을 진행한다.
- 인코딩 방법간의 차이를 살펴보기 위해 모델은 RandomForest로 고정한다.
- 1. 앞의 (3-2) 데이터 정리 포스트에서 변수를 숫자 범주형(레이블 인코더)으로 변환한 데이터를 그대로 학습 후 제출
- 2. 숫자 범주형을 사용하지 않고 범주형 데이터를 원핫인코딩 후 제출
위의 1번의 경우 데이터 셋을 불러온다.
|
1
2
3
4
5
6
|
import pandas as pd
import numpy as np
noNaTrain = pd.read_csv("../input/noNa_train - v1.0.1.csv")
noNaTest = pd.read_csv("../input/noNa_test - v1.0.1.csv")
gender = pd.read_csv("../input/gender_submission.csv")
|
cs |
|
1
2
3
4
5
|
feature_1 = ['Survived','Pclass','ca_Sex','ca_Age', 'SibSp', 'Parch','ca_designation']
train_data = noNaTrain[feature_1[1:]].copy()
target = noNaTrain['Survived'].copy().values
test_data = noNaTest[feature_1[1:]].copy()
|
cs |
- Fare 컬럼을 사용하지 않고 위와 같이 featrue_1을 구성한다.
- 모델에 학습시킬 train_data는 Survived를 제외, target은 Survived를 사용

|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(train_data, target, test_size = 0.2, random_state=42)
model = RandomForestClassifier()
model.fit(X_train, y_train)
accuracy = round(model.score(X_test, y_test) * 100, 2)
print(f"accuracy of {type(model).__name__}: {str(accuracy)}%")
predict = model.predict(test_data)
submission_df = pd.DataFrame({'PassengerId':noNaTest['PassengerId'],
'Survived':predict})
# submission_df.head()
submission_df.to_csv(f'sbn_{type(model).__name__ }_labeling.csv', index=False)
print(f"name of export submission : sbn_{type(model).__name__}_labeling.csv")
|
cs |

- 분류모델에 별다른 하이퍼 파라미터 수정하지 않고,
- 위의 train_data는 변수들을 라벨링한 후의 결과 값으로 80.45%의 정확도를 보였다.


- 하지만 실제 스코어는 0.5933으로 매우 낮았다.
이제 2번의 계획인 onehot encoding을 사용해 본다.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# test for one hot encoding
feature_2 = ['Survived', 'Pclass', 'Sex', 'ca_Age', 'SibSp', 'Parch', 'designation']
train_data2 = noNaTrain[feature_2[1:]].copy()
target = noNaTrain['Survived'].copy().values
test_data2 = noNaTest[feature_2[1:]].copy()
for df in [train_data2, test_data2]:
for col in ['Pclass', 'ca_Age', 'SibSp', 'Parch']:
for index, item in enumerate(df[col]):
df.loc[index, col] = col+ '_' + str(item)
|
cs |
- 우선 feature의 경우 기존 feature_1 = ['Survived','Pclass','ca_Sex','ca_Age', 'SibSp', 'Parch','ca_designation'] 에서
- ca_Sex를 Sex로, ca_designation은 designation으로 사용하고 나머지 컬럼은 앞의 prefix를 붙혀 데이터를 변환한다.
- 데이터 변환 결과는 아래와 같다.

|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# https://towardsdatascience.com/stop-using-pandas-get-dummies-for-feature-encoding-5d2cd07cb4fc
# https://pythonsimplified.com/difference-between-onehotencoder-and-get_dummies/
from sklearn.preprocessing import OneHotEncoder
# one hot encoding
enc = OneHotEncoder(sparse=False, handle_unknown='ignore')
onehot = enc.fit_transform(train_data2[feature_2[1:]])
columns = list([j for i in enc.categories_ for j in i])
#to print the encoded features for train data
trainOneHotDf = pd.DataFrame(onehot, columns=columns)
train_data2 = trainOneHotDf.copy()
# tranform encoding for test data
test_onehot = enc.transform(test_data2[feature_2[1:]])
#to print the encoded features for train data
testOneHotDf = pd.DataFrame(test_onehot, columns=columns)
test_data2 = testOneHotDf.copy()
|
cs |
- 위 코드를 살펴보면 enc를 통해 train_data가 fit_transform되었고 , onehot array를 실제 columns와 매핑하여 trainOneHotDf를 생성하였다.
- testOneHotDf의 경우는 train_data2의 컬럼을 기준으로 학습된 enc를 적용하여 transform해서 test셋에는 있지만 train 셋에는 없어서 학습할 수 없는 경우가 발생하지 않도록 unknown 컬럼은 ignore 시키도록 파라미터를 추가하였다.


- 위를 바탕으로 feature들이 onehot-encoding된 것을 확인할 수 있다.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
X_train, X_test, y_train, y_test = train_test_split(train_data2, target, test_size = 0.2, random_state=42)
model = RandomForestClassifier()
model.fit(X_train, y_train)
accuracy = round(model.score(X_test, y_test) * 100, 2)
print(f"accuracy of {type(model).__name__}: {str(accuracy)}%")
predict = model.predict(test_data2)
submission_df = pd.DataFrame({'PassengerId':noNaTest['PassengerId'],
'Survived':predict})
# submission_df.head()
submission_df.to_csv(f'sbn_{type(model).__name__ }_onehot.csv', index=False)
print(f"name of export submission : sbn_{type(model).__name__}_onehot.csv")
|
cs |

- 분류모델에 별다른 하이퍼 파라미터 수정하지 않고,
- 위의 train_data는 변수들을 onehot-encoding한 후의 결과 값으로 82.68%의 정확도를 보였다.


- 단지 onehot-encoding만 실시하였지만 score가 확연히 차이나는 것을 확인할 수 있다.
- 이는 모델이 학습시에 데이터를 올바르게 읽지 못하고 연속된 값이 연관이 있다고 판단하여 생기는 문제이다.
- 따라 데이터 전처리의 경우 각 데이터의 특성에 따른 적절한 전처리를 할 필요가 있다.
다음 포스트
TBW
'Kaggle > 타이타닉' 카테고리의 다른 글
| 타이타닉 생존자 예측 분석 (3-2) 데이터 정리 - v.1.0.1 (0) | 2023.01.12 |
|---|---|
| 타이타닉 생존자 예측 분석 (3-1) 전처리 (나이예측) - v.1.0.1 (0) | 2023.01.09 |
| 타이타닉 생존자 예측 분석 (2-3) EDA(상관관계 및 기타) - v.1.0.1 (0) | 2023.01.09 |
| 타이타닉 생존자 예측 분석 (2-2) EDA(연령대별) - v.1.0.1 (0) | 2023.01.05 |
| 타이타닉 생존자 예측 분석 (2-1) EDA(성별) v.1.0.1 (0) | 2023.01.04 |
| 타이타닉 생존자 예측 분석 (1) 개요 (0) | 2023.01.04 |


