[python] get_dummies (Pandas)와 OneHotEncoder (Scikit-learn)의 장단점은 무엇입니까?

기계 학습 분류기를 위해 범주 형 변수를 숫자로 변환하는 다양한 방법을 배우고 있습니다. 나는 pd.get_dummies방법을 발견했고 sklearn.preprocessing.OneHotEncoder()성능과 사용 측면에서 어떻게 다른지보고 싶었습니다.

내가 사용하는 방법에 대한 자습서 발견 OneHotEncoder()https://xgdgsc.wordpress.com/2015/03/20/note-on-using-onehotencoder-in-scikit-learn-to-work-on-categorical-features/ 이후를 sklearn문서는이 기능에 너무 도움이되지 않았습니다. 제대로하고 있지 않다는 느낌이 있지만 …

일부는 pd.dummiesover 사용의 장단점을 설명 할 수 있습니까 sklearn.preprocessing.OneHotEncoder()? 나는 그것이 OneHotEncoder()당신에게 희소 행렬 을 제공 한다는 것을 알고 있지만 그것이 사용되는 pandas방법 과 방법에 대한 이점이 무엇인지 확실하지 않습니다 . 비효율적으로 사용하고 있습니까?

import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
sns.set()

%matplotlib inline

#Iris Plot
iris = load_iris()
n_samples, m_features = iris.data.shape

#Load Data
X, y = iris.data, iris.target
D_target_dummy = dict(zip(np.arange(iris.target_names.shape[0]), iris.target_names))

DF_data = pd.DataFrame(X,columns=iris.feature_names)
DF_data["target"] = pd.Series(y).map(D_target_dummy)
#sepal length (cm)  sepal width (cm)  petal length (cm)  petal width (cm)  \
#0                  5.1               3.5                1.4               0.2   
#1                  4.9               3.0                1.4               0.2   
#2                  4.7               3.2                1.3               0.2   
#3                  4.6               3.1                1.5               0.2   
#4                  5.0               3.6                1.4               0.2   
#5                  5.4               3.9                1.7               0.4   

DF_dummies = pd.get_dummies(DF_data["target"])
#setosa  versicolor  virginica
#0         1           0          0
#1         1           0          0
#2         1           0          0
#3         1           0          0
#4         1           0          0
#5         1           0          0

from sklearn.preprocessing import OneHotEncoder, LabelEncoder
def f1(DF_data):
    Enc_ohe, Enc_label = OneHotEncoder(), LabelEncoder()
    DF_data["Dummies"] = Enc_label.fit_transform(DF_data["target"])
    DF_dummies2 = pd.DataFrame(Enc_ohe.fit_transform(DF_data[["Dummies"]]).todense(), columns = Enc_label.classes_)
    return(DF_dummies2)

%timeit pd.get_dummies(DF_data["target"])
#1000 loops, best of 3: 777 µs per loop

%timeit f1(DF_data)
#100 loops, best of 3: 2.91 ms per loop



답변

OneHotEncoder문자열 값을 직접 처리 할 수 ​​없습니다. 명목 특징이 문자열 인 경우 먼저 정수로 매핑해야합니다.

pandas.get_dummies그 반대입니다. 기본적으로 열을 지정하지 않는 한 문자열 열만 원-핫 표현으로 변환합니다.


답변

기계 학습의 경우 거의 확실히 sklearn.OneHotEncoder. 간단한 분석과 같은 다른 작업의 경우을 사용할 수 있습니다 pd.get_dummies. 이는 좀 더 편리합니다.

참고 sklearn.OneHotEncoder가되도록 최신 버전으로 업데이트되었습니다 문자열 동의 않는 범주 변수뿐만 아니라 정수를.

핵심은 sklearn인코더가 지속 되는 함수를 생성 한 다음 동일한 범주 형 변수를 사용하는 새로운 데이터 세트에 적용 할 수 있으며 일관된 결과를 제공한다는 것 입니다.

from sklearn.preprocessing import OneHotEncoder

# Create the encoder.
encoder = OneHotEncoder(handle_unknown="ignore")
encoder.fit(X_train)    # Assume for simplicity all features are categorical.

