Этот пост является продолжением другого поста, относящегося к универсальному методу обнаружения выбросов во временных рядах . По сути, на данный момент меня интересует надежный способ обнаружить периодичность / сезонность общего временного ряда, на который влияет много шума. С точки зрения разработчика, я хотел бы простой интерфейс, такой как:
unsigned int discover_period(vector<double> v);
Где v
находится массив, содержащий выборки, а возвращаемое значение - период сигнала. Главное, опять же, я не могу делать никаких предположений относительно анализируемого сигнала. Я уже пробовал подход, основанный на автокорреляции сигнала (обнаружение пиков коррелограммы), но он не надежен, как хотелось бы.
time-series
algorithms
frequency
real-time
Джанлука
источник
источник
Ответы:
Если вы действительно не представляете, что такое периодичность, возможно, лучший способ - найти частоту, соответствующую максимуму спектральной плотности. Однако, спектр на низких частотах будет зависеть от тренда, поэтому вам нужно сначала развернуть серию. Следующая функция R должна выполнять работу для большинства серий. Это далеко от совершенства, но я проверил это на нескольких десятках примеров, и, кажется, работает нормально. Он вернет 1 для данных, которые не имеют строгой периодичности, и длину периода в противном случае.
Обновление: версия 2 функции. Это намного быстрее и кажется более надежным.
источник
findfrequency
Если вы ожидаете, что процесс будет стационарным - периодичность / сезонность не изменится со временем - тогда что-то вроде периодограммы хи-квадрат (см., Например, Sokolove and Bushell, 1978) может быть хорошим выбором. Он обычно используется при анализе циркадных данных, которые могут содержать очень большое количество шума, но, как ожидается, будут иметь очень стабильные периодичности.
Этот подход не предполагает предположения о форме волны (кроме того, что она согласована от цикла к циклу), но требует, чтобы любой шум имел постоянное среднее значение и не коррелировал с сигналом.
Последние две строки - только пример, показывающий, что он может идентифицировать период чисто тригонометрической функции, даже с большим количеством аддитивного шума.
Как написано, последний аргумент (
alpha
) в вызове является излишним, функция просто возвращает «лучший» период, который она может найти; раскомментируйте первоеreturn
утверждение и закомментируйте второе, чтобы оно вернуло список всех значимых периодов на уровнеalpha
.Эта функция не выполняет какой-либо проверки работоспособности, чтобы убедиться, что вы указали идентифицируемые периоды, и не работает (не может) с дробными периодами, а также не существует встроенного элемента управления множественным сравнением, если вы решите смотреть на несколько периодов. Но кроме этого он должен быть достаточно надежным.
источник
Вы можете определить, что вы хотите более четко (для себя, если не здесь). Если то, что вы ищете, является наиболее статистически значимым стационарным периодом, содержащимся в ваших зашумленных данных, по сути, есть два пути:
1) вычислить надежную оценку автокорреляции и взять максимальный коэффициент
2) вычислить надежную оценку спектральной плотности мощности и взять максимум спектра
Проблема с № 2 заключается в том, что для любого шумного временного ряда вы получаете большое количество энергии на низких частотах, что затрудняет его различение. Существуют некоторые методы для решения этой проблемы (например, предварительное отбеливание, затем оценка PSD), но если истинный период из ваших данных достаточно длинный, автоматическое обнаружение будет ненадежным.
Лучше всего, вероятно, реализовать надежную процедуру автокорреляции, такую как можно найти в главе 8.6, 8.7 в Робастная статистика - теория и методы Маронны, Мартина и Йохая. Поиск в Google по запросу "надежный Дурбин-Левинсон" также даст некоторые результаты.
Если вы просто ищете простой ответ, я не уверен, что он существует. Обнаружение периода во временных рядах может быть сложным, и запрос автоматической процедуры, которая может выполнять магию, может быть слишком большим.
источник
Вы можете использовать преобразование Гильберта из теории DSP для измерения мгновенной частоты ваших данных. Сайт http://ta-lib.org/ имеет открытый исходный код для измерения доминирующего периода цикла финансовых данных; соответствующая функция называется HT_DCPERIOD; Вы могли бы использовать это или адаптировать код для своих целей.
источник
Другим подходом может быть эмпирическая модовая декомпозиция. Пакет R называется EMD, разработанным изобретателем способа:
Метод был назван «эмпирическим» по уважительной причине, и существует риск того, что функции внутреннего режима (отдельные аддитивные компоненты) будут перепутаны. С другой стороны, метод очень интуитивен и может быть полезен для быстрой визуальной проверки цикличности.
источник
Ссылка на пост Роба Хиндмана выше https://stats.stackexchange.com/a/1214/70282
Функция find.freq работает великолепно. На ежедневном наборе данных, который я использую, он правильно рассчитал частоту 7.
Когда я пробовал это только в дни недели, он упоминал, что частота равна 23, что удивительно близко к 21,42857 = 29,6 * 5/7, что является средним числом рабочих дней в месяце. (Или, наоборот, 23 * 7/5 - это 32.)
Оглядываясь назад на свои ежедневные данные, я экспериментировал с догадкой: взять первый период, усреднить по нему, а затем найти следующий период и т. Д. См. Ниже:
Выше приведены (7,28) или (7,35) в зависимости от того, начинается ли seq с 1 или f. (См. Комментарий выше.)
Что подразумевает, что сезонные периоды для msts (...) должны быть (7,28) или (7,35).
Логика кажется чувствительной к начальным условиям, учитывая чувствительность параметров алгоритма. Среднее значение 28 и 35 составляет 31,5, что близко к средней продолжительности месяца.
Я подозреваю, что я заново изобрел колесо, как называется этот алгоритм? Есть ли лучшая реализация в R где-нибудь?
Позже я запустил приведенный выше код, попробовав все запуски с 1 по 7, и получил 35,35,28,28,28,28,28 за второй период. В среднем получается до 30, что является средним числом дней в месяце. Интересно...
Есть мысли или комментарии?
источник
Можно также использовать тест Юнга-Бокса, чтобы выяснить, какая сезонная разница достигает наилучшей стационарности. Я работал над другим предметом, и я использовал это на самом деле для тех же целей. Попробуйте разные периоды, например от 3 до 24, для ежемесячных данных. И протестируйте каждый из них с помощью Ljung-Box и сохраните результаты Chi-Square. И выберите период с наименьшим значением хи-квадрат.
Вот простой код для этого.
источник