原文官网链接:Representing Data with EntitySets
实体集 EntitySets是实体及其之间关系的集合。它们对于为特征工程准备原始的结构化数据集非常有用。尽管Featuretools中的许多函数将实体和关系作为不同的参数,但建议创建一个EntitySet,以便你可以根据需要更轻松地操作数据。
下面我们有两个与客户交易相关的数据表(表示为Pandas的DataFrames)。第一个是transactions、sessions和customers的合并,以便结果看起来像日志文件中可能看到的内容:
import featuretools as ft
data = ft.demo.load_mock_customer()
transactions_df = data["transactions"].merge(data["sessions"]).merge(data["customers"])
transactions_df.sample(10)
第二个dataframe是这些交易中涉及的产品列表。
products_df = data["products"]
首先,我们初始化一个EntitySet。如果你想给它一个名字,你可以选择在构造器中给出一个id。
es = ft.EntitySet(id="customer_data")
开始,我们加载transactions(交易记录)的dataframe作为一个实体。
es = es.entity_from_dataframe(entity_id="transactions",
dataframe=transactions_df,
index="transaction_id",
time_index="transaction_time",
variable_types={"product_id": ft.variable_types.Categorical,
"zip_code": ft.variable_types.ZIPCode})
es
注意:你也可以通过调用 EntitySet.plot()以图形化的方式展示你的实体集结构。
该方法把dataframe的每一列加载为一个变量。可以使用下面代码观察实体中的变量。
es["transactions"].variables
在调用entity_from_dataframe时,我们指定三个重要参数: 1、index参数指定唯一标识dataframe的一行的列
2、time_index参数告诉Featuretools什么时候创建的数据
3、variable_types参数指定“product_id”应该被作为类别变量解释,虽然它在基础数据中是整形的。
现在,我们可以对products的dataframe做同样的事:
es = es.entity_from_dataframe(entity_id="products",
dataframe=products_df,
index="product_id")
我们的实体集中有两个实体,我们可以给他们添加一个关系。
我们想通过每个实体的“product_id”列关联这两个实体。每种产品有多个相关交易,所以它被称为父实体,交易实体则作为子实体。指定关系时,先列上父实体的变量。注意,每个ft.Relationship必须表示为一对多关系,而不是一对一或多对多关系。
new_relationship = ft.Relationship(es["products"]["product_id"],
es["transactions"]["product_id"])
es = es.add_relationship(new_relationship)
es
现在,可以看到关系已经添加到了实体中。
在处理原始数据时,通常有足够的信息来证明创建新实体的合理性。为了为sessions创建新的实体和关系,我们将transaction实体“规范化”。
es = es.normalize_entity(base_entity_id="transactions",
new_entity_id="sessions",
index="session_id",
make_time_index="session_start",
additional_variables=["device", "customer_id", "zip_code", "session_start", "join_date"])
es
观察上面的输出,可以看到该方法做了两个操作:
1、基于“transactions”中的两个变量“session_id” 和“session_start”创建了“sessions”实体
2、添加了连接“transactions” 和 “sessions”的关系
如果观察transactions里和新sessions实体里的变量,可以看到另外两个操作自动执行了。
es["transactions"].variables
es["sessions"].variables
它从“transactions”中移走了“device”, “customer_id”, “zip_code” and “join_date”,并在sessions实体创建了一个新变量。这减少了冗余信息,因为会话的属性在事务之间不会改变。
它将“session_start”作为时间索引变量复制并标记到新的sessions实体中,以标识会话的开始。如果基本实体具有时间索引,并且未设置make_time_index,normalize entity将为新实体创建时间索引。在这种情况下,它将使用每个会话的第一个事务的时间创建一个名为“first_transactions_time”的新时间索引。如果不希望创建此时间索引,可以设置make_time_index=False。
如果我们查看dataframes,可以看到normalize_entity对实际数据做了什么。
为完成该数据集的准备,用统一的方法调用创建一个“customers”实体:
es = es.normalize_entity(base_entity_id="sessions",
new_entity_id="customers",
index="customer_id",
make_time_index="join_date",
additional_variables=["zip_code", "join_date"])
最后,我们已准备好将此实体集与Featuretools中的任何功能一起使用。例如,让我们为数据集中的每个产品构建一个特征矩阵。
feature_matrix, feature_defs = ft.dfs(entityset=es,
target_entity="products")
feature_matrix
如我们所见,DFS的特性使用了实体集的关系结构。因此,仔细思考我们创造的实体是很重要的。