기계 학습 분류기를 위해 범주 형 변수를 숫자로 변환하는 다양한 방법을 배우고 있습니다. 나는 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.dummies
over 사용의 장단점을 설명 할 수 있습니까 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_test
에 sklearn
우리가 훈련 모델 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.]])