Я пытаюсь использовать функциональные возможности FeatureUnion scycit-learn Pipelines в проекте, где данные находятся в базе данных. У меня возникают некоторые фундаментальные проблемы в том, как структурировать то, что я делаю.Sci-Kit Learn 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)
Я бегу в другую более основополагающий вопрос - после трансформации двух функциональных матриц, которые выходят из каждого трубопровода имеют различное количество строк. Следовательно, простой hstack в конце FeatureUnion не удается, так как:
ValueError: all the input array dimensions except for the concatenation axis must match exactly
Это имеет фундаментальное значение для данных у меня есть. Существует ряд user_id, которые не присутствуют в таблице feature1, аналогично существует ряд user_id, которых нет в таблице feature2. Это имеет фундаментальное значение для данных - если у пользователя нет данных в таблице feature1, он/она никогда не использовал эту функцию в приложении, например. нет данных = нет взаимодействия с этой функцией. Для того, чтобы сделать пример явным, вот пример из двух ДФ-х, которые передается каждому трансформатору:
ДФ (для Feature1)
user_id, x1, timestamp
1, 'click', 1/1/2016
1, 'click', 1/2/2016
2, 'click', 1/2/2016
ДФ (для feature2)
user_id, x2, timestamp
2, 12.3, 1/2/2016
3, 14,5, 1/4/2016
Примечание как DataFrame для feature1 не имеет пользователя 3, а DataFrame для функции2 не имеет пользователя 1. Когда я делал это без Pipelines, я бы сделал внешнее соединение, а затем 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 ... Я должен запускать отдельные конвейеры, преобразовывать каждую из них, выполнять внешнее соединение и заполнять в пандах, а затем запускать завершенную матрицу функций в нисходящий поток моделирование трубопровода? Есть ли способ лучше? Глядя в сообщество за помощью.
ПРИМЕЧАНИЕ. Я НЕ знаю user_ids перед началом работы. Я запрашиваю таблицы на основе диапазона метка времени ... не user_id. Сам запрос сообщает мне, какие пользователи должны иметь в настройке обучения (или теста).
Это трудно следовать, что вы просите. Дайте нам некоторые примеры данных или небольшой ввод/вывод, чтобы мы могли проверить проблему, с которой вы сталкиваетесь. Я не уверен, почему вы не можете заполнить один набор данных, чтобы иметь только то же количество строк, что и другое (заполните его «Нет или что-то»), а затем выполните FeatureUnion – mwm314
. Вы правы, я отредактирую надлежащим образом ... Я не знаю всех user_ids перед рукой, хотя --- вот почему я делал внешнее соединение ... я не хочу отслеживать это отдельно. Я отредактирую это, чтобы быть более сосредоточенным с хорошим примером. –