【发布时间】:2021-01-23 08:49:45
【问题描述】:
当我在查找如何准备好 sklearn.Pipeline 中的一个步骤以仅在某些列上运行时,我偶然发现了 sklearn.Pipeline.FeatureUnion from this answer on stackoverflow。但是,我不太清楚,如何不对我不想要的列应用任何东西并将完整的数据传递到下一步。例如,在我的第一步中,我只想在某些列上应用StandardScaler,可以使用下面显示的代码来完成,但问题是下一步将只有标准缩放的列。如何在下一步中使用从上一步标准缩放的列获得完整数据?
下面是一些示例代码:
from sklearn.pipeline import Pipeline, FeatureUnion, make_pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.neighbors import KNeighborsClassifier
class Columns(BaseEstimator, TransformerMixin):
def __init__(self, names=None):
self.names = names
def fit(self, X, y=None, **fit_params):
return self
def transform(self, X):
return X[self.names]
pipe = Pipeline([
# steps below applies on only some columns
("features", FeatureUnion([
('numeric', make_pipeline(Columns(names=[list of numeric column names]), StandardScaler())),
])),
('feature_engineer_step1', FeatEng_1()),
('feature_engineer_step2', FeatEng_2()),
('feature_engineer_step3', FeatEng_3()),
('remove_skew', Skew_Remover()),
# below step applies on all columns
('model', RandomForestRegressor())
])
编辑:
由于选择的答案没有任何示例代码,我将我的粘贴在这里,以供可能遇到此问题并希望找到有效代码的任何人使用。 下例中使用的数据是google colab自带的加州住房数据。
from sklearn.preprocessing import StandardScaler
from sklearn.compose import ColumnTransformer
from sklearn.ensemble import RandomForestRegressor
# writing a column transformer that operates on some columns
num_cols = ['housing_median_age', 'total_rooms','total_bedrooms', 'population', 'households', 'median_income']
p_stand_scaler_1 = ColumnTransformer(transformers=[('stand_scale', StandardScaler(), num_cols)],
# set remainder to passthrough to pass along all the un-specified columns untouched to the next steps
remainder='passthrough')
# make a pipeline now with all the steps
pipe_1 = Pipeline(steps=[('standard_scaler', p_stand_scaler_1),
('rf_regressor', RandomForestRegressor(random_state=100))])
# pass the data now to fit
pipe_1.fit(house_train.drop('median_house_value', axis=1), house_train.loc[:,'median_house_value'])
# make predictions
pipe_predictions = pipe_1.predict(house_test.drop('median_house_value', axis=1))
【问题讨论】:
-
如果 feat_eng1() 是一种通用转换,可以应用于任何两列,例如 additon,subtraction 。所以我想将特征名称传递给转换器并将结果存储在具有此特征名称的数据框中是可能的
-
我无法完全理解你。您希望您的转换器将完整的数据框作为输入并将一些转换功能(例如加法或减法)应用到两列,是吗?如果是,那是可能的,我已经做到了。
-
def transform(self,X,y=None): for tpl in self.dif_columns: print('diff caclulator') X.loc[:,tpl[2]] = X[tpl[ 0]] - X[tpl[1]] return X 这就是我想要做的。我将一个元组('AMT_PMT','AMT_INST','AMT_PER') 传递给构造函数。元组有两列第三项是新列名。我收到两个错误 1. settingwithcopy 使用 loc 2. 关键字不能是表达式。第二个错误是新列名必须是硬编码的并且不能是表达式。因此你能分享你的 feat_eng1() 结构吗
-
请打开一个新问题并在此处发布它的网址。我会尽力回答。以这种方式查看代码并理解它并不容易。
-
链接到我在上面的评论中谈到的问题stackoverflow.com/questions/65164203/…
标签: python python-3.x scikit-learn pipeline