Обнаружение изменений во временных рядах (пример R)

18

Я хотел бы обнаружить изменения в данных временных рядов, которые обычно имеют одинаковую форму. До сих пор я работал с changepointпакетом для R cpt.mean(), cpt.var()и cpt.meanvar()функций и. cpt.mean()с методом PELT хорошо работает, когда данные обычно остаются на одном уровне. Однако я также хотел бы обнаружить изменения во время спусков. Примером изменения, которое я хотел бы обнаружить, является участок, где черная кривая внезапно падает, в то время как она фактически должна следовать за красной пунктирной линией. Я экспериментировал с функцией cpt.var (), однако не смог получить хорошие результаты. Есть ли у вас какие-либо рекомендации (те, которые не обязательно должны использовать R)?

Изменить кривую

Вот данные с изменением (как объект R):

dat.change <- c(12.013995263488, 11.8460207231808, 11.2845153487846, 11.7884417180764, 
11.6865425802022, 11.4703118125303, 11.4677576899063, 11.0227199625084, 
11.274775836817, 11.03073498338, 10.7771805591742, 10.7383206158923, 
10.5847230134625, 10.2479315651441, 10.4196381241735, 10.467607842288, 
10.3682422713283, 9.7834431752935, 9.76649842404295, 9.78257968297228, 
9.87817694914062, 9.3449034905713, 9.56400153361727, 9.78120084558148, 
9.3445162813738, 9.36767436354887, 9.12070987223648, 9.21909859069157, 
8.85136359917466, 8.8814423003979, 8.61830163359642, 8.44796977628488, 
8.06957847272046, 8.37999165387824, 7.98213210294954, 8.21977468333673, 
7.683960439316, 7.73213584532496, 7.98956476021092, 7.83036046746187, 
7.64496198988985, 4.49693528397253, 6.3459274845112, 5.86993447552116, 
4.58301192892403, 5.63419551523625, 6.67847511602895, 7.2005344054883, 
5.54970477623895, 6.00011922569104, 6.882667104467, 4.74057284230894, 
6.2140437333397, 6.18511450451019, 5.83973575417525, 6.57271194428385, 
5.36261938326723, 5.48948831338016, 4.93968645996861, 4.52598133247377, 
4.56372558828803, 5.74515428123725, 5.45931581984165, 5.58701112949141, 
6.00585679276365, 5.41639695946931, 4.55361875158434, 6.23720558202826, 
6.19433060301002, 5.82989415940829, 5.69321394985076, 5.53585871082265, 
5.42684812413063, 5.80887522466946, 5.56660158483312, 5.7284521523444, 
5.25425775891636, 5.4227645808924, 5.34778016248718, 5.07084809927736, 
5.324066161355, 5.03526881241705, 5.17387528516352, 5.29864121433813, 
5.36894461582415, 5.07436929444317, 4.80619983525015, 4.42858947882894, 
4.33623051506001, 4.33481791951228, 4.38041031792294, 3.90012900415342, 
4.04262777674943, 4.34383842876647, 4.36984816425014, 4.11641092254315, 
3.83985887104645, 3.81813419810962, 3.85174630901311, 3.66434598962311, 
3.4281724860426, 2.99726515704766, 2.96694634792395, 2.94003031547181, 
3.20892607367132, 3.03980832743458, 2.85952185077593, 2.70595278908964, 
2.50931109659839, 2.1912274016859)
mlee
источник
Обратите внимание: если вы запрашиваете код R, это будет не по теме. Если вы просите общего методологического совета, это нормально. Это может прийти с некоторым R-кодом, но с другой стороны, это может и не произойти.
gung - Восстановить Монику
1
Хорошее замечание, я заинтересован в общем решении, использование R было бы просто удобно.
mlee

Ответы:

17

Вы можете использовать обнаружение выбросов временных рядов для обнаружения изменений во временных рядах. Tsay - х или Чен и Лю процедуры популярные методы обнаружения останец временных рядов. Смотрите мой предыдущий вопрос на этом сайте.

Пакет tsoutlier от R использует метод обнаружения Чена и Лю для обнаружения выбросов. SAS / SPSS / Autobox также может сделать это. Ниже приведен код R для обнаружения изменений во временных рядах.

library("tsoutliers")
dat.ts<- ts(dat.change,frequency=1)
data.ts.outliers <- tso(dat.ts)
data.ts.outliers
plot(data.ts.outliers)

Функция tso в пакете tsoultlier определяет следующие выбросы. Вы можете прочитать документацию, чтобы узнать тип выбросов.

Outliers:
  type ind time coefhat   tstat
1   TC  42   42 -2.9462 -10.068
2   AO  43   43  1.0733   4.322
3   AO  45   45 -1.2113  -4.849
4   TC  47   47  1.0143   3.387
5   AO  51   51  0.9002   3.433
6   AO  52   52 -1.3455  -5.165
7   AO  56   56  0.9074   3.710
8   LS  62   62  1.1284   3.717
9   AO  67   67 -1.3503  -5.502

