3

我正在为当前行生成历史特征featuretools。例如,会话期间最后一小时内进行的事务数。

featuretools包含参数cutoff_time以排除cutoff_time及时出现的所有行。

我设置cutoff_timetime_index value - 1 second,因此我希望这些功能基于历史数据减去当前行。这允许包括来自历史行的响应变量。

问题是,当这个参数不等于变量时,我会在原始特征生成特征中time_index得到一堆s。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'](无时间增量),此代码有效,但包含当前行。

计算将从计算中排除当前行的聚合和转换的正确方法是什么?

4

2 回答 2

2

您所看到的是截止时间和 的预期行为time_index。实体的time_index代表第一次可以知道每个实例的任何信息。当您向 Featuretools 提供截止时间时,它会通过删除时间索引在截止时间之后的行来模拟数据集上的数据集状态。

在这种情况下,事务的transaction_idsession_id在事务时间之前是未知的,这是有道理的,因为事务尚未发生。这就是为什么当您要求 Featuretools 在交易时间前一秒计算特征时,它会返回NaN所有特征。

处理此问题的方法是将secondary_time_indexamount分配给in之类的变量transactions。此Stack Overflow 答案的高级解决方案对此进行了描述。这使您可以告诉 Featuretools 特定变量在该时间无效,transaction_time并且只能在您的次要时间索引列中使用。本质上,您将阻止某些行值在事务时使用,同时允许其他值。您可以为该实体中的任意数量的变量分配辅助时间索引。

于 2018-07-05T20:36:27.277 回答
1

根据 Max Kanter 的回答:

#!/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 分钟前的行。

于 2018-07-06T09:54:46.870 回答