Разработка возможностей набора данных временных рядов в Python
У меня есть набор данных с n
наблюдения, где все наблюдения имеют m
временные шаги. у меня тоже есть n*m
массив, который содержит метку для каждого временного шага в каждом данном наблюдении.
Я занимаюсь проектированием элементов этого набора данных, чтобы найти значимые элементы в данных в соответствии с имеющимися у меня ярлыками. Есть ли какой-нибудь пакет Python для облегчения этого процесса?
Я наткнулся tsfresh
( https://github.com/blue-yonder/tsfresh), хотя кажется, что он предназначен только для использования, когда у нас есть одна метка для классификации каждого наблюдения, а не метка для классификации каждого временного шага, как в моем случае,
2 ответа
Вы можете попробовать Featuretools. Это автоматизированная библиотека разработки функций с открытым исходным кодом, которая явно работает со временем, чтобы убедиться, что вы не вносите утечку метки.
Для ваших данных вы можете создать две сущности: "observations"
а также "timesteps"
, а затем применить featuretools.dfs
( Deep Feature Synthesis) для создания функций для каждого временного шага. Вы можете думать о сущности так же, как о таблице в реляционной базе данных.
Особой полезностью для вашей проблемы могут быть кумулятивные примитивы в Featuretools, которые представляют собой операции, использующие множество экземпляров, упорядоченных по времени, для вычисления одного значения. В вашем случае, если было наблюдение с несколькими временными шагами, каждый с определенным значением, вы можете вычислить среднее значение предыдущих временных шагов, используя примитив CumMean.
Вот пример:
from featuretools.primitives import Day, Weekend, Percentile, CumMean, CumSum
import featuretools as ft
import pandas as pd
import numpy as np
timesteps = pd.DataFrame({'ts_id': range(12),
'timestamp': pd.DatetimeIndex(start='1/1/2018', freq='1d', periods=12),
'attr1': np.random.random(12),
'obs_id': [1, 2, 3] * 4})
print(timesteps)
attr1 obs_id timestamp ts_id
0 0.663216 1 2018-01-01 0
1 0.455353 2 2018-01-02 1
2 0.800848 3 2018-01-03 2
3 0.938645 1 2018-01-04 3
4 0.442037 2 2018-01-05 4
5 0.724044 3 2018-01-06 5
6 0.304241 1 2018-01-07 6
7 0.134359 2 2018-01-08 7
8 0.275078 3 2018-01-09 8
9 0.499343 1 2018-01-10 9
10 0.608565 2 2018-01-11 10
11 0.340991 3 2018-01-12 11
entityset = ft.EntitySet("timeseries")
entityset.entity_from_dataframe("timesteps",
timesteps,
index='ts_id',
time_index='timestamp')
entityset.normalize_entity(base_entity_id='timesteps',
new_entity_id='observations',
index='obs_id',
make_time_index=True)
# per timestep
cutoffs = timesteps[['ts_id', 'timestamp']]
feature_matrix, feature_list = ft.dfs(entityset=entityset,
target_entity='timesteps',
cutoff_time=cutoffs,
trans_primitives=[Day, Weekend, Percentile, CumMean, CumSum],
agg_primitives=[])
print(feature_matrix.iloc[:, -6:])
CUMMEAN(attr1 by obs_id) CUMSUM(attr1 by obs_id) CUMMEAN(PERCENTILE(attr1) by obs_id) CUMSUM(CUMMEAN(attr1 by obs_id) by obs_id) CUMSUM(PERCENTILE(attr1) by obs_id) observations.DAY(first_timesteps_time)
ts_id
0 0.100711 0.100711 1.000000 0.100711 1.000000 1
1 0.811898 0.811898 1.000000 0.811898 1.000000 2
2 0.989166 0.989166 1.000000 0.989166 1.000000 3
3 0.442035 0.442035 0.500000 0.442035 0.500000 1
4 0.910106 0.910106 0.800000 0.910106 0.800000 2
5 0.427610 0.427610 0.333333 0.427610 0.333333 3
6 0.832516 0.832516 0.714286 0.832516 0.714286 1
7 0.035121 0.035121 0.125000 0.035121 0.125000 2
8 0.178202 0.178202 0.333333 0.178202 0.333333 3
9 0.085608 0.085608 0.200000 0.085608 0.200000 1
10 0.891033 0.891033 0.818182 0.891033 0.818182 2
11 0.044010 0.044010 0.166667 0.044010 0.166667 3
В этом примере также использовались "времена выключения", чтобы сообщить механизму вычисления признаков использовать только данные до указанного времени для каждого "ts_id" или "obs_id". Вы можете прочитать больше о сроках на этой странице в документации.
Еще одна интересная вещь, которую позволяет Featuretools, - это создание объектов по наблюдению в таблице "наблюдений", а не по временному шагу. Для этого измените параметр "target_entity". В следующем примере мы используем взять последнюю метку времени на наблюдение, чтобы использовать ее в качестве времени отсечения, что гарантирует, что после этого времени не будет использоваться никаких данных (например, данные из obs_id = 2 в 2018-01-11 не будут включены в вычисление Percentile() для obs_id = 1 со временем отключения 2018-01-10).
# per observation
ocutoffs = timesteps[['obs_id', 'timestamp']].drop_duplicates(['obs_id'], keep='last')
ofeature_matrix, ofeature_list = ft.dfs(entityset=entityset,
target_entity='observations',
cutoff_time=ocutoffs,
trans_primitives=[Day, Weekend, Percentile, CumMean, CumSum])
print(ofeature_matrix.iloc[:, -6:])
PERCENTILE(STD(timesteps.attr1)) PERCENTILE(MAX(timesteps.attr1)) PERCENTILE(SKEW(timesteps.attr1)) PERCENTILE(MIN(timesteps.attr1)) PERCENTILE(MEAN(timesteps.attr1)) PERCENTILE(COUNT(timesteps))
obs_id
1 0.666667 1.000000 0.666667 0.666667 0.666667 1.000000
2 0.333333 0.666667 0.666667 0.666667 0.333333 0.833333
3 1.000000 1.000000 0.333333 0.333333 1.000000 0.666667
Наконец, на самом деле можно использовать tsfresh вместе с Featuretools как "пользовательский примитив". Это расширенная функция, но я мог бы объяснить больше, если вам интересно.
Я мог бы ответить более подробно, если вы дадите мне больше деталей по этому вопросу. Однако, исходя из моего понимания, вы хотите что-то предсказать с данными временного ряда, которые у вас есть.
Есть пакет под названием keras
в Python для машинного обучения. Что вы можете сделать, так это то, что вы можете использовать LSTM для обучения вашей модели. Поддержка LSTM очень хороша в keras
,