범주형 변수의 인코딩 방법

정형 데이터에서 범주형 변수를 처리하는 방법은 되게 까다롭습니다. 이번 포스팅에서는 제가 알고 있는 범주형 변수들에 대해서 설명하고 어떤 의미를 가지고있는지에 대해 작성해보도록 하겠습니다. 먼저 범주형 변수란 일종의 카테고리를 가지는 변수를 의미합니다. 예를들어 식물의 종도 일종의 카테고리가 되고 음식점의 종류 등 어떠한 집단을 의미하는 변수들을 의미합니다. 이러한 변수들은 컴퓨터가 인식할 수 없기에 인식할 수 있도록 인코딩을 해주는 작업이 필요합니다. 대표적으로 많이 알려진 인코딩 기법으로는 One-Hot Encoding, Label Encoding, Frequency Encoding, Target Encoding 등이 있습니다.

 

먼저, One-Hot Encoding은 일종의 변수를 1과 0으로 나누는 방법입니다. 해당 값이 존재하는 경우는 1로 그렇지 않은 경우는 0으로 만드는 것입니다. 예를 한번 들어보겠습니다. 범주형 변수는 애완동물의 종이고 사람은 아래와 같이 5명이 있는 상황입니다. 

 

Id 애완동물의 종
1
2 고양이
3
4
5 고양이, 개

 

위와 같은 상황에서 One-Hot Encoding을 적용하면 아래와 같은 표가 만들어집니다. 

Id 고양이
1 1 0
2 0 1
3 1 0
4 1 0
5 1 1

즉, id 1, 3, 4와 같이 개를 애완동물로 키우는 사람들은 "개"라는 변수가 새로 생겨서 1의 값을 가지고 id 2, 5와 같이 고양이를 키우는 사람은 "고양이" 변수에 1의 값을 가집니다. 그리고 id 5를 보면 알겠지만 둘 모두 키우는 사람에는 두 변수 모두 1의 값을 가지는 특징이 있습니다. 참고로 키우지 않은 애완동물의 종에 대해서는 0을 가지는 것도 확인할 수 있습니다.  

 

이와 같이 One-Hot Encoding으로 인코딩을 하면 장점은 컴퓨터가 변수의 의미를 "정확"하게 파악한다는 점입니다. 단순하게 변수가 "존재한다" vs "존재하지 않는다"의 의미를 가지니 원 의미 그대로 컴퓨터에게 전달할 수 있는 장점이 있습니다. 그런데 이렇게 당연한 의미가 왜 장점이 되는 것일까요? 사실 컴퓨터에게 위와 같이 전달하기 쉽지 않기 때문입니다. 애완동물의 종이 2개인 경우에는 One-Hot Encoding을 수행하면 변수가 2개밖에 생성되지 않습니다. 하지만 종이 100개, 1000개, 10000개가 넘어서 수백만이면 어떨까요? 그럴때 One-Hot Encoding을 수행하면 변수만 수백만이 되게 되고 엄청나게 Sparse한 행렬이 만들어지게 될 것입니다. 이렇게되면 메모리의 측면에서 좋지 않고 모델도 돌기 쉽지 않을 것입니다. 

 

그래서 차선으로 나온 생각이 컬럼의 수는 1개로 유지하되 각각의 종이 다른 값을 가지고 있다라는 의미를 부여해보면 어떨까? 입니다. 즉, 개는 1번 고양이는 2번, 새는 3번, 거북이는 4번, ...., 무당벌레는 1000만번 이런 식으로 종마다 다른 번호를 부여해주면 하나의 컬럼으로도 모든 종을 표현할 수 있게 됩니다. 

 

Id 애완 동물의 종 
1 1
2 2
3 1
4 1
5 3

 

이러한 방법은 각각의 값에 숫자를 부여해준다고 해서 Label Encoding 이라고 부릅니다. 하지만, 이러한 라벨인코딩의 단점은 모델이 이 숫자의 순서를 특징으로 인식할 수도 있다는 것입니다. 개와 고양이의 경우를 다시 보겠습니다. Tree 모델의 경우 모델을 Split할때 어떤 수치를 기준으로 왼쪽과 오른쪽으로 나누게 될 것입니다. 하지만, 이러한 수치는 단순 종을 분류한건데 1000만번 종의 왼쪽에 속하는 값은 ~~한 특징을 가지고 1000만번 종의 오른쪽에 속하는 값은 ~~한 특징을 가집니다. 이런 식으로 해석하는게 옳을까요? 물론 트리가 복잡해지면 복잡해질 수록 위와 같은 해석이 옳도록 트리가 깊어지고 가지가 분할될 것이긴 합니다. 하지만, 이렇게 되면 과적합 등의 문제가 생기는 이슈 또한 같이 발생할 것입니다. 또한, 학습셋에서 보지 못했던 거위라는 종이 미래에 나타나게 되면 어떤 현상이 발생하게 될까요? 분명 제대로된 예측을 하지 못하게 될 것입니다. (생각해보면 이와같은 문제는 One-Hot Encoding 에서도 동일하게 나타날 것입니다. One-Hot 에서는 변수를 하나 더 만들어줘야하기에 더욱 치명적일 수 있습니다.) 그리고 id 5번의 경우에 처럼 고양이와 개를 모두 키우는 경우에 대해서도 표현하기가 애매해집니다. 하지만, 이러한 라벨 인코딩에도 뚜렷한 장점이 있는데 첫째, 컬럼의 수가 1개로 줄어서 메모리의 관점에서 매우 효율적입니다. 둘째, 변수가 순서를 가지는 경우, 예를 들어서 수능 1등급 집단, 2등급 집단, 3등급 집단 ... 혹은 10대, 20대, ... , 90대와 같이 순서 자체가 진짜 의미가 있는 경우에는 라벨 인코딩이 효과적일 수 있습니다. 

 

