Python에서 핫 인코딩을 어떻게 할 수 있습니까?
80 % 범주 형 변수가있는 기계 학습 분류 문제가 있습니다. 분류를 위해 일부 분류자를 사용하려면 핫 인코딩 하나를 사용해야합니까? 인코딩없이 분류기에 데이터를 전달할 수 있습니까?
기능 선택을 위해 다음을 수행하려고합니다.
기차 파일을 읽었습니다.
num_rows_to_read = 10000 train_small = pd.read_csv("../../dataset/train.csv", nrows=num_rows_to_read)
카테고리 기능의 유형을 '카테고리'로 변경합니다.
non_categorial_features = ['orig_destination_distance', 'srch_adults_cnt', 'srch_children_cnt', 'srch_rm_cnt', 'cnt'] for categorical_feature in list(train_small.columns): if categorical_feature not in non_categorial_features: train_small[categorical_feature] = train_small[categorical_feature].astype('category')
하나의 핫 인코딩을 사용합니다.
train_small_with_dummies = pd.get_dummies(train_small, sparse=True)
문제는 제가 강한 기계를 사용하고 있는데도 세 번째 부분이 자주 막히는 것입니다.
따라서 하나의 핫 인코딩 없이는 기능의 중요성을 결정하기 위해 기능 선택을 할 수 없습니다.
추천 메뉴가 무엇인가요?
접근 방식 1 : Pandas 데이터 프레임에서 get_dummies를 사용할 수 있습니다.
예 1 :
import pandas as pd
s = pd.Series(list('abca'))
pd.get_dummies(s)
Out[]:
a b c
0 1.0 0.0 0.0
1 0.0 1.0 0.0
2 0.0 0.0 1.0
3 1.0 0.0 0.0
예 2 :
다음은 주어진 열을 하나의 핫으로 변환합니다. 여러 더미를 가지려면 접두사를 사용하십시오.
import pandas as pd
df = pd.DataFrame({
'A':['a','b','a'],
'B':['b','a','c']
})
df
Out[]:
A B
0 a b
1 b a
2 a c
# Get one hot encoding of columns B
one_hot = pd.get_dummies(df['B'])
# Drop column B as it is now encoded
df = df.drop('B',axis = 1)
# Join the encoded df
df = df.join(one_hot)
df
Out[]:
A a b c
0 a 0 1 0
1 b 1 0 0
2 a 0 0 1
접근 방식 2 : Scikit-learn 사용
3 개의 기능과 4 개의 샘플이있는 데이터 세트가 주어지면 인코더가 기능 당 최대 값을 찾고 데이터를 이진 원-핫 인코딩으로 변환하도록합니다.
>>> from sklearn.preprocessing import OneHotEncoder
>>> enc = OneHotEncoder()
>>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])
OneHotEncoder(categorical_features='all', dtype=<class 'numpy.float64'>,
handle_unknown='error', n_values='auto', sparse=True)
>>> enc.n_values_
array([2, 3, 4])
>>> enc.feature_indices_
array([0, 2, 5, 9], dtype=int32)
>>> enc.transform([[0, 1, 1]]).toarray()
array([[ 1., 0., 0., 1., 0., 0., 1., 0., 0.]])
다음은이 예제에 대한 링크입니다. http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html
numpy.eye
및 배열 요소 선택 메커니즘을 사용하여 수행 할 수 있습니다 .
import numpy as np
nb_classes = 6
data = [[2, 3, 4, 0]]
def indices_to_one_hot(data, nb_classes):
"""Convert an iterable of indices to one-hot encoded labels."""
targets = np.array(data).reshape(-1)
return np.eye(nb_classes)[targets]
의 반환 값 indices_to_one_hot(nb_classes, data)
은 이제
array([[[ 0., 0., 1., 0., 0., 0.],
[ 0., 0., 0., 1., 0., 0.],
[ 0., 0., 0., 0., 1., 0.],
[ 1., 0., 0., 0., 0., 0.]]])
은 .reshape(-1)
(당신이 또한있을 수 있습니다 당신이 올바른 라벨 형식이 존재하는 것입니다 [[2], [3], [4], [0]]
).
첫째, 핫 인코딩을하는 가장 쉬운 방법은 Sklearn을 사용하는 것입니다.
http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html
둘째, 팬더를 하나의 핫 인코딩에 사용하는 것이 그렇게 간단하다고 생각하지 않습니다 (확인되지 않음)
마지막으로 핫 인코딩이 필요합니까? 하나의 핫 인코딩은 기능의 수를 기하 급수적으로 증가시켜 분류기 또는 실행할 다른 모든 항목의 실행 시간을 크게 증가시킵니다. 특히 각 범주 기능에 여러 수준이있을 때. 대신 더미 코딩을 할 수 있습니다.
더미 인코딩을 사용하면 일반적으로 실행 시간과 복잡성이 훨씬 줄어들어 잘 작동합니다. 한 현명한 교수가 '적은 것이 더 많다'고 말했습니다.
원하는 경우 내 사용자 지정 인코딩 기능에 대한 코드는 다음과 같습니다.
from sklearn.preprocessing import LabelEncoder
#Auto encodes any dataframe column of type category or object.
def dummyEncode(df):
columnsToEncode = list(df.select_dtypes(include=['category','object']))
le = LabelEncoder()
for feature in columnsToEncode:
try:
df[feature] = le.fit_transform(df[feature])
except:
print('Error encoding '+feature)
return df
편집 : 더 명확하게 비교 :
원-핫 인코딩 : n 레벨을 n-1 열로 변환합니다.
Index Animal Index cat mouse
1 dog 1 0 0
2 cat --> 2 1 0
3 mouse 3 0 1
범주 형 기능에 다양한 유형 (또는 수준)이있는 경우 이것이 어떻게 기억을 폭발 시킬지 알 수 있습니다. 이것은 단 하나의 열입니다.
더미 코딩 :
Index Animal Index Animal
1 dog 1 0
2 cat --> 2 1
3 mouse 3 2
대신 수치 표현으로 변환하십시오. 약간의 정확성을 희생하면서 기능 공간을 크게 절약합니다.
팬더를 사용한 핫 인코딩은 매우 쉽습니다.
def one_hot(df, cols):
"""
@param df pandas DataFrame
@param cols a list of columns to encode
@return a DataFrame with one-hot encoding
"""
for each in cols:
dummies = pd.get_dummies(df[each], prefix=each, drop_first=False)
df = pd.concat([df, dummies], axis=1)
return df
편집하다:
sklearn을 사용하는 one_hot의 또 다른 방법 LabelBinarizer
:
from sklearn.preprocessing import LabelBinarizer
label_binarizer = LabelBinarizer()
label_binarizer.fit(all_your_labels_list) # need to be global or remembered to use it later
def one_hot_encode(x):
"""
One hot encode a list of sample labels. Return a one-hot encoded vector for each label.
: x: List of sample Labels
: return: Numpy array of one-hot encoded labels
"""
return label_binarizer.transform(x)
기본 원-핫 인코딩에 Pandas를 훨씬 쉽게 사용할 수 있습니다. 더 많은 옵션을 찾고 있다면 scikit-learn을 사용할 수 있습니다.
Pandas 를 사용한 기본 원-핫 인코딩 의 경우 데이터 프레임을 get_dummies 함수에 전달하기 만하면 됩니다.
예를 들어 imdb_movies 라는 데이터 프레임이있는 경우 :
... Rated 열을 원-핫 인코딩하고 싶습니다. 간단히 이렇게합니다.
pd.get_dummies(imdb_movies.Rated)
이것은 존재하는 평가의 모든 " 수준 "에 대한 열이있는 새 데이터 프레임을 반환하며 , 주어진 관찰에 대해 해당 평가의 존재를 지정하는 1 또는 0을 함께 반환합니다 .
일반적으로 이것이 원래 데이터 프레임의 일부가되기를 원합니다. 이 경우 " column-binding을 사용하여 새 더미 코딩 된 프레임을 원래 프레임에 연결하기 만하면 됩니다 .
Pandas concat 함수 를 사용하여 열 바인딩 할 수 있습니다 .
rated_dummies = pd.get_dummies(imdb_movies.Rated)
pd.concat([imdb_movies, rated_dummies], axis=1)
이제 전체 데이터 프레임에서 분석을 실행할 수 있습니다.
간단한 유틸리티 기능
이 작업을 빠르게 수행하려면 유틸리티 함수 로 만드는 것이 좋습니다 .
def encode_and_bind(original_dataframe, feature_to_encode):
dummies = pd.get_dummies(original_dataframe[[feature_to_encode]])
res = pd.concat([original_dataframe, dummies], axis=1)
return(res)
사용법 :
encode_and_bind(imdb_movies, 'Rated')
결과 :
또한 @pmalbu 주석에 따라 함수가 원래 feature_to_encode 를 제거하려면 다음 버전을 사용하십시오.
def encode_and_bind(original_dataframe, feature_to_encode):
dummies = pd.get_dummies(original_dataframe[[feature_to_encode]])
res = pd.concat([original_dataframe, dummies], axis=1)
res = res.drop([feature_to_encode], axis=1)
return(res)
numpy.eye 함수를 사용할 수 있습니다.
import numpy as np
def one_hot_encode(x, n_classes):
"""
One hot encode a list of sample labels. Return a one-hot encoded vector for each label.
: x: List of sample Labels
: return: Numpy array of one-hot encoded labels
"""
return np.eye(n_classes)[x]
def main():
list = [0,1,2,3,4,3,2,1,0]
n_classes = 5
one_hot_list = one_hot_encode(list, n_classes)
print(one_hot_list)
if __name__ == "__main__":
main()
결과
D:\Desktop>python test.py
[[ 1. 0. 0. 0. 0.]
[ 0. 1. 0. 0. 0.]
[ 0. 0. 1. 0. 0.]
[ 0. 0. 0. 1. 0.]
[ 0. 0. 0. 0. 1.]
[ 0. 0. 0. 1. 0.]
[ 0. 0. 1. 0. 0.]
[ 0. 1. 0. 0. 0.]
[ 1. 0. 0. 0. 0.]]
pandas는 "get_dummies"함수를 내장하여 특정 열의 핫 인코딩을 가져옵니다.
원-핫 인코딩을위한 한 줄 코드 :
df=pd.concat([df,pd.get_dummies(df['column name'],prefix='column name')],axis=1).drop(['column name'],axis=1)
원-핫 인코딩은 값을 인디케이터 변수로 변환하는 것보다 조금 더 필요합니다. 일반적으로 ML 프로세스에서는이 코딩을 검증 또는 테스트 데이터 세트에 여러 번 적용하고 생성 한 모델을 실시간 관찰 데이터에 적용해야합니다. 모델을 구성하는 데 사용 된 매핑 (변환)을 저장해야합니다. 좋은 해결책은 DictVectorizer
or LabelEncoder
(뒤에 get_dummies
.)를 사용하는 것 입니다. 다음은 사용할 수있는 함수입니다.
def oneHotEncode2(df, le_dict = {}):
if not le_dict:
columnsToEncode = list(df.select_dtypes(include=['category','object']))
train = True;
else:
columnsToEncode = le_dict.keys()
train = False;
for feature in columnsToEncode:
if train:
le_dict[feature] = LabelEncoder()
try:
if train:
df[feature] = le_dict[feature].fit_transform(df[feature])
else:
df[feature] = le_dict[feature].transform(df[feature])
df = pd.concat([df,
pd.get_dummies(df[feature]).rename(columns=lambda x: feature + '_' + str(x))], axis=1)
df = df.drop(feature, axis=1)
except:
print('Error encoding '+feature)
#df[feature] = df[feature].convert_objects(convert_numeric='force')
df[feature] = df[feature].apply(pd.to_numeric, errors='coerce')
return (df, le_dict)
이것은 pandas 데이터 프레임에서 작동하고 데이터 프레임의 각 열에 대해 생성하고 매핑을 다시 반환합니다. 따라서 다음과 같이 호출합니다.
train_data, le_dict = oneHotEncode2(train_data)
그런 다음 테스트 데이터에서 훈련에서 반환 된 사전을 전달하여 호출이 이루어집니다.
test_data, _ = oneHotEncode2(test_data, le_dict)
동등한 방법은 DictVectorizer
. 같은 관련 게시물이 내 블로그에 있습니다. 단순히 get_dummies 게시물을 사용하는 것보다이 접근 방식에 대한 몇 가지 이유를 제공하기 때문에 여기에 언급했습니다 (공개 : 이것은 내 블로그입니다).
다음은 DictVectorizer
및 Pandas DataFrame.to_dict('records')
방법을 사용하는 솔루션 입니다.
>>> import pandas as pd
>>> X = pd.DataFrame({'income': [100000,110000,90000,30000,14000,50000],
'country':['US', 'CAN', 'US', 'CAN', 'MEX', 'US'],
'race':['White', 'Black', 'Latino', 'White', 'White', 'Black']
})
>>> from sklearn.feature_extraction import DictVectorizer
>>> v = DictVectorizer()
>>> qualitative_features = ['country','race']
>>> X_qual = v.fit_transform(X[qualitative_features].to_dict('records'))
>>> v.vocabulary_
{'country=CAN': 0,
'country=MEX': 1,
'country=US': 2,
'race=Black': 3,
'race=Latino': 4,
'race=White': 5}
>>> X_qual.toarray()
array([[ 0., 0., 1., 0., 0., 1.],
[ 1., 0., 0., 1., 0., 0.],
[ 0., 0., 1., 0., 1., 0.],
[ 1., 0., 0., 0., 0., 1.],
[ 0., 1., 0., 0., 0., 1.],
[ 0., 0., 1., 1., 0., 0.]])
이 파티에 늦었다는 것을 알고 있지만 자동화 된 방식으로 데이터 프레임을 핫 인코딩하는 가장 간단한 방법은이 함수를 사용하는 것입니다.
def hot_encode(df):
obj_df = df.select_dtypes(include=['object'])
return pd.get_dummies(df, columns=obj_df.columns).values
인코딩없이 catboost 분류기에 데이터를 전달할 수 있습니다. Catboost는 원-핫 및 대상 확장 평균 인코딩을 수행하여 범주 형 변수 자체를 처리합니다.
다른 질문에 추가하려면 Numpy를 사용하여 Python 2.0 함수로 수행 한 방법을 제공하겠습니다.
def one_hot(y_):
# Function to encode output labels from number indexes
# e.g.: [[5], [0], [3]] --> [[0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0]]
y_ = y_.reshape(len(y_))
n_values = np.max(y_) + 1
return np.eye(n_values)[np.array(y_, dtype=np.int32)] # Returns FLOATS
n_values = np.max(y_) + 1
예를 들어 미니 배치를 사용하는 경우 적절한 수의 뉴런을 사용하도록 라인 을 하드 코딩 할 수 있습니다.
이 기능이 사용 된 데모 프로젝트 / 튜토리얼 : https://github.com/guillaume-chevalier/LSTM-Human-Activity-Recognition
이것은 나를 위해 작동합니다.
pandas.factorize( ['B', 'C', 'D', 'B'] )[0]
산출:
[0, 1, 2, 0]
나는 이것을 음향 모델에 사용했습니다. 아마도 이것은 당신의 모델에 도움이 될 것입니다.
def one_hot_encoding(x, n_out):
x = x.astype(int)
shape = x.shape
x = x.flatten()
N = len(x)
x_categ = np.zeros((N,n_out))
x_categ[np.arange(N), x] = 1
return x_categ.reshape((shape)+(n_out,))
다음과 같이 쉽게 할 수 있습니다.
class OneHotEncoder:
def __init__(self,optionKeys):
length=len(optionKeys)
self.__dict__={optionKeys[j]:[0 if i!=j else 1 for i in range(length)] for j in range(length)}
사용법 :
ohe=OneHotEncoder(["A","B","C","D"])
print(ohe.A)
print(ohe.D)
다음을 수행 할 수도 있습니다. 아래에 대해서는을 사용할 필요가 없습니다 pd.concat
.
import pandas as pd
# intialise data of lists.
data = {'Color':['Red', 'Yellow', 'Red', 'Yellow'], 'Length':[20.1, 21.1, 19.1, 18.1],
'Group':[1,2,1,2]}
# Create DataFrame
df = pd.DataFrame(data)
for _c in df.select_dtypes(include=['object']).columns:
print(_c)
df[_c] = pd.Categorical(df[_c])
df_transformed = pd.get_dummies(df)
df_transformed
명시 적 열을 범주 형으로 변경할 수도 있습니다. 예를 들어 여기에서 Color
및Group
import pandas as pd
# intialise data of lists.
data = {'Color':['Red', 'Yellow', 'Red', 'Yellow'], 'Length':[20.1, 21.1, 19.1, 18.1],
'Group':[1,2,1,2]}
# Create DataFrame
df = pd.DataFrame(data)
columns_to_change = list(df.select_dtypes(include=['object']).columns)
columns_to_change.append('Group')
for _c in columns_to_change:
print(_c)
df[_c] = pd.Categorical(df[_c])
df_transformed = pd.get_dummies(df)
df_transformed
여기 에이 접근 방식을 시도했습니다.
import numpy as np
#converting to one_hot
def one_hot_encoder(value, datal):
datal[value] = 1
return datal
def _one_hot_values(labels_data):
encoded = [0] * len(labels_data)
for j, i in enumerate(labels_data):
max_value = [0] * (np.max(labels_data) + 1)
encoded[j] = one_hot_encoder(i, max_value)
return np.array(encoded)
참고 URL : https://stackoverflow.com/questions/37292872/how-can-i-one-hot-encode-in-python
'program story' 카테고리의 다른 글
트위터 부트 스트랩으로 작업하는 HTML 이메일을받은 사람이 있습니까? (0) | 2020.09.12 |
---|---|
JNDI의 목적은 무엇입니까 (0) | 2020.09.12 |
Swift 3.0으로 컴파일 된 모듈은 Swift 3.0.1에서 가져올 수 없습니다. (0) | 2020.09.11 |
DB의 모든 스키마를 나열하기위한 Oracle SQL 쿼리 (0) | 2020.09.11 |
Visual Studio 2010 C # 코드 창에서 혼합 탭과 공백이 계속 표시되는 이유는 무엇입니까? (0) | 2020.09.11 |