머신러닝 전처리, Categorical variable 처리법
회귀분석 모델이 제대로 작동하기 위해서는 변수값들이 서로 order를 가져야만 한다. 하지만 categorical variable은 모델이 사용할만큼 그 order가 명시적이지 않다. categorical variable는 두가지로 나뉠 수 있다. 하나는 category 사이에 order가 있는경우, 나머지는 그렇지 못한 경우다. 전자의 경우는 각 category를 해당하는 order로 encoding하는 방법이 있다. 후자의 경우도 조금 복잡한 전처리 과정을 거쳐서 모델이 사용가능한 데이터로 encoding이 가능하다.
방법 1: Drop
그냥 버려서 모델에 노이즈로 작용하지 않게 한다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pandas as pd | |
#data : 전처리할 DataFrame | |
preproccessed_data = data.select_dtypes(exclude=['object'])#object 타입을 제외한 DataFrame을 생성해 반환, 타입은 object-float64-int64가 있다 |
방법 2: Ordinal Encoding
category가 자체적인 order를 가진 경우에만 사용가능한 방법이다. 각 category를 해당하는 order로 encoding 한다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pandas as pd | |
from sklearn.preprocessing import OrdinalEncoder | |
# Categorical columns | |
object_cols = [col for col in train_data.columns if train_data[col].dtype == "object"] | |
# valid_data에서의 value set이 train_data에서의 value set의 부분집합인 column들, train_data에 fit된 encoder를 사용하기위한 필요조건이다. | |
good_cols = [col for col in object_cols if set(valid_data[col]).issubset(set(train_data[col]))] | |
ordinal_encoder = OrdinalEncoder() | |
label_X_train[good_label_cols] = ordinal_encoder.fit_transform(train_data[good_label_cols]) | |
label_X_valid[good_label_cols] = ordinal_encoder.transform(valid_data[good_label_cols]) |
방법 3 : One-Hot Encoding
category가 order를 가지지 않는 경우를 위한 방법이다. 각 category별로 column을 만들고 column의 value가 (original value == category)에 대한 boolean value를 가지도록 encoding 한다. 이러면 각 column은 boolean value를 가지기 때문에 회귀분석모델에서 충분히 이용 가능하다. 다만 category 수가 많아지면 data의 column이 너무 많아지게 된다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pandas as pd | |
from sklearn.preprocessing import OneHotEncoder | |
#너무 많은 차원으로 분리되지 않을 컬럼들만 인코딩한다. | |
low_cardinality_cols = [col for col in object_cols if X_train[col].nunique() < 10] | |
encoder = OneHotEncoder(handle_unknown='ignore', sparse=False) | |
OH_cols_train = pd.DataFrame(encoder.fit_transform(X_train[low_cardinality_cols])) | |
OH_cols_valid = pd.DataFrame(encoder.transform(X_valid[low_cardinality_cols])) | |
#인코딩하면 df의 index가 초기화된다. 다시 입력해주자 | |
OH_cols_train.index = X_train.index | |
OH_cols_valid.index = X_valid.index | |
#각 column 이름이 ascent int로 부여된다. column이름이 int면 model fit할때 경고가 뜬다. | |
#column이름을 각 column이 의미하는 카테고리로 이름을 바꿔주자. | |
OH_cols_train.columns = OH_encoder.get_feature_names_out() | |
OH_cols_valid.columns = OH_encoder.get_feature_names_out() | |
#일단 모든 object 컬럼을 제거한다. | |
num_X_train = X_train.drop(object_cols, axis=1) | |
num_X_valid = X_valid.drop(object_cols, axis=1) | |
#인코딩된 컬럼 붙여주기 | |
OH_X_train = pd.concat([num_X_train, OH_cols_train], axis=1) | |
OH_X_valid = pd.concat([num_X_valid, OH_cols_valid], axis=1) |
댓글
댓글 쓰기