当前位置:首页>python>python的Featuretools库介绍

python的Featuretools库介绍

  • 2026-09-10 18:21:32
python的Featuretools库介绍

Featuretools 是一个强大的 Python 库,专注于自动化特征工程,特别是处理关系型数据和时间序列数据。其核心思想是通过“深度特征合成”算法,自动将多个表之间的关联关系转化为机器学习可用的特征矩阵。

下面我将通过大量代码实例,带你从零开始掌握 Featuretools。

1. 核心概念

在编写代码前,先理解三个关键组件:

EntitySet(实体集):数据集的集合,每个“实体”可以看作一个 DataFrame,实体之间通过“关系”连接(例如用户表和订单表)。

Deep Feature Synthesis (DFS):核心算法,通过“堆叠”特征基元沿着关系路径生成新特征。

Feature Primitives(特征基元):基础特征操作方法,分为聚合基元(如 sum, mean)和转换基元(如 hour, month)。

2. 基础示例:从多表数据生成特征

2.1 加载内置数据并创建 EntitySet

Featuretools 内置了一个模拟电商数据的示例,包含 customers、sessions 和 transactions 三个表。

import featuretools as ft# 加载示例数据(返回字典形式的多个DataFrame)data = ft.demo.load_mock_customer()# 查看数据结构customers_df = data["customers"]sessions_df = data["sessions"]transactions_df = data["transactions"]print("customers shape:", customers_df.shape)print("sessions shape:", sessions_df.shape)print("transactions shape:", transactions_df.shape)

输出示例:

customers shape: (5, 4)sessions shape: (35, 4)transactions shape: (500, 5)

接下来,我们将这三个 DataFrame 组织成一个 EntitySet,并定义它们之间的关系:

# 创建实体集es = ft.EntitySet(id="customer_data")# 添加各个实体,指定索引列和时间列(如果有)es = es.add_dataframe(    dataframe_name="customers",    dataframe=customers_df,    index="customer_id",)es = es.add_dataframe(    dataframe_name="sessions",    dataframe=sessions_df,    index="session_id",    time_index="session_start",  # 时间列,用于时间序列特征)es = es.add_dataframe(    dataframe_name="transactions",    dataframe=transactions_df,    index="transaction_id",    time_index="transaction_time",)# 定义表之间的关系# 关系: (父表, 父键, 子表, 子键)es = es.add_relationship("sessions", "session_id", "transactions", "session_id")es = es.add_relationship("customers", "customer_id", "sessions", "customer_id")# 查看实体集摘要es

输出会展示实体数量、每个实体的行数以及它们之间的关系。

2.2 运行深度特征合成

现在,我们以 customers 为目标实体,自动生成特征矩阵:

# 运行DFSfeature_matrix, feature_defs = ft.dfs(    entityset=es,    target_dataframe_name="customers",  # 目标实体    max_depth=2,                         # 最大深度,控制特征复杂度    agg_primitives=["mean", "sum", "count", "std"],  # 聚合基元    trans_primitives=["month", "hour", "weekday"],   # 转换基元    verbose=True,)print(f"生成的样本数: {feature_matrix.shape[0]}, 特征数: {feature_matrix.shape[1]}")feature_matrix.head()

运行后,你会看到为每个客户生成了大量统计特征,例如:

COUNT(sessions):每个客户的会话数量

MEAN(transactions.amount):该客户所有交易的平均金额

MODE(sessions.device):最常使用的设备类型

2.3 理解“深度特征”

当 max_depth=2 时,DFS 会堆叠基元产生更复杂的特征。例如,MEAN(sessions.SUM(transactions.amount)) 的含义是:

先对每个会话内的交易金额求和(SUM)

再对同一客户的所有会话求平均值(MEAN)

这样就得到了“客户平均每个会话的消费总额”这一有意义的特征。

3. 进阶应用:自定义基元

当内置基元不够用时,Featuretools 允许你定义自己的转换或聚合函数。

3.1 自定义转换基元:统计字符串中指定单词出现次数

假设我们有一个文本字段,想统计某个单词出现的次数:

