Разработка возможностей набора данных временных рядов в 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,

Другие вопросы по тегам