首页 文章

从Python featuretools中排除特征工程的当前行

提问于
浏览
2

我正在使用 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 回答

  • 1

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

    在这种情况下,事务的_2411576和 session_id 在事务时间之前是未知的,这是有道理的,因为事务尚未发生 . 这就是为什么当您要求Featuretools在事务时间之前一秒钟计算要素时,它会为所有要素返回 NaN .

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

  • 0

    根据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分钟的所有先前行 .

相关问题