본문 바로가기

Data Handling/Data Preprocessing

범주형 변수 처리 - 인코딩(Encoding)

다음과 같은 데이터 프레임이 있다고 가정해봅시다.

흔히 'subject'와 같은 값의 형태를 가진 변수를 '범주형 변수',

'score'와 같은 값의 형태를 가진 변수를 '수치형 변수'라고 합니다.

 

'범주형 변수'의 경우, 모델링을 하기 전에 컴퓨터가 이해하기 쉬운 숫자의 형태(정수형)로 인코딩해야 하는데, 

오늘은 그 방법에 대해서 정리해보겠습니다.

 

 

순서

  • Label encoding
  • One hot encoding
  • get_dummies()
  • factorize()

 


 

● Label encoding

문자형을 정수형으로 인코딩하는 과정입니다.

예를 들어 'english', 'korean', 'math'를 0, 1, 2 처럼 변환시키는 것입니다. 

from sklearn.preprocessing import LabelEncoder

encoder = LabelEncoder()
df_c['subject'] = encoder.fit_transform(df_c['subject'].values)

 

인코딩 값에 대한 원본값을 알고 싶을때에는 .classes_

인코딩 되기 전으로 되돌리고 싶을 때에는 inverse_transform() 을 사용하면 됩니다.

display(encoder.classes_)
display(encoder.inverse_transform(df_c['subject']))

 

하지만 레이블 인코딩에는 주의할 점이 있습니다.

숫자의 특성 때문에 가중치의 차이가 생기는 점인데요, 'english'와 'science'의 중요도는 똑같은 반면에 인코딩을 하고 난 후에는 더 큰 숫자로 인코딩 된 'science'의 중요도가 높아졌습니다.

 

트리 기반 알고리즘에서는 숫자의 크기에 따른 중요도 차이가 없지만,

그 외의 선형적 특징을 가지는 알고리즘들은 차이가 있기 때문에 one hot encoding 을 통해 해결해줍니다.

 

 

● One hot encoding

label encoding이 선행되어야 합니다.

레이블 인코딩으로 할당된 숫자를 각 열을 추가해서 0또는 1로 나타내었습니다.

다시 한번 강조하지만 이 과정은 숫자의 크고 작은 특성(중요도)을 없애기 위함입니다. 

from sklearn.preprocessing import OneHotEncoder

oh_encoder = OneHotEncoder(sparse=False) # sparse 매개변수가 없다면 oh_df.toarray()를 해야함
oh_df = oh_encoder.fit_transform(np.array(df_c['subject']).reshape(-1,1)) # 인코딩 하기 전에 2차원 데이터로 변환

onehot_df = pd.DataFrame(oh_df, columns = ["subject_"+str(int(i)) for i in range(oh_df.shape[1])])
df_result = pd.concat([df_c, onehot_df], axis=1)

 

원 핫 인코딩을 할 때에는 두 가지를 조심해야 합니다.

첫 번째로는 Label encoding을 선행하여 모든 문자열 값이 숫자형으로 변환되어 있어야 하는 것이고,

두 번째로 입력값으로 2차원 데이터가 필요하다는 점입니다. (.reshape() 활용)

 

● get_dummies()

LabelEncoder() + OneHotEncoder() = get_dummies()

지금까지의 과정을 한 번에 모두 처리해주는 함수가 get_dummies() 입니다.

판다스의 내장함수이기 때문에 별다른 설치 없이 바로 실행가능 합니다.

pd_df = pd.get_dummies(df['subject'])
df_result = pd.concat([df, pd_df], axis=1)

 

 

● factorize()

LabelEncoder() 와 같음

이것 역시 판다스의 내장함수이므로 별도의 설치가 필요하지 않습니다.

factorize() 함수는 두 개의 값을 반환하는데, 인코딩된 값인코딩된 범주입니다.

encoded_value, encoded_class = pd.factorize(df['subject'])
df['encoded_value'] = encoded_value

 

* 참고

 

 


 

 

결과

  • get_dummies() 함수를 사용하는게 가장 빠르다.

  • get_dummies() = (LabelEncoder() + OneHotEncoder()) or (factorize() + OneHotEncoder)

  • LabelEncoder() = factorize()