代码之家  ›  专栏  ›  技术社区  ›  Anton Tarasenko Jace Browning

在python featuretools中从特性工程中排除当前行

  •  2
  • Anton Tarasenko Jace Browning  · 技术社区  · 7 年前

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

    包裹 特色工具 包含参数 cutoff_time 排除后面的所有行 截止时间 及时。

    我设置 截止时间 作为 time_index value - 1 second ,所以我希望这些特性基于历史数据减去当前行。这允许包含来自历史行的响应变量。

    问题是,当这个参数不等于 time_index 变量,我得到一堆 NaN 原文中的S 生成的特征。

    例子:

    #!/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 都是 也。

    如果 transactions_df['cutoff_time'] = transactions_df['transaction_time'] (无时间增量),此代码有效,但包含当前行。

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

    2 回复  |  直到 7 年前
        1
  •  1
  •   Max Kanter    7 年前

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

    在这种情况下, transaction_id session_id 因为事务在事务时间之前是未知的,这是有意义的,因为事务尚未发生。这就是为什么当您要求FeatureTools在事务时间前一秒计算功能时,它会返回 NaN 所有的功能。

    处理此问题的方法是指定 secondary_time_index 变量如下 amount 在里面 transactions 是的。这在高级解决方案中有描述 Stack Overflow answer .这允许您告诉FeatureTools特定变量在 transaction_time 并且只能在第二时间索引列中使用。实际上,您将阻止某些行值在事务处理时被使用,同时允许其他值。可以为该实体中的任意数量的变量指定辅助时间索引。

        2
  •  0
  •   Anton Tarasenko Jace Browning    7 年前

    根据麦克斯·坎特的回答:

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