데이터 분석을 공부하거나 프로젝트에 적용할 때, 그리고 빅데이터 분석기사를 준비할 때
string타입의 범주형 변수를 보면 습관적으로 labelencoder를 쳤다.
그럴때마다 종종 train데이터 셋에서 fit_transform한 encoder를 test데이터셋에 transform할 때면,
train데이터셋에서 없었던 범주(class)가 나와 오류가 뜨곤 했다.
뭐 당연히 split하기 전에 먼저 encoding 했으면 좋았겠지만,
처음부터 train과 test가 따로 제공되기도 하고 test에는 target 변수가 없는 상태로 주어지기에
각각의 파일로 제공이 된다.
그래서 가끔 이런 오류를 보면 답답했다. 왜 예외값을 처리하는 옵션은 없는가!
(우물 안 개구리였다.)
LabelEncoder
https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html
공식 문서를 보면
" This transformer should be used to encode target values, i.e. y, and not the input X. "
라고 쓰여있는 것을 볼 수 있는데,
LabelEncoder는 input x값을 위한 transformer가 아닌, target변수 y를 위한 transformer라는 것.
처음 알았다.
그래서 LabelEncoder의 attribute에는 classes_ 라는 옵션이 있었다.
이게 target변수의 class를 의미하는 것이다.
le = LabelEncoder()
le.fit(["paris", "paris", "tokyo", "amsterdam"])
## LabelEncoder()
list(le.classes_)
## [np.str_('amsterdam'), np.str_('paris'), np.str_('tokyo')]
le.transform(["tokyo", "tokyo", "paris"])
## array([2, 2, 1]...)
list(le.inverse_transform([2, 2, 1]))
## [np.str_('tokyo'), np.str_('tokyo'), np.str_('paris')]
OrdinalEncoder
https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OrdinalEncoder.html#
OrdinalEncoder의 공식문서를 보면
인자로 handle_unknown이나 unknown_value를 설정할 수 있다.
- handle_unknown : ['error', 'use_encoded_value'] 중에 사용가능, default : 'error'
default인 'error' 설정 시, unknown categorical transform시 error를 유발하도록 한다.
'use_encoded_value'로 설정 시, unknown_value 파라미터에 설정된 값으로 category 값이 정해진다. - unknown_value : default : None
transform시, fit에서 미리 학습한 class가 없다면 어떤값으로 대체할 건가 에 대한 파라미터.
다른 카테고리여도 fit에서 학습되지 않았던 category면 동일한 값으로 transform된다. - encoding_missing_value : default : np.nan
NaN 으로 설정된 값의 경우, 어떤 값으로 대체할 것인가 에 대한 파라미터.
oe = OrdinalEncoder(handle_unknown="use_encoded_value",
unknown_value=99,
encoded_missing_value=-1)
oe.fit(["paris", "paris", "tokyo", "amsterdam"])
oe.categories_
## [array(['amsterdam', 'paris', 'tokyo'], dtype= object)
oe.transform(["seoul", "tokyo", "paris", NaN])
## array([99, 2, 1, -1])
입력변수를 인코딩할 때는, OrdinalEncoder를 사용할 것!
** 주의 **
이렇게 사용하다가
OrdinalEncoder로 바꾸고 싶어 Encoder이름만 수정했는데, 오류가 났다.
LabelEncoder는 Series형식으로 인자 입력이 가능,
OrdinalEncoder는 Array형식으로 인자 입력이 가능하다.
그래서 기존 코드에서 수정을 하려면, 대괄호를 두개 붙여 DataFrame형식으로 바꿔주어야 한다.
'Python' 카테고리의 다른 글
[Python] 함수 내 함수 (0) | 2024.10.04 |
---|---|
[Python] 파이썬 기초 자료형 Tuple, Set 비교 (0) | 2024.08.20 |
주피터 실행결과 출력문 생략 (0) | 2024.08.01 |
[Python] sklearn 설치하기 (0) | 2024.08.01 |
VScode 에서 주피터 노트북 가상환경 (1) | 2024.08.01 |