我想创建一个管道,在那里我可以在我的火车数据集(train_df)上调用fit_transform()
一次时间,并接收一个完全预处理的数据集。但是,我不认为我目前可以这样做,因为我必须在ColumnTransformer的输出上调用PCA(),然后将该输出与在train_df上调用的单独ColumnTransformer的结果连接起来。基本上,我认为我在抽象阶梯上走得太高了,有太多的管道/ct彼此嵌入。没有办法通过将train_df传递给单个Pipeline或ColumnTransformer来简化整个预处理过程-除非我错过了一些东西,而您有任何见解?我花了几个小时来解决这个问题,最终面对现实,我只是在白费力气。如有任何帮助或解决方案,我将不胜感激。
谢谢!
num_ct = ColumnTransformer([
('non_skewed_num', non_skewed_num_pipe, non_skewed_vars),
('skewed_num', skewed_num_pipe, skewed_vars)
], remainder='drop')
total_num_pipe = Pipeline([('num_ct', num_ct),
('dim_reduc', PCA(n_components=5))])
cat_ct = ColumnTransformer([
('cat_pipe1', cat_pipe1, cat_vars1),
('cat_pipe2', cat_pipe2, cat_vars2)
], remainder='drop')
final_num = total_num_pipe.fit_transform(train_df)
final_cat = cat_ct.fit_transform(train_df)
final_X_train = np.c_[final_num, final_cat]
我终于找到了一个解决方案,感谢@Alexander的链接columntransformer到管道的建议。(TLDR:不要忘记您可以创建一个columntransformer的管道,使用remainder='passthrough'对您有利。)
我首先创建了一个ColumnTransformer,它连接了数值和分类变量的转换,但是没有PCA。
ct = ColumnTransformer([
('non_skewed_num', non_skewed_num_pipe, non_skewed_vars),
('skewed_num', skewed_num_pipe, skewed_vars),
('cat_pipe1', cat_pipe1, cat_vars1),
('cat_pipe2', cat_pipe2, cat_vars2)
], remainder='drop')
然后,我为PCA创建了一个ColumnTransformer
,当我指定要将其应用于哪些列时,我使用了一个切片对象,因为这个ColumnTransformer
将在最终的管道中被提供NumPy数组-而不是DataFrame(它将是管道中的第二个ColumnTransformer
)。我还设置了remainder='passthrough',因此非数字变量将在PCA之后保留未转换。
ct2 = ColumnTransformer([('dim_reduc', PCA(n_components=5), slice(0, 37))], remainder='passthrough') # 37 is number of numeric variables
最后,我创建了一个管道链接这两个ColumnTransformers
final_pipe = Pipeline([('ct', ct),
('ct2', ct2)])
调用final_pipe.fit_transform(train_df)
将生成我想要的清理后的数组。希望这对你有帮助!