Пакет также предоставляет хорошие участки. см. ниже. График показывает, где находятся выбросы, а также что бы произошло, если бы не было выбросов.

введите описание изображения здесь

Я также использовал пакет R, называемый strucchange, для обнаружения сдвигов уровня. Как пример на ваших данных

library("strucchange")
breakpoints(dat.ts~1)

Программа правильно определяет точки останова или структурные изменения.

Optimal 4-segment partition: 

Call:
breakpoints.formula(formula = dat.ts ~ 1)

Breakpoints at observation number:
17 41 87 

Corresponding to breakdates:
17 41 87 

Надеюсь это поможет

предсказатель
источник
1
Спасибо, tsoработает хорошо, но это немного медленно для больших наборов данных. Позиции точки прерывания Struccchange кажутся немного произвольными (кроме позиции 41).
mlee
7

Я бы подошел к этой проблеме со следующих точек зрения . Это всего лишь некоторые идеи с моей головы - пожалуйста, возьмите их с крошкой соли. Тем не менее, я надеюсь, что это будет полезно.

  • Кластеризация временных рядов . Например, с помощью популярных динамических деформаций времени (DTW) или альтернативных подходов. Пожалуйста, смотрите мои связанные ответы: по DTW для классификации / кластеризации и по DTW или альтернативам для неравномерных временных рядов . Идея заключается в временных рядов кластеров в категории «нормальных» и «ненормальных» (или аналогичный).

  • Меры энтропии . Смотрите мой соответствующий ответ о мерах энтропии временного ряда . Идея заключается в определении энтропии «нормальных» временных ряды , а затем сравнить его с другими временными рядами (эта идея имеет предположение о энтропии отклонения в случае отклонения от «нормальности»).

  • Обнаружение аномалий . Смотрите мой соответствующий ответ по обнаружению аномалий (включает R ресурсов). Идея заключается в непосредственно обнаруживать аномалии через различные методы (см ссылки). Ранние предупреждающие сигналы (EWS) Набор инструментов и Rпакет earlywarningsкажутся особенно многообещающими.

Александр Блех
источник
6

Мой ответ с использованием AUTOBOX очень похож на @forecaster, но с гораздо более простой моделью. Бокс, Эйнштейн и другие думают о том, как сохранить решения простыми, но не слишком простыми. Модель, которая была разработана автоматически, была введите описание изображения здесь. Фактический и очищенный участок очень похож введите описание изображения здесь. График остатков (который всегда должен быть показан) находится здесь введите описание изображения здесьвместе с обязательным действием остатков введите описание изображения здесь. Статистика невязок всегда полезна для сравнения «дуэльных моделей» введите описание изображения здесь. График Actual / Fit / Forecast находится здесьвведите описание изображения здесь

IrishStat
источник
1

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

MrMeritology
источник
3
Этот подход потерпит неудачу, потому что в истории есть совершенно разные склоны. Если вы не включите несколько «трендов / уклонов», этот подход не даст значимых результатов. Простые прямые решения часто просто слишком просты.
IrishStat
1

Все хорошие ответы, но вот простой, как предлагает @MrMeritology, который, кажется, хорошо работает для рассматриваемого временного ряда и, вероятно, для многих других «похожих» наборов данных.

Вот R-фрагмент, создающий понятные графики ниже.

outl = rep( NA, length(dat.change))
detr = c( 0, diff( dat.change))

ix = abs(detr) > 2*IQR( detr)
outl[ix] = dat.change[ix]

plot( dat.change, t='l', lwd=2, main="dat.change TS")
points( outl, col=2, pch=18)

plot( detr, col=4, main="detrended TS", t='l', lwd=2 )
acf( detr, main="ACF of detrended TS")

введите описание изображения здесь введите описание изображения здесь введите описание изображения здесь

dnqxt
источник
может быть многократные изменения тренда и множественные изменения перехвата (сдвиги уровней) ... таким образом, нужно найти решения, которые фактически диагностируют данные, чтобы определить их ...
IrishStat
Да, действительно, я прочитал ваш предыдущий комментарий выше. Однако диагностика временных рядов для обнаружения нескольких трендов / уровней сама по себе является проблемой. Я хочу показать, что вышеупомянутый простой подход иногда работает, в частности, для данных. И наоборот, ни один подход не будет работать хорошо всегда. Подход R.Hyndman (R-функции tsoutliers) - это то, что я иначе рекомендовал бы.
dnqxt
AUTOBOX - это единственный подход, который всегда будет хорошо работать (по крайней мере, для тех миллионов временных рядов, которые мы видели), и существует версия R. Если вы хотите общаться в автономном режиме, так как я не хочу переходить к «продажам» здесь, я могу объяснить процесс, который полностью понятен / прозрачен, но не легко дублируется.
IrishStat