의사 결정 트리 / 임의의 포리스트에있는 기능인 문자열


63

의사 결정 트리 / 임의의 응용 프로그램에서 일부 문제가 있습니다. 숫자와 문자열 (예 : 국가 이름)을 기능으로 갖는 문제를 해결하려고합니다. 이제 라이브러리 scikit-learn 은 숫자를 매개 변수로 사용하지만 문자열을 주입하고 많은 지식을 가지고 싶습니다.

그러한 시나리오를 어떻게 처리합니까?

파이썬의 해싱과 같은 메커니즘으로 문자열을 숫자로 변환 할 수 있습니다. 그러나 의사 결정 트리 문제에서 문자열을 처리하는 방법에 대한 모범 사례를 알고 싶습니다.


sckitlearn의 경우 범주 형 변수를 인코딩해야한다는 것을 알았습니다. 그렇지 않으면 fit 메소드는 ValueError : string을 float로 변환 할 수 없습니다.
Kar

답변:


55

잘 설정된 머신 러닝 시스템의 대부분에서 범주 형 변수는 자연스럽게 처리됩니다. 예를 들어 R에서는 요인을 사용하고 WEKA에서는 공칭 변수를 사용합니다. scikit-learn에서는 그렇지 않습니다. scikit-learn에서 구현 된 의사 결정 트리는 숫자 기능 만 사용하며 이러한 기능은 항상 연속 숫자 변수 로 해석됩니다 .

따라서 문자열을 해시 코드로 바꾸는 것은 피해야합니다. 연속적인 숫자 피처로 간주하면 사용하는 코딩이 데이터에 존재하지 않는 순서를 유발할 수 있습니다.

한 가지 예는 [ 'red', 'green', 'blue']를 [1,2,3]으로 코딩하는 것입니다. 'red'가 'blue'보다 낮은 이상한 것들을 생성하며 평균이 'red'인 경우 그리고 '파란색'은 '녹색'을 얻게됩니다. [1,2,3]으로 [ 'low', 'medium', 'high']를 코딩 할 때 또 다른 미묘한 예가 발생할 수 있습니다. 후자의 경우에는 의미가있는 순서가있을 수 있지만, '중간'이 '낮음'과 '높음'의 중간에 있지 않을 때 미묘한 불일치가 발생할 수 있습니다.

마지막으로 귀하의 질문에 대한 답변은 범주 형 기능을 여러 이진 기능으로 코딩하는 것 입니다. 예를 들어, [ 'red', 'green', 'blue']는 각 범주에 대해 하나씩 열이 3 개인 열로 코딩 할 수 있습니다 (범주가 일치하면 1, 그렇지 않으면 0). 이를 one-hot-encoding , 이진 인코딩, one-of-k-encoding 또는 기타라고합니다. 범주 형 기능 인코딩기능 추출-해싱 및 받아쓰기에 대한 설명서를 여기에서 확인할 수 있습니다 . 분명히 하나의 핫 인코딩은 공간 요구 사항을 확장하고 때로는 성능도 저하시킵니다.


2
범주 형 변수를 올바르게 처리하지 않는 것은 scikit 구현입니다. 이 답변이 제안하는 방식과 같은 코딩은 아마도 최선의 방법 일 것입니다. 더 심각한 사용자는 대체 패키지를 찾을 수 있습니다.
SmallChess

3
범주 형 변수의 원 핫 인코딩을 위해 sklearn.preprocessing.LabelBinarizer를 사용할 수 있습니다.
GuSuku

@rapaio 바이너리 코딩은 하나의 핫 인코딩이 아니라고 생각합니다. 이진 코딩은 3 개의 열이있는 8 개의 범주 또는 4 개의 열이있는 9-16 개의 범주 등을 나타내는 경우입니다. 내가 잘못?
Alok Nayak

patsy python 패키지는 범주 형 변수의 원-핫 인코딩을 처리합니다. patsy.readthedocs.io/en/latest/quickstart.html
zhespelt

