Исключение текущей строки из конструирования объектов в инструментальных средствах Python - PullRequest
0 голосов
/ 05 июля 2018

Я генерирую исторические объекты для текущей строки с featuretools. Например, количество транзакций, выполненных за последний час во время сеанса.

Пакет featuretools включает параметр cutoff_time для исключения всех строк, следующих за cutoff_time во времени.

Я установил cutoff_time как time_index value - 1 second, поэтому я ожидаю, что функции будут основаны на исторических данных минус текущая строка. Это позволяет включать переменную ответа из исторических строк.

Проблема в том, что когда этот параметр не равен переменной time_index, я получаю набор NaN с в исходных и созданных функциях.

Пример:

#!/usr/bin/env python3

import featuretools as ft
import pandas as pd
from featuretools import primitives, variable_types

data = ft.demo.load_mock_customer()

transactions_df = data['transactions']
transactions_df['cutoff_time'] = transactions_df['transaction_time'] - pd.Timedelta(seconds=1)

es = ft.EntitySet('transactions_set')
es.entity_from_dataframe(
    entity_id='transactions',
    dataframe=transactions_df,
    variable_types={
        'transaction_id': variable_types.Index,
        'session_id': variable_types.Id,
        'transaction_time': variable_types.DatetimeTimeIndex,
        'product_id': variable_types.Id,
        'amount': variable_types.Numeric,
        'cutoff_time': variable_types.Datetime
    },
    index='transaction_id',
    time_index='transaction_time'
)
es.normalize_entity(
    base_entity_id='transactions',
    new_entity_id='sessions',
    index='session_id'
)
es.add_last_time_indexes()

fm, features = ft.dfs(
    entityset=es,
    target_entity='transactions',
    agg_primitives=[primitives.Sum, primitives.Count],
    trans_primitives=[primitives.Day],
    cutoff_time=transactions_df[['transaction_id', 'cutoff_time']].
        rename(index=str, columns={'transaction_id': 'transaction_id', 'cutoff_time': 'time'}),
    training_window='1 hours',
    verbose=True
)

print(fm)

Вывод (выдержка):

                DAY(cutoff_time)  sessions.SUM(transactions.amount)  \
transaction_id                                                        
352                          NaN                                NaN   
186                          NaN                                NaN   
319                          NaN                                NaN   
256                          NaN                                NaN   
449                          NaN                                NaN   
40                           NaN                                NaN   
13                           NaN                                NaN   
127                          NaN                                NaN   
21                           NaN                                NaN   
309                          NaN                                NaN   

Столбец sessions.SUM(transactions.amount) должен быть> = 0. Оригинальные функции session_id product_id amount также NaN.

Если transactions_df['cutoff_time'] = transactions_df['transaction_time'] (без разницы во времени), этот код работает, но включает текущую строку.

Как правильно вычислять агрегаты и преобразования, которые исключают текущую строку из вычислений?

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

На основании ответа Макса Кантера:

#!/usr/bin/env python3

import featuretools as ft
import pandas as pd
from featuretools import primitives, variable_types

data = ft.demo.load_mock_customer()

transactions_df = data['transactions']
transactions_df['response_time'] = transactions_df['transaction_time'] + pd.Timedelta(seconds=1)

es = ft.EntitySet('transactions_set')
es.entity_from_dataframe(
    entity_id='transactions',
    dataframe=transactions_df,
    variable_types={
        'transaction_id': variable_types.Index,
        'session_id': variable_types.Id,
        'transaction_time': variable_types.DatetimeTimeIndex,
        'product_id': variable_types.Id,
        'amount': variable_types.Numeric,
        'response_time': variable_types.Datetime
    },
    index='transaction_id',
    time_index='transaction_time',
    secondary_time_index={'response_time': ['amount', 'transaction_id']}
)
es.normalize_entity(
    base_entity_id='transactions',
    new_entity_id='sessions',
    index='session_id'
)
es.add_last_time_indexes()

fm, features = ft.dfs(
    entityset=es,
    target_entity='transactions',
    agg_primitives=[primitives.Sum, primitives.Count],
    trans_primitives=[primitives.Day],
    cutoff_time=transactions_df[['transaction_id', 'transaction_time']],
    cutoff_time_in_index=True,
    training_window='5 minutes',
    verbose=True
)

print(fm)

Этот код создает функции sessions.SUM(transactions.amount) и sessions.COUNT(transactions), которые исключают текущую строку и включают все предыдущие строки, возраст которых менее 5 минут.

0 голосов
/ 05 июля 2018

То, что вы видите, - это предполагаемое поведение времени отключения и time_index. time_index объекта представляет собой первый раз, когда любая информация может быть известна для каждого экземпляра. Когда вы предоставляете время отсечения для Featuretools, оно имитирует состояние набора данных в наборе данных, удаляя строки, где индекс времени находится после времени отсечения.

В этом случае transaction_id и session_id для транзакции неизвестны до времени транзакции, что имеет смысл, поскольку транзакция не произошла. Вот почему, когда вы просите Featuretools рассчитать объекты за секунду до времени транзакции, он возвращает NaN для всех объектов.

Способ справиться с этим состоит в том, чтобы назначить second_time_index таким переменным, как amount в transactions. Это описано в расширенном решении этого ответа Stack Overflow . Это позволяет вам сообщить Featuretools, что конкретная переменная недопустима для использования в transaction_time и может использоваться только в то время, когда вы используете столбец вторичного индекса времени. По сути, вы бы блокировали использование некоторых значений строки во время транзакции, одновременно допуская другие значения. Вы можете назначить вторичный временной индекс любому количеству переменных в этом объекте.

...