# Apply the encoder.
X_train = encoder.transform(X_train)
X_test = encoder.transform(X_test)

우리가 만든 동일한 인코더를 X_train새 데이터 세트에 적용하는 방법에 유의하십시오 X_test.

변수 중 하나와 X_test다른 수준이 포함 된 경우 어떻게되는지 고려하십시오 X_train. 예를 들어,하자의 말은 X_train["color"]단지 포함 "red"하고 "green"있지만, 그뿐만 아니라, X_test["color"]때때로 포함 "blue".

우리가 사용하는 경우 pd.get_dummies, X_test추가로 끝날 것이다 "color_blue"X_train이없는, 그리고 불일치는 아마 우리가 먹이 특히, 나중에 우리의 암호를 해독합니다 X_testsklearn우리가 훈련 모델 X_train.

그리고 한 번에 하나의 예제를받는 프로덕션에서 이와 같은 데이터를 처리하려면 pd.get_dummies사용할 수 없습니다.

함께 sklearn.OneHotEncoder우리는 인코더를 만든 후 다른 한편으로, 우리는 단지에 대한 열이있는, 동일한 출력마다 생산을 다시 사용할 수 있습니다 "red""green". 그리고 우리는 그것이 새로운 레벨을 만날 때 일어나는 일을 명시 적으로 제어 할 수 있습니다 "blue". 만약 그것이 불가능하다고 생각한다면, 우리는 그것에 오류를 던지도록 말할 수 있습니다 handle_unknown="error"; 그렇지 않으면 계속하도록 지시하고 단순히 빨간색과 녹색 열을 0으로 설정할 수 있습니다 handle_unknown="ignore".


답변

결과 get_dummies에서 col_list 변수로 열을 캐시하거나 저장 한 다음 pd.reindex를 사용하여 train 대 테스트 데이터 세트를 정렬하는 이유는 무엇입니까? … 예 :

df = pd.get_dummies(data)
col_list = df.columns.tolist()

new_df = pd.get_dummies(new_data)
new_df = new_df.reindex(columns=col_list).fillna(0.00)


답변

나는 Carl의 대답을 정말 좋아하고 찬성했습니다. 더 많은 사람들이 pd.get_dummies가 unknown을 처리 할 수 ​​있다는 사실에 감사 할 수 있도록 Carl의 예제를 조금 확장하겠습니다. 아래의 두 예는 pd.get_dummies가 unknown을 OHE로 처리 할 때 동일한 작업을 수행 할 수 있음을 보여줍니다.

# data is from @dzieciou's comment above
>>> data =pd.DataFrame(pd.Series(['good','bad','worst','good', 'good', 'bad']))
# new_data has two values that data does not have. 
>>> new_data= pd.DataFrame(
pd.Series(['good','bad','worst','good', 'good', 'bad','excellent', 'perfect']))

pd.get_dummies 사용

>>> df = pd.get_dummies(data)
>>> col_list = df.columns.tolist()
>>> print(df)
   0_bad  0_good  0_worst
0      0       1        0
1      1       0        0
2      0       0        1
3      0       1        0
4      0       1        0
5      1       0        0
6      0       0        0
7      0       0        0

>>> new_df = pd.get_dummies(new_data)
# handle unknow by using .reindex and .fillna()
>>> new_df = new_df.reindex(columns=col_list).fillna(0.00)
>>> print(new_df)
#    0_bad  0_good  0_worst
# 0      0       1        0
# 1      1       0        0
# 2      0       0        1
# 3      0       1        0
# 4      0       1        0
# 5      1       0        0
# 6      0       0        0
# 7      0       0        0

OneHotEncoder 사용

>>> encoder = OneHotEncoder(handle_unknown="ignore", sparse=False)
>>> encoder.fit(data)
>>> encoder.transform(new_data)
# array([[0., 1., 0.],
#        [1., 0., 0.],
#        [0., 0., 1.],
#        [0., 1., 0.],
#        [0., 1., 0.],
#        [1., 0., 0.],
#        [0., 0., 0.],
#        [0., 0., 0.]])


답변