python - (Featuretools) 如何计算聚合特征图元?
问题描述
即使我使用非常简单的数据进行测试,我也不知道如何计算聚合特征原语。我也查看了 featuretools 代码,但找不到聚合操作发生在哪里。
以下是示例代码:
from sklearn.utils import shuffle
periods = 5
end_date = "2012-04-13"
train_df = pd.DataFrame(
{
"store_id": [0]*periods + [1]*periods + [2]*periods + [3]*periods,
"region": ["A"]*periods+["B"]*periods*3,
"amount": shuffle(range(periods*4)),
"transacted_date": [
"2012-02-05", "2012-02-10", "2012-03-01", "2012-03-18", "2012-04-23",
]*4
}
)
train_df["transacted_date"] = pd.to_datetime(train_df["transacted_date"])
train_df.sort_values(["store_id", "transacted_date"], inplace=True)
def make_retail_cutoffs_amounts(data_df, amount_start_date, amount_end_date):
store_pool = data_df[data_df['transacted_date'] < amount_start_date]['store_id'].unique()
tmp = pd.DataFrame({'store_id': store_pool})
amounts = data_df[
(data_df['store_id'].isin(store_pool)) &
(amount_start_date <= data_df['transacted_date']) &
(data_df['transacted_date'] < amount_end_date)
].groupby('store_id')['amount'].sum().reset_index()
amounts = amounts.merge(tmp, on = 'store_id', how = 'right')
amounts['amount'] = amounts['amount'].fillna(0) # 0으로 채워지는 애는 3개월 다 수익이 없는 녀석!
amounts['cutoff_time'] = pd.to_datetime(amount_start_date)
amounts = amounts[['store_id', 'cutoff_time', 'amount']]
amounts = amounts.rename(columns={"amount":"1month_amount_from_cutoff_time"})
return amounts
amount_start_date = "2012-02-01"
amount_end_date = end_date
agg_month = 1
data_df_list = []
date_list = pd.date_range(amount_start_date, datetime.strptime(end_date, "%Y-%m-%d") + pd.DateOffset(months=1), freq="MS")
for amount_start_date, amount_end_date in zip(date_list[:-agg_month], date_list[agg_month:]):
data_df_list.append(
make_retail_cutoffs_amounts(
train_df, amount_start_date, amount_end_date
)
)
data_df = pd.concat(data_df_list)
data_df.sort_values(["store_id", "cutoff_time", ], inplace=True)
import featuretools as ft
es = ft.EntitySet(id="sale_set")
es = es.entity_from_dataframe(
"sales",
dataframe=train_df,
index="sale_id", make_index=True,
time_index='transacted_date',
)
es.normalize_entity(
new_entity_id="stores",
base_entity_id="sales",
index="store_id",
additional_variables=['region']
)
# When using a training window,
# it is necessary to calculate the last time indexes for the entity set. Adding
es.add_last_time_indexes()
features = ft.dfs(
entityset=es,
target_entity='stores',
cutoff_time=data_df,
verbose=1,
cutoff_time_in_index=True,
n_jobs=1,
max_depth=2,
agg_primitives=["sum",],
trans_primitives=["cum_max"],
training_window="1 month",
)
dfs
工作正常,但无法解释结果特征。
这是特征的样本数据:
正如您在此处看到的,第一行SUM(sales.amount)
和SUM(sales.CUM_MAX(amount))
分别是 19 和 37。我想知道它们是如何计算的。
以下是我对结果的解释:
如您在此处看到的,store_0 在 2012 年 2 月有 2 条销售数据记录。因此,
SUM(sales.amount)
截止时间 2012-03-01 的 store_id=0 应该是 0 + 8 = 8,而不是 19。同样,
SUM(sales.CUM_MAX(amount))
截止时间为 2012-03-01 的 store_id=0 也应该是 SUM(sales.CUM_MAX(amount)) = SUM([0, 8]) = 8,而不是 37。
我错过了什么吗?它们是如何计算的?
解决方案
这些概念将帮助您了解如何计算特征:
- 时间索引达到并包括截止时间的数据用于计算特征。
- 为了
CumMax
在每个商店的基础上进行计算,它需要放置在groupby_trans_primitives
而不是trans_primitives
.
我将通过一个例子。这是 CSV 格式的数据。
store_id,region,amount,transacted_date
0,A,16,2012-02-05
0,A,15,2012-02-10
0,A,13,2012-03-01
0,A,2,2012-03-18
0,A,3,2012-04-23
1,B,9,2012-02-05
1,B,8,2012-02-10
1,B,14,2012-03-01
1,B,1,2012-03-18
1,B,5,2012-04-23
2,B,6,2012-02-05
2,B,12,2012-02-10
2,B,4,2012-03-01
2,B,7,2012-03-18
2,B,11,2012-04-23
3,B,18,2012-02-05
3,B,19,2012-02-10
3,B,0,2012-03-01
3,B,10,2012-03-18
3,B,17,2012-04-23
首先,我加载数据集。
import pandas as pd
train_df = pd.read_csv('data.csv', parse_dates=['transacted_date'])
train_df.sort_values(["store_id", "transacted_date"], inplace=True)
store_id region amount transacted_date
0 A 16 2012-02-05
0 A 15 2012-02-10
0 A 13 2012-03-01
0 A 2 2012-03-18
0 A 3 2012-04-23
1 B 9 2012-02-05
1 B 8 2012-02-10
1 B 14 2012-03-01
1 B 1 2012-03-18
1 B 5 2012-04-23
2 B 6 2012-02-05
2 B 12 2012-02-10
2 B 4 2012-03-01
2 B 7 2012-03-18
2 B 11 2012-04-23
3 B 18 2012-02-05
3 B 19 2012-02-10
3 B 0 2012-03-01
3 B 10 2012-03-18
3 B 17 2012-04-23
然后,我使用Compose自动生成相同的截止时间。
import composeml as cp
def total_amount(df):
return df.amount.sum()
lm = cp.LabelMaker(
target_entity='store_id',
time_index='transacted_date',
labeling_function=total_amount,
window_size='1MS',
)
lt = lm.search(
train_df,
num_examples_per_instance=-1,
minimum_data='2012-03-01',
)
store_id cutoff_time total_amount
0 2012-03-01 15
0 2012-04-01 3
1 2012-03-01 15
1 2012-04-01 5
2 2012-03-01 11
2 2012-04-01 11
3 2012-03-01 10
3 2012-04-01 17
现在,我构建实体集。
import featuretools as ft
es = ft.EntitySet(id="sale_set")
es = es.entity_from_dataframe(
"sales",
dataframe=train_df,
index="sale_id",
make_index=True,
time_index='transacted_date',
)
es.normalize_entity(
new_entity_id="stores",
base_entity_id="sales",
index="store_id",
additional_variables=['region'],
)
es.add_last_time_indexes()
这是一个了解实体集结构的图。
es.plot()
最后,我运行 DFS 来计算特征。
fm, fd = ft.dfs(
entityset=es,
target_entity='stores',
cutoff_time=lt,
cutoff_time_in_index=True,
agg_primitives=["sum"],
groupby_trans_primitives=["cum_max"],
training_window="1 month",
max_depth=2,
verbose=1,
)
fm.filter(regex='SUM')
SUM(sales.amount) SUM(sales.CUM_MAX(amount) by store_id)
store_id time
0 2012-03-01 44 48.0
2012-04-01 15 26.0
1 2012-03-01 31 32.0
2012-04-01 15 28.0
2 2012-03-01 22 30.0
2012-04-01 11 11.0
3 2012-03-01 37 56.0
2012-04-01 10 10.0
我们可以看到SUM(sales.amount)
for store 0
at cutoff time2012-03-01
包括直到并包括2012-03-01
计算特征的数据。
>>> 16 + 15 + 13
44
在 DFS 中SUM(sales.CUM_MAX(amount) by store_id)
作为 a 应用时也是如此。groupby_trans_primitives
>>> sum((16, 16, 16))
48
让我知道这是否有帮助。
推荐阅读
- c - 在 C 应用程序中使用 RegSetValueEx 注册事件日志 dll,对于 CategoryMessageFile 之类的内容是否需要完整路径?
- python - 如何使用 Python/通过 API 获取现有 Metabase 问题背后的 SQL 代码?
- javascript - 尽管有限制,AWS S3 createPresignedPost URL 可以上传任何大小的文件
- html - jQuery:下拉菜单按钮本身的动态 CSS
- loops - 如何在javascript中重新启动函数
- python - tkinter 输入框中的第一个字母没有被删除
- javascript - 使用 Webpack 延迟加载供应商 JS、CSS 文件
- pytest - pytest - 不同文件的相同`@fixture`
- python - 在 Session python (requests) 中使用代理
- php - WPGraphQL 为自定义帖子类型添加嵌套/多个查询