5
LabelBinarizer를 사용하지 말고 sklearn.preprocessing.OneHotEncoder를 사용 하십시오 . 팬더를 사용하여 데이터를 가져오고 사전 처리하는 경우 pandas.get_dummies를 사용하여 직접 수행 할 수도 있습니다 . scikit-learn은 범주 형 변수를 지원하지 않습니다.
Ricardo Cruz

11

sci-kit이 ML 알고리즘에 사용할 수있는 숫자 기능으로 문자열을 인코딩해야합니다. 이 기능은 전처리 모듈에서 처리됩니다 (예 : sklearn.preprocessing.LabelEncoder 참조 ).


3
rapaio가 자신의 답변에서 왜 이것이 잘못된 결과를 얻는 지 설명합니다.
Keith

7

임의 포리스트를 포함하여 사이 킷 학습 모델의 경우 일반적으로 일회성 인코딩 범주 형 변수를 사용해야합니다. 임의 포리스트는 원 핫 인코딩 없이도 정상적으로 작동하지만 원 핫 인코딩을 수행하면 일반적으로 성능이 향상됩니다. 원핫 인코딩 및 "더미"변수는이 컨텍스트에서 동일한 의미를 갖습니다. Scikit-learn에는 sklearn.preprocessing.OneHotEncoder가 있으며 Pandas에는 pandas.get_dummies 가 있습니다.

그러나 대안이 있습니다. 기사 KDnuggets에서 "한 - 핫 너머은" 하나 뜨거운 인코딩 범주 변수와 대안을 인코딩해야하는 이유를 설명하는 훌륭한 일을한다.

R 또는 H2O와 같은 one-hot 인코딩이 필요없는 랜덤 포리스트의 대체 구현이 있습니다. R에서의 구현은 계산 비용당신의 기능은 많은 종류가있는 경우 작동하지 않습니다 . H2O는 많은 범주에서 작동합니다. Continuum은 Anaconda Python에서 H2O를 사용할 수있게했습니다.

있습니다 scikit가 배울 직접 범주 기능을 처리 할 수 있도록 지속적인 노력은 .

이 기사에서는 H2O에서 사용되는 알고리즘에 대해 설명합니다. 학술 논문 A 스트리밍 병렬 결정 트리 알고리즘더 긴 버전 의 동일한 논문을 참조합니다.


5

2018 업데이트!

범주 형 변수에 대한 임베딩 (고밀도 벡터) 공간을 만들 수 있습니다. 많은 사람들이 word2vec 및 fastext에 익숙하며, 이는 의미있는 밀집 벡터 공간에 단어를 포함시킵니다. 같은 생각입니다. 범주 형 변수는 의미가있는 벡터에 매핑됩니다.

로부터 구오 / Berkhahn 용지 :

엔터티 임베딩은 원 핫 인코딩에 비해 메모리 사용량을 줄이고 신경망의 속도를 높일뿐만 아니라 임베딩 공간에서 유사한 값을 서로 가깝게 매핑하여 범주 형 변수의 고유 속성을 보여줍니다. 우리는 최근 Kaggle 경쟁에서 성공적으로 적용했으며 상대적으로 간단한 기능으로 3 위를 차지했습니다.

저자는 이런 식으로 범주 형 변수를 나타내는 것이 랜덤 포레스트를 포함하여 테스트 된 모든 머신 러닝 알고리즘의 효율성을 향상 시킨다는 것을 발견했습니다.

가장 좋은 예는 Pinterest가 관련 핀을 그룹화 하는 기술적용한 것입니다 .

여기에 이미지 설명을 입력하십시오

fastai의 직원들은 범주 형 임베딩을 구현 했으며 컴패니언 데모 노트북 으로 매우 멋진 블로그 게시물 을 만들었습니다 .

추가 세부 사항 및 설명

