Featuretools для агрегирования на дочерних объектах с сохранением времени отсечения - PullRequest
2 голосов
/ 15 апреля 2020

Я пытался использовать featuretools с временными метками, чтобы использовать прошлые решения дистрибьюторов в качестве прогнозирующей переменной. У меня есть только один набор данных в качестве входных данных, с типичной проблемой двоичной классификации (с n строк). Существует множество распространителей (<<p> Очень важно соблюдать порядок меток времени при расчете средних меток, связанных с распределителями на каждой отметке времени, чтобы избежать утечки информации.

Вот как бы я это сделал это с Pandas:

import pandas as pd
import numpy as np
from datetime import datetime
import featuretools as ft

timestamps = ['2019-01-05-10:36:12', '2019-01-04-11:32:12', '2019-01-03-08:01:03', '2019-01-03-06:32:54',
                '2019-01-01-07:30:24', '2018-12-20-04:20:25']

time = [datetime.strptime(x,'%Y-%m-%d-%H:%M:%S') for x in timestamps]

data = {'time': time,
        'Distributor': ['A','B','A','B','B','B'],
        'Label': [1, 0, 0, 0, 0, 1]}

# Create DataFrame
df = pd.DataFrame(data)
df = df.sort_values(['Distributor','time'])

def past70(g):
    g = g.set_index('time').resample('D').last()
    g['Past_average_label_per_distributor'] = g['Label'].rolling(70, 0).mean().shift(1)
    return g[g.Label.notnull()]

df = df.groupby('Distributor').apply(past70)
df

Теперь делаем это утомительно с pandas, так как я хотел бы использовать много примитивов для моей проблемы (скажем, я хочу также стандартное отклонение прошлых меток для дистрибьюторов, но также многие другие переменные grouped_by, рассчитанные дистрибьюторами по временному окну)

Вот неудачная попытка с помощью featuretools:

import pandas as pd
import numpy as np
from datetime import datetime
import featuretools as ft

timestamps = ['2019-01-05-10:36:12', '2019-01-04-11:32:12', '2019-01-03-08:01:03', '2019-01-03-06:32:54',
                '2019-01-01-07:30:24', '2018-12-20-04:20:25']

time = [datetime.strptime(x,'%Y-%m-%d-%H:%M:%S') for x in timestamps]

data = {'time': time,
        'Distributor': ['A','B','A','B','B','B'],
        'Label': [1, 0, 0, 0, 0, 1]}

# Create DataFrame
df = pd.DataFrame(data)
df = df.sort_values(['Distributor','time'])

cutoff_times = pd.DataFrame({
    "index": df.index,
    "cutoff_time": df['time']
    })

es = ft.EntitySet(id='Sales')
es.entity_from_dataframe(entity_id='Sales', dataframe=df, index='index', make_index=True, time_index='time')
es = es.normalize_entity(base_entity_id='Sales', new_entity_id='Distributors', index='Distributor')

feature_matrix, feature_defs = ft.dfs(entityset=es, target_entity='Sales',
                                      cutoff_time=cutoff_times,
                                      where_primitives=['mean'], features_only=False,
                                      cutoff_time_in_index=False)

feature_matrix # not correct

Кто-нибудь может подсказать, как этого добиться? Не могу показаться чтобы найти что-то похожее в документации. Но это, кажется, довольно распространенная вещь в предварительной обработке машинного обучения.

1 Ответ

0 голосов
/ 24 апреля 2020

Вы можете использовать время отсечки в DFS для расчета этих значений. Я приведу go через пример, использующий тот же набор данных. Для справки: это вывод, который я получаю при запуске вашего кода в Pandas.

                       Distributor  Label  Past_average_label_per_distributor
Distributor time
A           2019-01-03           A    0.0                                 NaN
            2019-01-05           A    1.0                            0.000000
B           2018-12-20           B    1.0                                 NaN
            2019-01-01           B    0.0                            1.000000
            2019-01-03           B    0.0                            0.500000
            2019-01-04           B    0.0                            0.333333

Сначала мы создаем набор данных.

import pandas as pd
import numpy as np
import featuretools as ft

data = {
    'ID': [0, 1, 2, 3, 4, 5],
    'Distributor': ['A', 'B', 'A', 'B', 'B', 'B'],
    'Label': [1, 0, 0, 0, 0, 1],
    'Time': [
        '2019-01-05-10:36:12',
        '2019-01-04-11:32:12',
        '2019-01-03-08:01:03',
        '2019-01-03-06:32:54',
        '2019-01-01-07:30:24',
        '2018-12-20-04:20:25',
    ],
}

types = {'Time': 'datetime64[ns]'}
df = pd.DataFrame(data).astype(types)
df = df.sort_values(['Distributor', 'Time'])
print(df.to_string(index=False))
               Time Distributor  Label  ID
2019-01-03 08:01:03           A      0   2
2019-01-05 10:36:12           A      1   0
2018-12-20 04:20:25           B      1   5
2019-01-01 07:30:24           B      0   4
2019-01-03 06:32:54           B      0   3
2019-01-04 11:32:12           B      0   1

Затем мы построить набор сущностей.

es = ft.EntitySet()

es.entity_from_dataframe(
    entity_id='Sales',
    dataframe=df,
    time_index='Time',
    index='ID',
)

es.normalize_entity(
    base_entity_id='Sales',
    new_entity_id='Distributors',
    index='Distributor',
    make_time_index=False,
)

es.add_last_time_indexes()

es.plot()

enter image description here

Теперь мы сгенерируем матрицу объектов, используя время отсечения.

cutoff_times = df[['Distributor', 'Time', 'Label']]
cutoff_times['Time'] = cutoff_times['Time'].dt.normalize()

fm, _ = ft.dfs(
    target_entity='Distributors',
    entityset=es,
    trans_primitives=[],
    agg_primitives=['mean', 'std'],
    cutoff_time=cutoff_times,
    cutoff_time_in_index=True,
)

print(fm)
                        MEAN(Sales.Label)  STD(Sales.Label)  Label
Distributor time
A           2019-01-03                NaN               NaN      0
            2019-01-05           0.000000               NaN      1
B           2018-12-20                NaN               NaN      1
            2019-01-01           1.000000               NaN      0
            2019-01-03           0.500000          0.707107      0
            2019-01-04           0.333333          0.577350      0

Дайте мне знать, если это поможет. Вы также можете найти дополнительную информацию об использовании времени отключения в по этой ссылке .

...