sklearn pipeline - 如何对不同的列应用不同的转换
sklearn pipeline - how to apply different transformations on different columns
我对 sklearn 中的管道很陌生,我 运行 遇到了这个问题:我有一个混合了文本和数字的数据集,即某些列只有文本,其余列有整数(或浮动点数)。
我想知道是否有可能建立一个管道,例如我可以在文本功能上调用 LabelEncoder()
并在数字列上调用 MinMaxScaler()
。我在网上看到的例子大多指向在整个数据集上使用 LabelEncoder()
而不是在 select 列上。这可能吗?如果是这样,将不胜感激。
我通常这样做的方式是使用 FeatureUnion
,使用 FunctionTransformer
来提取相关的列。
重要提示:
你必须用 def
定义你的函数,因为如果你想 pickle 你的模型,你不能在 FunctionTransformer 中使用 lambda
或 partial
很烦人
您需要用validate=False
初始化FunctionTransformer
像这样:
from sklearn.pipeline import make_union, make_pipeline
from sklearn.preprocessing import FunctionTransformer
def get_text_cols(df):
return df[['name', 'fruit']]
def get_num_cols(df):
return df[['height','age']]
vec = make_union(*[
make_pipeline(FunctionTransformer(get_text_cols, validate=False), LabelEncoder()))),
make_pipeline(FunctionTransformer(get_num_cols, validate=False), MinMaxScaler())))
])
从 v0.20 开始,您可以使用 ColumnTransformer
来完成此操作。
ColumnTransformer 的示例可能对您有所帮助:
# FOREGOING TRANSFORMATIONS ON 'data' ...
# filter data
data = data[data['county'].isin(COUNTIES_OF_INTEREST)]
# define the feature encoding of the data
impute_and_one_hot_encode = Pipeline([
('impute', SimpleImputer(strategy='most_frequent')),
('encode', OneHotEncoder(sparse=False, handle_unknown='ignore'))
])
featurisation = ColumnTransformer(transformers=[
("impute_and_one_hot_encode", impute_and_one_hot_encode, ['smoker', 'county', 'race']),
('word2vec', MyW2VTransformer(min_count=2), ['last_name']),
('numeric', StandardScaler(), ['num_children', 'income'])
])
# define the training pipeline for the model
neural_net = KerasClassifier(build_fn=create_model, epochs=10, batch_size=1, verbose=0, input_dim=109)
pipeline = Pipeline([
('features', featurisation),
('learner', neural_net)])
# train-test split
train_data, test_data = train_test_split(data, random_state=0)
# model training
model = pipeline.fit(train_data, train_data['label'])
您可以在以下位置找到完整代码:https://github.com/stefan-grafberger/mlinspect/blob/19ca0d6ae8672249891835190c9e2d9d3c14f28f/example_pipelines/healthcare/healthcare.py
我对 sklearn 中的管道很陌生,我 运行 遇到了这个问题:我有一个混合了文本和数字的数据集,即某些列只有文本,其余列有整数(或浮动点数)。
我想知道是否有可能建立一个管道,例如我可以在文本功能上调用 LabelEncoder()
并在数字列上调用 MinMaxScaler()
。我在网上看到的例子大多指向在整个数据集上使用 LabelEncoder()
而不是在 select 列上。这可能吗?如果是这样,将不胜感激。
我通常这样做的方式是使用 FeatureUnion
,使用 FunctionTransformer
来提取相关的列。
重要提示:
你必须用
def
定义你的函数,因为如果你想 pickle 你的模型,你不能在 FunctionTransformer 中使用lambda
或partial
很烦人您需要用
validate=False
初始化
FunctionTransformer
像这样:
from sklearn.pipeline import make_union, make_pipeline
from sklearn.preprocessing import FunctionTransformer
def get_text_cols(df):
return df[['name', 'fruit']]
def get_num_cols(df):
return df[['height','age']]
vec = make_union(*[
make_pipeline(FunctionTransformer(get_text_cols, validate=False), LabelEncoder()))),
make_pipeline(FunctionTransformer(get_num_cols, validate=False), MinMaxScaler())))
])
从 v0.20 开始,您可以使用 ColumnTransformer
来完成此操作。
ColumnTransformer 的示例可能对您有所帮助:
# FOREGOING TRANSFORMATIONS ON 'data' ...
# filter data
data = data[data['county'].isin(COUNTIES_OF_INTEREST)]
# define the feature encoding of the data
impute_and_one_hot_encode = Pipeline([
('impute', SimpleImputer(strategy='most_frequent')),
('encode', OneHotEncoder(sparse=False, handle_unknown='ignore'))
])
featurisation = ColumnTransformer(transformers=[
("impute_and_one_hot_encode", impute_and_one_hot_encode, ['smoker', 'county', 'race']),
('word2vec', MyW2VTransformer(min_count=2), ['last_name']),
('numeric', StandardScaler(), ['num_children', 'income'])
])
# define the training pipeline for the model
neural_net = KerasClassifier(build_fn=create_model, epochs=10, batch_size=1, verbose=0, input_dim=109)
pipeline = Pipeline([
('features', featurisation),
('learner', neural_net)])
# train-test split
train_data, test_data = train_test_split(data, random_state=0)
# model training
model = pipeline.fit(train_data, train_data['label'])
您可以在以下位置找到完整代码:https://github.com/stefan-grafberger/mlinspect/blob/19ca0d6ae8672249891835190c9e2d9d3c14f28f/example_pipelines/healthcare/healthcare.py