이러한 라벨인코딩의 단점을 극복하고자 사람들은 이러한 생각을 합니다. 컬럼의 수를 1개로 유지하는 것은 좋지만 다른 값을 가지고 있다가 아니라 새로운 의미를 부여해보면 어떨까? 라는 생각에서 출발해서 "새로운 의미"를 다르게 한 방식이 Frequency Encoding과 Target Encoding 입니다. 여기서 Frequency Encoding은 해당 값이 "몇 번 등장했는지" , Target Encoding은 해당 값의 "Target의 Ratio가 얼마나 되는지"를 의미합니다. 한번 위의 예시를 조금 더 바꿔서 아래와 같이 해당 Id가 하루에 얼마나 많은 사료비를 쓰는지에 대한 Target을 만들어보겠습니다. 편의상 5번의 Id는 제외하고 새로운 id 5를 만들어서 문제를 풀겠습니다. 하나의 컬럼으로 표현하는 모든 인코딩 방법은 저러한 멀티 라벨의 경우 표현하기 어려움을 가지는게 동일하기 때문입니다. 

 

Id 애완동물의 종 사료의 비용 (타겟 변수) 
1 1000원 
2 고양이 10000000원 
3 1500원 
4 3500원 
5 거위 2000원

먼저 Frequency Encoding의 경우 각각의 종이 몇번이나 등장했는지로 인코딩을 하게됩니다. 위의 예시에서 개는 총 3번, 고양이, 거위는 총 1번이 등장하므로 위의 식은 아래와 같이 표현이 가능합니다. 

Id 애완동물의 종
1 3
2 1
3 3
4 3
5 1

마찬가지로 Target Encoding의 경우 각각의 종이 가지는 타겟 변수(사료의 비용)의 평균으로 인코딩을 하게됩니다. 개의 경우에는 1000 + 1500 + 3500을 3으로 나눈 2000원, 고양이의 경우에는 10000000원을 1으로 나눈 10000000원, 거위의 경우에는 2000원을 1으로 나눈 2000원이 됩니다.

Id 애완동물의 종
1 2000
2 10000000
3 2000
4 2000
5 2000

Frequency 인코딩, Target 인코딩의 경우 각각의 값을 수치로 바꿈으로서 하나의 컬럼에 모든 값을 표현할 수 있는 장점도 보존하면서 순서에 영향을 받지 않는다는 장점도 있습니다. 하지만 Frequency Encoding에서는 2번과 5번 Id 처럼 서로 다른 종을 가지지만 종이 겹치는 문제가 발생합니다. 마찬가지로 Target Encoding에서도 1, 3, 4, 5번의 Id 처럼 동일한 문제를 확인할 수 있습니다. 그리고 미래에 새로 등장하는 종에 대해서는 인코딩을 할 수 없는 단점도 그대로 보유합니다. 하지만 이러한 각각의 방법에는 뚜렷한 장단점이 추가로 존재합니다. 

 

Frequency, Target Encoding의 경우 새로운 "수치"를 모델에게 해석시킬 수 있습니다. 예를들어서 Frequency의 경우 얼마만큼 사람들이 이 종을 키우는지? Target의 경우에는 사람들이 이 종에 평균적으로 얼마만큼의 사료를 투입하는지? 입니다. Target의 경우 명확하게 인코딩된 변수와 관련이 있는게 눈에 보이실 겁니다. 하지만, Frequency의 경우는 그렇지 않을 것입니다. 하지만 이러한 관점이 도움이 될 수 있는것은 값이 큰 종의 경우 사람들이 많이 키우니 사료를 파는 곳도 많을 것이고 일반적으로 공급이 많으니 가격도 전반적으로 싸지 않을까? (물론 수요도 높으니 다를 수도 있지만 이러한 해석도 가능하다는 것을 보여드리고 싶습니다) 아니면 사료의 비용이 싸니깐 사람들이 많이 키우는게 아닐까? 이런식으로 모델이 새로운 관점에서 해석을 하는게 가능합니다. 그렇기에 대부분의 정형 대회의 솔루션을 보면 Frequency Encoding과 Label Encoding을 섞어서 다른 관점을 모델에게 학습시키는 시도를 많이 하고 있습니다. 하지만, 대부분의 솔루션에서 Target Encoding은 거의 보지 못했습니다. 왜 그럴까요? 위의 Id 2번의 예를 다시 보겠습니다. 고양이를 키우는데 드는 사료의 비용을 값으로 매핑했기에 10000000의 값을 가지고 있습니다. 이게 정말 맞을까요..? 고양이에게 하루에 천만원을 사료로 들인다는 시각은 전혀 일반적이지는 않을 것입니다. 이렇게 Target Encoding의 경우 오버피팅의 위험이 큰게 가장 큰 단점입니다. Id 2처럼 이상치가 있는 경우와 5번의 경우처럼 해당 종이 하나만 나온 경우에 대해서 해당 값들에 너무 오버피팅되기가 쉬운 문제가 있습니다. 그러한 문제를 해결하고자 노이즈를 추가한다는지 5폴드를 통해서 Target Encoding을 하는 방법들도 존재하지만 개인적으로 대회를 나가면서 느낀점은 해서 이득을 본 적은 거의 없었습니다. 

댓글(0)

Designed by JB FACTORY