Closed v1docq closed 11 months ago
она подсчитывает число "пиков" (значения коээфициентов которые значимо отличаются от других), в зависимости от ряда гиперпараметров (расстояние между пиками, продолжительность пика, проч)
однако в scipy уже реализовано подобное. from scipy.signal import find_peaks_cwt
параметры плюс минус все теже, разве что можно прокинуть свой тип вейвлета.
Выглядит как кандидат на рефакторинг.
вот здесь fedot_ind/core/operation/transformation/WindowSelection.py лежит класс в котором реализованы 4 метода для определения окна временного ряда. Окно дает представления о возможносй сезонности, о лучшем вложении для траекторной матрицы (что дает лучшую разделимость ряда и лучший базис). метод для получения лучшего окна def get_window_size(). В самом коде много косяков:
Что надо сделать.
сам класс TopologicalTransformation никак не используется fedot_ind/core/models/topological/TopologicalExtractor.py
Отсутствует docstring к методам генерации признаков
https://giotto-ai.github.io/gtda-docs/0.5.1/library.html можно взять описание отсюда.
По задаче 4.1 (переработка топологического генератора признаков)
По алгоритмам подбора окна:
Переписан код класса WindowSizeSelector:
scipy
и statsmodels
(примерно 0.005 сек на временной ряд)По поводу эффективности работы алгоритмов: Если кратко, то в случае наличия выраженной циклической компоненты она непременно будет найдена, причём не важно, каким методом. Ниже на картинке приведён пример работы этих методов для временного ряда, полученного склеиванием нескольких сэмплов из датасета Beef. Как видно, оба алгоритма показали идентичную длину окна, соответствующую длине одного сэмпла (они показаны разными цветами)
Однако, зачастую в задачах классификации циклика – понятие весьма условное. Например, в случае EC200, где каждый ряд - это фактически единичный удар сердца. В таком случае для целого набора ВР будет получено несколько вариантов окон, где была хоть какая-то корреляция. Тут встаёт вопрос в усреднении между предлагаемыми вариантами.
На картинках ниже линии соответствуют классам в наборе данных (выбраны рандомно):
np.mean
:
или np.median
:
Кроме того, стоит отметить одну важную вещь, связанную с тем, как работает AC метод
. Вот его код:
def autocorrelation(self, time_series):
acf_values = acf(time_series, fft=True, nlags=int(time_series.shape[0] / 2))
peaks, _ = find_peaks(acf_values)
peaks = peaks[np.logical_and(peaks >= self.window_min, peaks < self.window_max)]
corrs = acf_values[peaks]
if peaks.shape[0] == 0: # if there is no peaks in range (window_min, window_max) return window_min
return self.window_range[0]
return peaks[np.argmax(corrs)]
То есть среди коэффициентов автокорреляции ищутся пики, Х-координата которых соответствует длина окна. И эта кривая может выглядеть вот так:
Удачный случай, есть пики и, значит, есть окна:
Неудачный случай:
Поэтому более надёжным мне кажется метод DFT. Однако, важно ещё раз отметить, что эти методики призваны искать циклики в рядах. Поэтому, если в ряду не предполагается по логике какой-то циклический процесс, то полученное значение, например, 45 будет лишь говорить о том, что при такой величине окна наибольшая корреляция временного ряда с самим собой или какой-то синусоидой, но это может быть корреляция = 0.01
Требуется либо избавиться от "ненужных модулей" либо объединить их между собой.