深度特征合成
深度特征合成(DFS)是一种用于对关系数据和时间数据执行特征工程的自动方法。
输入数据
深度特征合成需要结构化数据集才能执行特征工程。为了演示DFS的功能,我们将使用客户交易数据集。
In [1]: import featuretools as ft
In [2]: es = ft.demo.load_mock_customer(return_entityset=True)
In [3]: es
Out[3]:
Entityset: transactions
Entities:
transactions [Rows: 500, Columns: 5]
products [Rows: 5, Columns: 2]
sessions [Rows: 35, Columns: 4]
customers [Rows: 5, Columns: 4]
Relationships:
transactions.product_id -> products.product_id
transactions.session_id -> sessions.session_id
sessions.customer_id -> customers.customer_id
一旦将数据准备为EntitySet,我们就可以针对目标实体进行自动特征生成。
运行DFS
通常,如果没有自动化特性工程,数据科学家需要通过编码实现客户数据聚合,并应用不同的统计函数进行客户行为数据的量化表示。在示例中,假设数据科学家可能对如下特征感兴趣:总的回话数或一个客户在一个月内总的登录此时。
In [4]: feature_matrix, feature_defs = ft.dfs(entityset=es,
...: target_entity="customers",
...: agg_primitives=["count"],
...: trans_primitives=["month"],
...: max_depth=1)
...:
In [5]: feature_matrix
Out[5]:
zip_code COUNT(sessions) MONTH(join_date) MONTH(date_of_birth)
customer_id
1 60091 8 4 7
2 13244 7 4 8
3 13244 6 8 11
4 60091 8 4 8
5 60091 6 7 7
在上述示例中,“count”是一个聚合原语,因为它基于一个客户的多个会话计算单个值。“月”被称为转换原语,因为它将客户的一个值转换为另一个值。
创建“深度特征”
“深度特征合成”这个名字来源于该算法能够堆叠原语以生成更复杂的特征。每次我们堆叠一个原语时,我们都会增加一个特征的“深度”。max_depth参数控制由DFS返回的特征的最大深度。在如下示例中进行深度为2的特征合成:
In [6]: feature_matrix, feature_defs = ft.dfs(entityset=es,
...: target_entity="customers",
...: agg_primitives=["mean", "sum", "mode"],
...: trans_primitives=["month", "hour"],
...: max_depth=2)
...:
In [7]: feature_matrix
Out[7]:
zip_code MODE(sessions.device) MEAN(transactions.amount) ... MODE(sessions.MODE(transactions.product_id)) MODE(sessions.MONTH(session_start)) MODE(sessions.HOUR(session_start))
customer_id ...
1 60091 mobile 71.631905 ... 4 1 6
2 13244 desktop 77.422366 ... 3 1 3
3 13244 desktop 67.060430 ... 1 1 5
4 60091 mobile 80.070459 ... 1 1 1
5 60091 mobile 80.375443 ... 3 1 0
[5 rows x 15 columns]
深度为2时,使用原语可以生成多个特征。通过返回的特征矩阵,可以帮助我们了解深度为2的特征
In [8]: feature_matrix[['MEAN(sessions.SUM(transactions.amount))']]
Out[8]:
MEAN(sessions.SUM(transactions.amount))
customer_id
1 1128.202500
2 1028.611429
3 1039.436667
4 1090.960000
5 1058.276667
对于每个客户的MEAN(sessions.SUM(transactions.amount))特征:
1、计算每个会话的所有交易金额之和,以获取每个会话的总金额
2、然后在这些会话上应用mean原语,从而获得米格会话的平均金额
我们将这个特征称之为深度为2的特征。
让我们来看另一个深度为2的特征,它为每个客户计算一天中最常见的开始会话的时间。
In [9]: feature_matrix[['MODE(sessions.HOUR(session_start))']]
Out[9]:
MODE(sessions.HOUR(session_start))
customer_id
1 6
2 3
3 5
4 1
5 0
对于每个客户,该特征计算过程如下:
1、获取客户会话开始的“时”
2、使用统计函数“mode”得到客户开始最常开始会话的“时”
堆叠会产生比单个原语本身更具表现力的特征。这可以自动创建复杂的机器学习模式。
修改目标Entity
DFS强大的原因在于其可以为数据集中的任何实体创建特征矩阵。如果我们将目标实体转换为“会话”,我们可以为每个会话而不是每个客户合生成特征。
In [10]: feature_matrix, feature_defs = ft.dfs(entityset=es,
....: target_entity="sessions",
....: agg_primitives=["mean", "sum", "mode"],
....: trans_primitives=["month", "hour"],
....: max_depth=2)
....:
In [11]: feature_matrix.head(5)
Out[11]:
customer_id device MEAN(transactions.amount) ... customers.MONTH(date_of_birth) customers.HOUR(join_date) customers.HOUR(date_of_birth)
session_id ...
1 2 desktop 76.813125 ... 8 23 0
2 5 mobile 74.696000 ... 7 5 0
3 4 mobile 88.600000 ... 8 20 0
4 1 mobile 64.557200 ... 7 10 0
5 4 mobile 70.638182 ... 8 20 0
[5 rows x 19 columns]
从上述示例可以看出,DFS可以基于父实体构建深度特征,上述构建了特定会话的客户特征。下述特征,则计算了一个会话中客户的平均交易金额。
In [12]: feature_matrix[['customers.MEAN(transactions.amount)']].head(5)
Out[12]:
customers.MEAN(transactions.amount)
session_id
1 77.422366
2 80.375443
3 80.070459
4 71.631905
5 80.070459