import pandas as pdimport featuretools as ftfrom featuretools.primitives import make_trans_primitivefrom woodwork.logical_types import NaturalLanguage, Double# 定义计算函数def string_count(column, string=None):    """计算字符串中指定子串的出现次数"""    assert string is not None, "需要指定要计数的字符串"    return [text.lower().count(string) for text in column]# 自定义生成名称的函数,让特征名更有意义def string_count_generate_name(self, base_feature_names):    return f'STRING_COUNT("{self.kwargs["string"]}")'# 创建自定义基元StringCount = make_trans_primitive(    function=string_count,    input_types=[NaturalLanguage],    return_type=Double,    cls_attributes={"generate_name": string_count_generate_name})

现在可以将这个基元用于 DFS:

feature_matrix, _ = ft.dfs(    entityset=es,    target_dataframe_name="customers",    trans_primitives=[StringCount(string="the")],  # 统计"the"的出现次数    max_depth=1,)

3.2 自定义转换基元:多输出特征

有些转换需要返回多个值,比如同时统计大小写字母个数。Featuretools 也支持这种多输出场景:

import reimport numpy as npfrom featuretools.primitives import make_trans_primitivedef case_count(array):    """返回大写字母个数和小写字母个数"""    upper = np.array([len(re.findall('[A-Z]', i)) for i in array])    lower = np.array([len(re.findall('[a-z]', i)) for i in array])    return [upper, lower]  # 返回列表,每个元素是一个输出CaseCount = make_trans_primitive(    function=case_count,    input_types=[NaturalLanguage],    return_type=Double,    number_output_features=2  # 指定输出个数)

使用后,特征矩阵中会出现两列:CASE_COUNT(feature)[0] 和 CASE_COUNT(feature)[1]。

4. 单表场景的用法

即使只有一张表,Featuretools 也能发挥价值,尤其是当表内存在时间序列或多层级关系时。

import pandas as pdimport featuretools as ft# 假设有一张销售记录表sales_df = pd.DataFrame({    'order_id': range(100),    'customer_id': [i % 10 for i in range(100)],    'amount': np.random.randn(100) * 50 + 100,    'order_date': pd.date_range('2023-01-01', periods=100, freq='D')})# 创建实体集并添加单个实体es = ft.EntitySet(id="single_table")es = es.add_dataframe(    dataframe_name="orders",    dataframe=sales_df,    index="order_id",    time_index="order_date")# 运行DFS,以订单表为目标feature_matrix, _ = ft.dfs(    entityset=es,    target_dataframe_name="orders",    agg_primitives=["mean", "sum", "count"],    trans_primitives=["month", "day", "weekday"],    max_depth=1,)

此时 DFS 会:

对每个订单,从时间列提取月份、星期几等特征

如果通过 add_relationship 定义了父子关系(比如订单和商品明细),则可以生成聚合特征

5. 安装与性能优化

5.1 安装

# 基础安装pip install featuretools# 安装完整版(包含Dask支持、NLP基元等)pip install "featuretools[complete]"# 或通过 conda 安装conda install -c conda-forge featuretools

5.2 并行加速

DFS 支持多核并行计算,可通过 n_jobs 参数开启:

feature_matrix, _ = ft.dfs(    entityset=es,    target_dataframe_name="customers",    n_jobs=-1,  # 使用所有可用核心    max_depth=2,)

对于超大数据集,还可以结合 Dask 实现分布式计算。

6. 实际应用价值

Featuretools 生成的数百个特征可以直接输入到机器学习模型中。以 BigMart 销售预测为例,使用 Featuretools 自动生成特征后,模型在验证集上的 RMSE 从 1103 降低到 1092,并且公共排行榜分数也从 1183 提升到 1155。这种提升来自自动化特征工程挖掘出的深层统计信息,例如跨门店的商品聚合特征、时间趋势特征等。

总结

Featuretools 通过 EntitySet 组织关系数据,用深度特征合成自动生成复杂的统计特征,并支持自定义基元扩展功能。它的优势在于:

自动化:无需手动编写聚合代码

关系型数据友好:天然支持多表关联

可解释性:生成的特征名称清晰描述了构造过程

可扩展:支持自定义基元和并行计算

当你面对多表数据或需要大量统计特征时,Featuretools 是一个值得尝试的自动化工具。

最新文章

随机文章