我正在尝试在数据库中数据的项目上使用Scikit-Learn Pipelines的功能功能。我在如何构建自己的工作方面存在一些基本问题。
我正在数据库中的两个不同表中创建两个功能。我有一个fetch_x1,fetch_x2方法,可以从数据库表中获取引人注目的数据作为pandas dataframes。我将两个数据框打包到数据框字典中。在每个变压器中,我打开了感兴趣的数据框架并在其上进行操作。我有点遵循这篇文章的模式。
我的代码如下:
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)
我遇到了另一个更基本的问题 - 转换后,每个管道中出现的两个特征矩阵具有不同数量的行。因此,功能上的简单hstack像这样失败了:
ValueError: all the input array dimensions except for the concatenation axis must match exactly
这对于我拥有的数据至关重要。功能1表中有许多User_ids不存在,同样,功能2表中的许多USER_ID不存在。这是数据的基础 - 如果用户在功能1表中没有数据,则他/她从未在应用中使用该功能,例如无数据=与该功能无参与。为了明确说明示例,这是传递给每个变压器的两个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。当我没有管道的情况下这样做时,我会进行外部加入,然后在结果的合并数据框架上填充(0),例如
merged_df = pd.merge(df1, df1, how='outer', left_on=['user_id'], right_on=['user_id'])
final_df = merged_df.fillna(0)
,但似乎没有任何方法可以使用功能方法来执行此操作。而且我似乎无法想到管道框架中的干净解决方法...我必须运行单独的管道,转换每个管道,在熊猫中进行外部连接和填充,然后将完成的功能矩阵运行到下游建模管道?有没有更好的办法?寻求社区寻求帮助。
注意:我不知道之前不知道user_ids。我正在根据时间戳范围来查询表...而不是User_id。查询本身告诉我在培训(或测试)集中应该拥有的用户。
为什么,您不会建立自己的基于熊猫的联盟?这样的东西...(我没有测试过,只看到这个想法)
class DataMerging(BaseEstimator):
def __init__(self):
return self
def fit(self, x, y=None):
return self
def transform(self, dfs):
df1, df2 = dfs
merged_df = pd.merge(df1, df2, how='outer', left_on=['user_id'], right_on=['user_id']).fillna(0)
return merged_df.values #(return shape (n_features, n_samples))
pipeline = Pipeline([
('union', DataMerging,
('other thing', ...)
])
pipeline.fit(df1, df2)