3

我知道 featuretools 有 ft.calculate_feature_matrix 方法,但它计算数据使用测试。我需要在获得特征时使用训练数据,并加入测试数据,而不是在测试数据上使用相同的特征。例如:训练数据:

id sex score
1 f 100
2 f 200
3 m 10
4 m 20

dfs后,我得到:</p>

id sex score sex.mean(score)
1 f 100 150
2 f 200 150
3 m 10 15
4 m 20 15

我想在测试集上这样:</p>

id sex score sex.mean(score)
5 f 30 150
6 f 40 150
7 m 50 15
8 m 60 15

不是

id sex score sex.mean(score)
5 f 30 35
6 f 40 35
7 m 50 55
8 m 60 55

我怎样才能实现它,谢谢。</p>

4

1 回答 1

2

Featuretools 最适合处理直接用时间信息注释的数据来处理此类情况。在计算您的特征时,您指定一个“截止时间”,然后您想过滤掉数据。如果我们重组您的数据,并添加一些时间信息,Featuretools 可以完成您想要的。

首先,让我创建一个人的 DataFrame

import pandas as pd

people = pd.DataFrame({"id": [1, 2, 3, 4, 5, 6, 7, 8],
                       "sex": ['f', 'f', 'm', 'm', 'f', 'f', 'm', 'm']})

看起来像这样

   id sex
0   1   f
1   2   f
2   3   m
3   4   m
4   5   f
5   6   f
6   7   m
7   8   m

然后,让我们创建一个单独的分数 DataFrame,在其中我们用它发生的时间来注释每个分数。这可以是日期时间或整数。在本例中为简单起见,我将时间0用于训练数据,时间1用于测试数据。

scores = pd.DataFrame({"id": [1, 2, 3, 4, 5, 6, 7, 8],
                       "person_id": [1, 2, 3, 4, 5, 6, 7, 8],
                       "time": [0, 0, 0, 0, 1, 1, 1, 1],
                       "score": [100, 200, 10, 20, 30, 40, 50, 60]})

看起来像这样

   id  person_id  score  time
0   1          1    100     0
1   2          2    200     0
2   3          3     10     0
3   4          4     20     0
4   5          5     30     1
5   6          6     40     1
6   7          7     50     1
7   8          8     60     1

现在,让我们在 Featuretools 中创建一个 EntitySet,在分数实体中指定“时间索引”

import featuretools as ft

es = ft.EntitySet('example')

es.entity_from_dataframe(dataframe=people,
                         entity_id='people',
                         index='id')

es.entity_from_dataframe(dataframe=scores,
                         entity_id='scores',
                         index='id',
                         time_index= "time")

# create a sexes entity
es.normalize_entity(base_entity_id="people", new_entity_id="sexes", index="sex")

# add relationship for scores to person
scores_relationship = ft.Relationship(es["people"]["id"],
                                      es["scores"]["person_id"])
es = es.add_relationship(scores_relationship)


es

这是我们的实体集

Entityset: example
  Entities:
    scores [Rows: 8, Columns: 4]
    sexes [Rows: 2, Columns: 1]
    people [Rows: 8, Columns: 2]
  Relationships:
    scores.person_id -> people.id
    people.sex -> sexes.sex

接下来,让我们计算感兴趣的特征。请注意,当我们使用cutoff_time参数指定最后一次允许使用数据进行计算时。这确保了在计算过程中我们的任何测试数据都不可用。

from featuretools.primitives import Mean
mean_by_sex = ft.Feature(Mean(es["scores"]["score"], es["sexes"]), es["people"])
ft.calculate_feature_matrix(entityset=es, features=[mean_by_sex], cutoff_time=0)

现在的输出是

    sexes.MEAN(scores.score)
id
1                        150
2                        150
3                         15
4                         15
5                        150
6                        150
7                         15
8                         15

此功能非常强大,因为我们可以以比单个训练/测试拆分更细粒度的方式处理时间。

有关时间索引如何在 Featuretools 中工作的信息,请阅读文档中的处理时间页面。

编辑

如果要自动定义许多特征,可以通过调用使用 Deep Feature Synthesisft.dfs

feature_list = ft.dfs(target_entity="people",
                      entityset=es,
                      agg_primitives=["count", "std", "max"],
                      features_only=True)
feature_list

这将返回您可以传递给的功能定义ft.calculate_feature_matrix

[<Feature: sex>,
 <Feature: MAX(scores.score)>,
 <Feature: STD(scores.time)>,
 <Feature: STD(scores.score)>,
 <Feature: COUNT(scores)>,
 <Feature: MAX(scores.time)>,
 <Feature: sexes.STD(scores.score)>,
 <Feature: sexes.COUNT(people)>,
 <Feature: sexes.STD(scores.time)>,
 <Feature: sexes.MAX(scores.score)>,
 <Feature: sexes.MAX(scores.time)>,
 <Feature: sexes.COUNT(scores)>]

在这篇文章中阅读有关 DFS 的更多信息

于 2018-10-07T23:42:26.893 回答