我想在数据库中的数据项目中使用scikit-learn Pipelines的FeatureUnion功能。我在如何构建我正在做的事情方面遇到了一些基本问题。Sci-Kit通过不同的行数学习FeatureUnion
我从数据库中的两个不同表创建两个功能。我有一个fetch_x1,fetch_x2方法来从数据库表中获取感兴趣的数据作为pandas DataFrames。我将这两个DataFrames打包成一个数据框字典。在每个变压器中,我解压缩感兴趣的DataFrame并对其进行操作。我有点关注这个post的模式。
我的代码如下:
class Feature1Extractor(TransformerMixin):
def transform(self, dictionary_of_dataframes):
df = dictionary_of_dataframes['feature1_raw_data']
x = df.groupby('user_id').count()['x1']
return df
class Feature2Extractor(TransformerMixin):
def transform(self, dictionary_of_dataframes):
df = dictionary_of_dataframes['feature2']
x = df.groupby('user_id').sum()['x2']
return x
pipeline = Pipeline([
('union', FeatureUnion(
transformer_list=[
('feature1', Feature1Extractor()),
('feature2', Feature2Extractor())])),
('null', None)
])
pipeline.transform(dictionary_of_dataframes)
我遇到另一个更基本的问题 - 改造后说出来的每个管道的两个特征矩阵有不同数量的行的。因此,FeatureUnion结束时的简单堆叠失败如下:
ValueError: all the input array dimensions except for the concatenation axis must match exactly
这是我拥有的数据的基础。 feature1表中不存在多个user_id,类似地,feature2表中没有多个user_id。这是数据的基础 - 如果用户在feature1表中没有数据,他/她从未在应用中使用该功能,例如没有数据=没有参与该功能。为了让这个例子明确,这里的两个DF的正在传递到每个变压器的例子:
DF(为特征1)
user_id, x1, timestamp
1, 'click', 1/1/2016
1, 'click', 1/2/2016
2, 'click', 1/2/2016
DF(为特征2)
user_id, x2, timestamp
2, 12.3, 1/2/2016
3, 14,5, 1/4/2016
注特征1的DataFrame没有用户3,特征2的DataFrame没有用户1.当我没有使用管道时,我会在最终的合并数据框上做一个外连接,然后fillna(0),例如
merged_df = pd.merge(df1, df1, how='outer', left_on=['user_id'], right_on=['user_id'])
final_df = merged_df.fillna(0)
但是似乎没有任何方法可以使用FeatureUnion方法来实现此目的。我似乎没有想到在Pipeline框架中有一个干净的解决方法......我必须运行单独的管道,对它们进行转换,在pandas中执行外连接和fillna,然后将完成的功能矩阵运行到下游建模管道?有没有更好的办法?展望社区寻求帮助。
注:我不知道user_ids之前。我根据时间戳范围查询表格,而不是user_id。查询本身告诉我应该在训练(或测试)中设置哪些用户。
很难跟随你的要求。给我们一些示例数据或一个小的输入/输出,以便我们可以验证您遇到的问题。我不确定为什么你不能填充一个数据集,使其具有与其他数据行相同的行数(用“None”或其他填充),然后执行FeatureUnion – mwm314
您是对的,我将编辑适当的......我不知道所有的user_ids在手之前 - 这就是为什么我正在做一个外连接......我不想单独跟踪这个。我将以一个很好的例子来编辑这个以更加专注。 –