2016-12-16 2 views
0

データがデータベースにあるプロジェクトで、scikit-learn PipelineのFeatureUnion機能を使用しようとしています。私は何をしているかを構造化する方法にいくつかの根本的な問題があります。Sci-Kit Learn FeatureUnionの行数が異なる

データベース内の2つの異なるテーブルから2つの機能を作成しています。私はfetch_x1、fetch_x2メソッドを持っていて、データベーステーブルから関心のあるデータをpandas DataFramesとして取得します。私は2つの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) 

- 変換後の各パイプラインから出てくる2つの特徴行列は、行の数が異なります。その結果、FeatureUnionの最後に簡単なhstackはそうのように失敗している:

ValueError: all the input array dimensions except for the concatenation axis must match exactly 

これは私が持っているデータの基本です。 feature1テーブルには存在しない多数のuser_idが存在します。同様に、feature2テーブルに存在しないuser_idもいくつか存在します。これはデータにとって基本的なことです。ユーザーがフィーチャ1テーブルにデータを持たない場合、ユーザーはフィーチャ1テーブル内のそのフィーチャを決して使用しませんでした。データなし=その機能との関与なし。 (特長1用)

DF(特長2用)

user_id, x1, timestamp 
1, 'click', 1/1/2016 
1, 'click', 1/2/2016 
2, 'click', 1/2/2016 

DF

user_id, x2, timestamp 
2, 12.3, 1/2/2016 
3, 14,5, 1/4/2016 

注:明示的な例を作成するには、ここでは各変圧器に渡される2つのDFさんの例ですフィーチャ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ではありません。クエリ自体は、トレーニング(またはテスト)のセットでユーザーがどのようなものを持っているべきかを教えてくれます。

+0

それはあなたが求めているものをフォローするのは難しいです。私たちにあなたが持っている問題を確認できるように、サンプルデータや小さな入出力を与えてください。私は、あなたが他のものと同じ数の行を持つように(なぜなら 'None'sか何かでそれを記入するために)1つのデータセットを満たすことができないのか分かりませんし、FeatureUnionを実行します。 – mwm314

+0

あなたは正しいです、私は編集します適切に...私はすべてのuser_idsを手前で知っているわけではありません---そういうわけで、私は外部結合を行っていました...私はそれを個別に追跡したくありません。これを編集して、良い例に集中するようにします。 –

答えて

0

なぜ、自分のパンダベースの組合を作りませんか?このような 何か...(私はそれをテストしていない、ただのアイデアを参照してください)

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) 
+0

これは面白いですが、これがパイプラインの説明にどのように適合しているか完全に理解していません...また、FeatureUnionをサブクラス化する必要がありますか? –

関連する問題