【问题标题】:featuretools historical label counts特征工具历史标签计数
【发布时间】:2020-01-22 10:00:01
【问题描述】:

背景

对于 CRM 项目,我有机会的快照。我已经能够使用featuretools 构建许多功能,但我真正想要的是拥有历史胜利计数和比率。换句话说,我想知道:

对于给定的机会,在最后一次修改机会之前已经赢得了多少笔交易?

示例数据

import pandas as pd
import featuretools as ft

df = pd.DataFrame(
    {'OpportunityId': [111, 111, 222, 222, 222, 333, 333, 333],
     'UpdateId': [1,3,2,5,7,4,6,8],
     'Label': ['Open', 'Win', 'Open', 'Open', 'Win', 'Open', 'Open', 'Open'],
     'CreatedOn': pd.to_datetime(['9/27/18','9/27/18','9/28/18','9/28/18','9/28/18','10/2/18','10/2/18','10/2/18']),
     'ModifiedOn': pd.to_datetime(['9/27/18','10/1/18','9/28/18','10/3/18','10/7/18','10/2/18','10/6/18','10/10/18']),
     'EstRevenue': [2000, 2000, 80000, 84000, 78000, 100000, 95000, 110000]})
df
| OpportunityId | UpdateId | Label | CreatedOn  | ModifiedOn | EstRevenue |
|---------------|----------|-------|------------|------------|------------|
| 111           | 1        | Open  | 2018-09-27 | 2018-09-27 | 2000       |
| 111           | 3        | Win   | 2018-09-27 | 2018-10-01 | 2000       |
| 222           | 2        | Open  | 2018-09-28 | 2018-09-28 | 80000      |
| 222           | 5        | Open  | 2018-09-28 | 2018-10-03 | 84000      |
| 222           | 7        | Win   | 2018-09-28 | 2018-10-07 | 78000      |
| 333           | 4        | Open  | 2018-10-02 | 2018-10-02 | 100000     |
| 333           | 6        | Open  | 2018-10-02 | 2018-10-06 | 95000      |
| 333           | 8        | Open  | 2018-10-02 | 2018-10-10 | 110000     |

期望的输出

| OPPORTUNITIES | Label | CreatedOn | Max( ModifiedOn ) | AVG( EstRevenue ) | Wins |
|---------------|-------|-----------|-------------------|------------------:|------|
| 111           | Win   | 9/27/18   | 10/1/18           |              2000 | 0    |
| 222           | Win   | 9/28/18   | 10/7/18           |             80667 | 1    |
| 333           | Open  | 10/2/18   | 10/10/18          |            101667 | 2    |

目前的尝试

让我难以理解的是……

  1. 依赖于多个机会的功能...我需要一个单独的实体吗?
  2. 如何聚合同时提供两者的Label
    1. Label 的当前值,以及
    2. Label列为0时的计数

我面临的挑战是Label 专栏...虽然通常我会创建一个CurrentLabel 专栏,但我很确定ft 可以处理这个...

es = (ft.EntitySet(id='CRM')
      .entity_from_dataframe(
          entity_id='updates',
          dataframe=df,
          index='UpdateId',
          time_index='ModifiedOn')
      .normalize_entity(
          base_entity_id='updates',
          new_entity_id='opportunities',
          index='OpportunityId',
          make_time_index='CreatedOn',
          copy_variables=['Label'],
          additional_variables=['CreatedOn']
      )
)
es['updates']['Label'].interesting_values  = ['Win']
Entityset: CRM
  Entities:
    updates [Rows: 8, Columns: 5]
    opportunities [Rows: 3, Columns: 3]
  Relationships:
    updates.OpportunityId -> opportunities.OpportunityId
feature_matrix, feature_defs = ft.dfs(
    entityset=es,
    target_entity="opportunities",
    agg_primitives=[
        "mean","count","num_unique","time_since_first"],
    trans_primitives=[
        'time_since_previous'],
    where_primitives=[
        "sum","count"],
    max_depth=2,
    verbose=1
)

【问题讨论】:

  • 'Wins''Label' 列中聚合结果的逻辑是什么?我了解其他列,但不了解这些列。
  • Label 是机会是“赢”还是“输”,我试图预测。 Wins 列是问题的答案:在最后一次修改机会之前已经赢得了多少笔交易?

标签: python pandas python-3.6 featuretools


【解决方案1】:

有几种不同的方法可以解决这个问题:

  1. 创建一个新的数据框列并使用last 聚合原语

对于这种方法,在您创建实体集之前,首先在您的数据框中创建一个新的 Wins 列,以跟踪随时间推移的累计获胜总数。您可能需要按 ModifiedOn 列对数据框进行排序,以确保累积总和值正确。另外,我在这里使用.shift() 将列值移动一个位置,以仅计算更新之前发生的胜利:

df = df.sort_values('ModifiedOn')
df['Wins'] = df['Label'].shift().eq('Win').cumsum()

当您运行深度特征合成时,将last 原语添加到您的agg_primitives 列表中:

feature_matrix, feature_defs = ft.dfs(
    entityset=es,
    target_entity="opportunities",
    agg_primitives=["mean", "count", "num_unique", "time_since_first", "last"],
    trans_primitives=["time_since_previous"],
    where_primitives=["sum", "count"],
    max_depth=2,
    verbose=1
)

现在,当您检查特征矩阵时,您将有一个标记为 LAST(updates.Label) 的列,其中显示了上次更新机会时 Label 的值。您还将有一个标有 LAST(updates.Wins) 的列,其中显示了上次更新机会时的总胜数。

  1. 使用带有自定义原语的种子特征 这种方法在概念上与第一种方法相似,但利用种子特征和自定义原语来获得所需的输出。

在运行深度特征合成之前,创建一个新的布尔种子特征来定义 Label 是否等于 Win

label_is_win = ft.Feature(es["updates"]["Label"]) == "Win"

接下来,定义一个自定义转换原语,该原语将使用此种子功能返回获胜的累积总和:

class ShiftedCumSumBoolean(ft.primitives.TransformPrimitive):
    name = "shifted_cum_sum_boolean"
    input_types = [ft.variable_types.Boolean]
    return_type = ft.variable_types.Numeric
    uses_full_entity = True

    def get_function(self):
        def shifted_cum_sum(values):
            return values.shift(fill_value=(False)).cumsum()

        return shifted_cum_sum

运行深度特征合成时,将新的ShiftedCumSumBoolean 原语添加到trans_primitives 列表中。此外,将last 原语添加到agg_primitives 列表中,以在机会更新时提供最后一个标签值。最后,将label_is_win 种子特征添加到ft.dfs 调用中的种子特征列表中:

feature_matrix, feature_defs = ft.dfs(
    entityset=es,
    target_entity="opportunities",
    agg_primitives=["mean","count","num_unique","time_since_first", "last"],
    trans_primitives=["time_since_previous", ShiftedCumSumBoolean],
    where_primitives=["sum", "count"],
    seed_features=[label_is_win],
    max_depth=2,
    verbose=1,
)

使用此解决方案,您的特征矩阵将有一个标记为 LAST(updates.Label) 的列,显示上次更新机会时 Label 的值。您还将有一个标有 LAST(updates.SHIFTED_CUM_SUM_BOOLEAN(Label = Win)) 的列,其中显示了上次更新机会时的总获胜次数。

【讨论】:

    猜你喜欢
    • 2018-08-28
    • 2010-09-24
    • 2011-02-06
    • 1970-01-01
    • 2018-11-09
    • 1970-01-01
    • 2021-09-13
    • 2011-12-24
    • 2014-11-21
    相关资源
    最近更新 更多