신경망은 임베딩을 생성하는 데 사용됩니다. 즉, 각 범주 값에 벡터를 할당합니다. 벡터가 있으면 숫자 값을 허용하는 모든 모델에서 벡터를 사용할 수 있습니다. 벡터의 각 구성 요소는 입력 변수가됩니다. 예를 들어, 3 차원 벡터를 사용하여 범주 별 색상 목록을 포함하는 경우 다음과 같은 결과가 나타날 수 있습니다. red = (0, 1.5, -2.3), blue = (1, 1, 0) 등 세 가지 구성 요소에 해당하는 임의 포리스트의 입력 변수 붉은 색의 경우 c1 = 0, c2 = 1.5 및 c3 = -2.3입니다. 파란색의 경우 c1 = 1, c2 = 1 및 c3 = 0입니다.

임베드를 만들기 위해 실제로 신경망을 사용할 필요 는 없습니다 (기술에서 수줍어하는 것을 권장하지는 않지만). 가능하면 직접 또는 다른 방법으로 자신의 임베딩을 자유롭게 만들 수 있습니다. 몇 가지 예 :

  1. 색상을 RGB 벡터에 매핑합니다.
  2. 위도 / 경도 벡터에 위치를 매핑합니다.
  3. 미국 정치 모델에서는 도시를 왼쪽 / 오른쪽 정렬, 세금 부담 등을 나타내는 일부 벡터 구성 요소에 매핑하십시오.

멋지다. 그러나 내가 놓친 것이 없다면 이것은 그물이 끝나기 시작하는 것이다. 임베딩을 만들고 포레스트에 포함시키는 방법은 무엇입니까? 모든 기능으로 전체 그물을 훈련 한 다음 처음 몇 층을 가져 와서 포레스트의 입력 기능으로 사용해야한다고 생각합니다. 이것이 어떻게 이루어질지는 분명하지 않습니다.
키이스

@Keith 신경망은 임베딩을 생성하는 데 사용됩니다. 즉, 각 범주 값에 벡터를 할당합니다. 벡터가 있으면 숫자 값을 허용하는 모든 모델에서 벡터를 사용할 수 있습니다. 벡터의 각 구성 요소는 입력 변수가됩니다. 예를 들어, 3 차원 벡터를 사용하여 범주 별 색상 목록을 포함 시키면 다음과 같은 결과가 나올 수 있습니다. red = (0, 1.5, -2.3), blue = (1, 1, 0)등. 임의의 포리스트에서 세 가지 구성 요소에 해당하는 세 개의 입력 변수를 사용합니다. 붉은 색의 경우 c1 = 0, c2 = 1.5 및 c3 = -2.3입니다. 푸른 물건의 경우 c1 = 1, c2 = 1 및 c3 = 0입니다.
Pete

꽤 단순하기 때문에 개념을 완전히 얻습니다. 구현 에서이 작업을 어떻게 수행 할 것입니까? fast.ai 데모 노트는 끝에 RandomForestRegressor가 약간 있지만 실제로 이것이 임베딩에 어떻게 추가되는지는 알 수 없습니다.
키이스


3

이러한 시나리오에서 더미 변수를 사용할 수 있습니다. 팬더를 사용하면 panda.get_dummies의사 결정 트리 또는 임의 포리스트에 넣을 문자열에 더미 변수를 만들 수 있습니다.

예:

import pandas as pd
d = {'one' : pd.Series([1., 2., 3.,4.], index=['a', 'b', 'c','d']),'two' :pd.Series(['Paul', 'John', 'Micheal','George'], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(d)

df_with_dummies= pd.get_dummies(df,columns=["two"],drop_first=False)
df_with_dummies

2

예를 들어, 각 고유 한 국가에 대해 고유 번호를 요구하는 숫자 (예 : 1,2,3 및 ...)

또한 당신이 하지 마십시오 사용할 필요 한 핫 인코딩 , 임의 숲 작업 할 때 (일명 더미 변수) 나무는 다른 알고리즘처럼 작동하지 않기 때문에 (선형 / 로지스틱 회귀 분석 등) 그들은 (원거리에서 작동하지 않는 그들은 기능에 적합한 분할을 찾는 데 도움이됩니다.) 따라서 핫 인코딩이 필요 하지 않습니다.


1
실제로 트리를 훈련시키는 특정 알고리즘에 달려 있습니다. 특히 scikit은 범주 형 변수를 지원하지 않습니다.
chuse
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.