Виявлення змін у часових рядах (приклад 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)

Зауважте, що якщо ви запитуєте лише код R, це не буде темою тут. Якщо ви запитуєте загальну методичну пораду, це добре. Він може прийти з деяким R-кодом, але знову ж таки, він не може.
gung - Відновіть Моніку

1
Добре зауваження, мене цікавить загальне рішення, використання R було б просто зручно.
mlee

Відповіді:


17

Ви можете використовувати виявлення зовнішніх часових рядів для виявлення змін у часових рядах. Процедури Цей або Чена і Лю є популярними методами виявлення зовнішніх часових рядів. Дивіться моє попереднє запитання на цьому сайті.

У пакеті Rs tsoutlier використовується метод Чена та Лю для виявлення людей , що втратили вірогідність . 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працює добре, проте для великих наборів даних це трохи повільно. Положення точки розриву струму зміни здаються трохи довільними (крім позиції 41).
mlee

7

Я б підійшов до цієї проблеми з наступних позицій . Це лише кілька ідей у ​​верхній частині моєї голови - будь ласка, прийміть їх із зерном солі. Тим не менш, я сподіваюся, що це буде корисно.

  • Кластеризація часових рядів . Наприклад, використовуючи популярні динамічні деформації часу (DTW) або альтернативні підходи. Будь ласка, дивіться мої відповідні відповіді: на DTW для класифікації / кластеризації та на DTW або альтернативи для нерівномірних часових рядів . Ідея полягає в часових рядів кластерів в категорії «нормальних» і «ненормальних» (або аналогічний).

  • Ентропійні заходи . Дивіться мою відповідну відповідь щодо заходів ентропії часових рядів . Ідея полягає у визначенні ентропії «нормальних» тимчасових ряди , а потім порівняти його з іншими тимчасовими рядами (ця ідея має припущення про ентропії відхилення в разі відхилення від «нормальності»).

  • Виявлення аномалії . Дивіться мою відповідну відповідь щодо виявлення аномалії (включає ресурси R). Ідея полягає в безпосередньо виявляти аномалії через різні методи (див посилання). Набір інструментів та Rпакет ранніх попереджувальних сигналів (EWS)earlywarnings здаються особливо перспективними.


6

Моя відповідь за допомогою AUTOBOX досить схожа на @forecaster, але зі значно простішою моделлю. Box і Ейнштейн та інші роздумували над тим, щоб зберегти рішення простими, але не надто простими. Автоматично розроблена модель була введіть тут опис зображення. Фактичний і очищений сюжет дуже схожий введіть тут опис зображення. Сюжет залишків (який завжди повинен бути показаний) тут, введіть тут опис зображенняпоряд із обов'язковим доступом до залишків введіть тут опис зображення. Статистика залишків завжди корисна для порівняння "моделей дуелей" введіть тут опис зображення. Графік фактичного / відповідного / прогнозу тутвведіть тут опис зображення


1

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


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")

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


можуть бути кілька змін у тренді та кілька змін перехоплення (зміни рівня) ... таким чином, потрібно знайти рішення, які фактично діагностують дані, щоб визначити ці ...
IrishStat

Так, дійсно, я прочитав ваш попередній коментар вище. Однак діагностика часових рядів для виявлення декількох тенденцій / рівнів є проблемою сама по собі. Моя суть тут полягає в тому, щоб показати, що вищезазначений простий підхід працює іноді, зокрема для даних. І навпаки, жоден єдиний підхід не буде працювати завжди завжди. Я б інакше порекомендував підхід Р.Хіндмана (R-function tsoutliers).
dnqxt

AUTOBOX - це єдиний підхід, який буде працювати завжди добре (принаймні, за мільйони часових рядів, які ми бачили), і є версія R. Якщо ви хочете спілкуватися в автономному режимі, оскільки я не хочу потрапляти на "розпродаж" тут, я можу пояснити процес, який є повністю зрозумілим / прозорим, але не легко дублюється.
IrishStat
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.