범주형 변수는 상태 공간의 크기가 유한한 변수를 의미하며, 반드시 도메인이나 변수의 상태 공간을 바탕으로 판단.
데이터에 범주형 변수가 포함되어 있어, 대다수의 지도 학습 모델이 학습되지 않거나 비정상적으로 학습되는 문제.
모델 학습을 위해 변주형 변수는 반드시 숫자로 변환.
더미화
가장 일반적으로 범주형 변수를 변환하는 방법.
- 간편히 쓸 수 있다.
- 범주 변수가 많으면 컬럼이 많아질 수 있다.
- 희소성 : 한 변수가 가지는 변수가 많아지면 변수가 희소해진다.
연속형 변수로 치환
- 범주형 변수의 상태 공간 크기가 클 때, 더미화는 과하게 많은 변수를 추가해서 차원의 저주 문제로 이어질 수 있음.
- 라벨 정보를 활용하여 범주 변수를 연속형 변수로 치환하면 기존 변수가 가지는 정보가 일부 손실될 수 있고 활용이 어려움.
- 차원의 크기가 변하지 않으며 더 효율적인 변수로 변환 가능.
OneHotCategoricalEncoder
from feature_engine.categorical_encoders import OneHotCategoricalEncoder as OHE
에러 발생 시, feature_engine 지우고 0.6.1버전으로 다시 다운로드 해야한다.
# 삭제
pip uninstall feature_engine
# 다시 설치
pip install feature_engine==0.6.1
더미화를 하기 위한 함수로 sklearn의 인스턴스의 방법과 유사
주요인자
다음과 같은 데이터가 있다.
데이터를 데이터와 라벨로 나누고 학습/평가 데이터로 분리시키자.
# 특징과 라벨 분리
X = df.drop('Class', axis = 1)
Y = df['Class']
# 학습 데이터와 평가 데이터 분리
from sklearn.model_selection import train_test_split
Train_X, Test_X, Train_Y, Test_Y = train_test_split(X, Y)
분리시킨 데이터의 '라벨'을 확인해보니 P/N로 되어 있다.
더미화가 아닌 숫자로 대체하도록 하자.
# 문자 라벨을 숫자로 치환
Train_Y.replace({"negative":-1, "positive":1}, inplace = True)
Test_Y.replace({"negative":-1, "positive":1}, inplace = True)
위에서 보았듯이 data는 범주형 변수로 보이는데 확인해 보면, 모든 변수가 범주형임을 알 수 있다.
더미화를 위해 str 타입으로 바꿔주자.(OneHotCategoricalEncoder는 str 타입에서만 작동)
Train_X = Train_X.astype(str) # 모든 변수가 범주이므로, 더미화를 위해 전부 string 타입으로 변환
그리고 OneHotCategoricalEncoder 불러와서 학습하여 적용시켜 보자.
from feature_engine.categorical_encoders import OneHotCategoricalEncoder as OHE
# 인스턴스화
dummy_model = OHE(variables = Train_X.columns.tolist(), # variables : 리스트 형태로 컬럼을 입력을 받는다.
drop_last = True)
# 학습
dummy_model.fit(Train_X)
# 적용
d_Train_X = dummy_model.transform(Train_X)
d_Test_X = dummy_model.transform(Test_X)
적용된 데이터를 확인해 보면 더미화가 적용된 것을 볼 수 있다.
이제 새로운 데이터가 추가되더라도 이 더미 모델을 활용하여 똑같은 방식으로 더미화를 할 수 있게 된다.
class 컬럼을 기준으로 범주형 변수를 연속형 변수로 치환해보자.
'data'와 'label'로 나눈 데이터를 다시 합쳐주고,
Train_df = pd.concat([Train_X, Train_Y], axis = 1) # 옆으로 이어붙임
각 컬럼의 해당 변수들에 대한 class의 평균값으로 바꿔준다.
for col in Train_X.columns: # 보통은 범주 변수만 순회
temp_dict = Train_df.groupby(col)['Class'].mean().to_dict() # 해당 col의 변수에 따른 Class의 평균을 나타내는 사전 (replace를 쓰기 위해, 사전으로 만듦)
Train_df[col] = Train_df[col].replace(temp_dict) # 변수 치환
Test_X[col] = Test_X[col].astype(str).replace(temp_dict) # 테스트 데이터도 같이 치환해줘야 함 (나중에 활용하기 위해서는 저장도 필요)