scikit-learn:如何使用管道组合 LabelEncoder 和 OneHotEncoder?
scikit-learn: How to compose LabelEncoder and OneHotEncoder with a pipeline?
在为机器学习 class 化任务预处理标签时,我需要对采用字符串值的标签进行一次热编码。 sklearn.preprocessing
中的 OneHotEncoder
或 kera.np_utils
中的 to_categorical
需要 int
输入。这意味着我需要在 one hot 编码器之前加上 LabelEncoder
。我已经用自定义 class:
手工完成了
class LabelOneHotEncoder():
def __init__(self):
self.ohe = OneHotEncoder()
self.le = LabelEncoder()
def fit_transform(self, x):
features = self.le.fit_transform( x)
return self.ohe.fit_transform( features.reshape(-1,1))
def transform( self, x):
return self.ohe.transform( self.la.transform( x.reshape(-1,1)))
def inverse_tranform( self, x):
return self.le.inverse_transform( self.ohe.inverse_tranform( x))
def inverse_labels( self, x):
return self.le.inverse_transform( x)
我相信在 sklearn API 中必须有一种使用 sklearn.pipeline
来完成它的方法,但是在使用时:
LabelOneHotEncoder = Pipeline( [ ("le",LabelEncoder), ("ohe", OneHotEncoder)])
我从 OneHotEncoder
得到错误 ValueError: bad input shape ()
。我的猜测是 LabelEncoder
的输出需要通过添加一个普通的第二个轴来重塑。不过我不确定如何添加此功能。
奇怪的是他们不能很好地一起玩...我很惊讶。我会将 class 扩展到 return 像你建议的重塑数据。
class ModifiedLabelEncoder(LabelEncoder):
def fit_transform(self, y, *args, **kwargs):
return super().fit_transform(y).reshape(-1, 1)
def transform(self, y, *args, **kwargs):
return super().transform(y).reshape(-1, 1)
然后使用管道应该可以工作。
pipe = Pipeline([("le", ModifiedLabelEncoder()), ("ohe", OneHotEncoder())])
pipe.fit_transform(['dog', 'cat', 'dog'])
https://github.com/scikit-learn/scikit-learn/blob/a24c8b46/sklearn/preprocessing/label.py#L39
从 scikit-learn 0.20 开始,OneHotEncoder
接受字符串,因此您不再需要在它前面加上 LabelEncoder
。您可以在管道中使用它。
我使用了自定义 class 来包装我的标签编码器功能,它 returns 整个更新的数据集。
class CustomLabelEncode(BaseEstimator, TransformerMixin):
def fit(self, X, y=None):
return self
def transform(self, X ,y=None):
le=LabelEncoder()
for i in X[cat_cols]:
X[i]=le.fit_transform(X[i])
return X
cat_cols=['Family','Education','Securities Account','CDAccount','Online','CreditCard']
le_ct=make_column_transformer((CustomLabelEncode(),cat_cols),remainder='passthrough')
pd.DataFrame(ct3.fit_transform(X)) #This will show you your changes
Final_pipeline=make_pipeline(le_ct)
[我实现了你可以看我的githublink]
[1]: https://github.com/Ayushmina-20/sklearn_pipeline
这不是针对所问的问题,而是为了仅将 LabelEncoder 应用于所有列,您可以使用以下格式
df_non_numeric =df.select_dtypes(['object'])
non_numeric_cols = df_non_numeric.columns.values
from sklearn.preprocessing import LabelEncoder
for col in non_numeric_cols:
df[col] = LabelEncoder().fit_transform(df[col].values)
df.head()
在为机器学习 class 化任务预处理标签时,我需要对采用字符串值的标签进行一次热编码。 sklearn.preprocessing
中的 OneHotEncoder
或 kera.np_utils
中的 to_categorical
需要 int
输入。这意味着我需要在 one hot 编码器之前加上 LabelEncoder
。我已经用自定义 class:
class LabelOneHotEncoder():
def __init__(self):
self.ohe = OneHotEncoder()
self.le = LabelEncoder()
def fit_transform(self, x):
features = self.le.fit_transform( x)
return self.ohe.fit_transform( features.reshape(-1,1))
def transform( self, x):
return self.ohe.transform( self.la.transform( x.reshape(-1,1)))
def inverse_tranform( self, x):
return self.le.inverse_transform( self.ohe.inverse_tranform( x))
def inverse_labels( self, x):
return self.le.inverse_transform( x)
我相信在 sklearn API 中必须有一种使用 sklearn.pipeline
来完成它的方法,但是在使用时:
LabelOneHotEncoder = Pipeline( [ ("le",LabelEncoder), ("ohe", OneHotEncoder)])
我从 OneHotEncoder
得到错误 ValueError: bad input shape ()
。我的猜测是 LabelEncoder
的输出需要通过添加一个普通的第二个轴来重塑。不过我不确定如何添加此功能。
奇怪的是他们不能很好地一起玩...我很惊讶。我会将 class 扩展到 return 像你建议的重塑数据。
class ModifiedLabelEncoder(LabelEncoder):
def fit_transform(self, y, *args, **kwargs):
return super().fit_transform(y).reshape(-1, 1)
def transform(self, y, *args, **kwargs):
return super().transform(y).reshape(-1, 1)
然后使用管道应该可以工作。
pipe = Pipeline([("le", ModifiedLabelEncoder()), ("ohe", OneHotEncoder())])
pipe.fit_transform(['dog', 'cat', 'dog'])
https://github.com/scikit-learn/scikit-learn/blob/a24c8b46/sklearn/preprocessing/label.py#L39
从 scikit-learn 0.20 开始,OneHotEncoder
接受字符串,因此您不再需要在它前面加上 LabelEncoder
。您可以在管道中使用它。
我使用了自定义 class 来包装我的标签编码器功能,它 returns 整个更新的数据集。
class CustomLabelEncode(BaseEstimator, TransformerMixin):
def fit(self, X, y=None):
return self
def transform(self, X ,y=None):
le=LabelEncoder()
for i in X[cat_cols]:
X[i]=le.fit_transform(X[i])
return X
cat_cols=['Family','Education','Securities Account','CDAccount','Online','CreditCard']
le_ct=make_column_transformer((CustomLabelEncode(),cat_cols),remainder='passthrough')
pd.DataFrame(ct3.fit_transform(X)) #This will show you your changes
Final_pipeline=make_pipeline(le_ct)
[我实现了你可以看我的githublink] [1]: https://github.com/Ayushmina-20/sklearn_pipeline
这不是针对所问的问题,而是为了仅将 LabelEncoder 应用于所有列,您可以使用以下格式
df_non_numeric =df.select_dtypes(['object'])
non_numeric_cols = df_non_numeric.columns.values
from sklearn.preprocessing import LabelEncoder
for col in non_numeric_cols:
df[col] = LabelEncoder().fit_transform(df[col].values)
df.head()