Выравнивание или устранение тренда сезонного временного ряда

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

Чтобы быть точным, 1-е значение по-прежнему будет 39,8, но 8-е значение также будет 39,8, а не 17,1. Если бы первые семь значений были просто повторены, то повторился бы недельный отрицательный тренд, и я бы хотел, чтобы вообще не было тренда (поэтому 7-е значение 6,2 также было бы выше).

Есть ли элегантный способ сделать это, особенно тот, который устойчив к нулевым записям во временных рядах (у меня их много)?

Мы можем предположить, что тренд временного ряда является линейным и постоянным (то есть не просто кусочно-линейным).

demand <- ts(
  c(39.8, 33.5, 40.6, 23.6, 11.9, 12.3, 6.2, 17.1, 10.8, 18, 1, -10.7, 
-10.4, -16.5, -5.6, -11.9, -4.7, -21.7, -33.4, -33.1, -39.2, -28.2, 
-34.6, -27.4, -44.4, -56.1, -55.7, -61.8, -50.9, -57.2, -50.1),
frequency = 7
)

plot(demand)

тренд спроса


person Eric    schedule 01.10.2017    source источник


Ответы (2)


Вы можете сделать что-то вроде этого:

trend = stl(demand, s.window = "periodic")$time.series[,2]

detrend_ts = demand - (trend - trend[1])

plot(detrend_ts)

Результат:

> detrend_ts
Time Series:
Start = c(1, 1) 
End = c(5, 3) 
Frequency = 7 
 [1] 39.80000 36.72792 47.05584 33.28224 24.80864 28.43514 25.56165 39.69889 36.63614
[10] 47.08241 33.32868 24.86478 28.40088 25.53956 39.67825 36.63383 47.08942 33.32204
[19] 24.85466 28.38747 25.52029 39.76777 36.61526 47.05556 33.29586 24.82129 28.44673
[28] 25.57045 39.69417 36.61948 46.94480

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

Примечания:

По сути, я использовал декомпозицию STL (сезонная декомпозиция временных рядов по Лессу) для оценки тренда, а затем вычел ее из demand. Поскольку вы хотели, чтобы временной ряд без тренда начинался с 39.8, я также вычел первое значение trend из trend.

person acylam    schedule 01.10.2017

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

linear_fit <- lm(demand ~ time(demand))
plot(demand - linear_fit$fitted.values + linear_fit$fitted.values[1],
    ylab = "detrended demand", typ = 'o')

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

Функция decompose также полезна для получения тренда. Поскольку применяется центрированная скользящая средняя, ​​тренд будет иметь 3 NA в начале ряда и 3 в конце.

demand_decomposed <- decompose(demand)
plot(demand - demand_decomposed$trend, ylab = 'detrended demand', typ = 'o')

Обратите внимание, что тренд можно вычислить напрямую, используя функцию filter, чтобы получить скользящее среднее значение, используемое функцией decompose.

trend_ma <- filter(demand, rep(1/7, 7), method = "convolution", sides = 2) 
plot(demand - trend_ma, typ = 'o', ylab = "detrended demand")

Последние два графика не были скорректированы по значению тренда в момент времени 1, так как его не существует. Можно заменить NA на значение, которое оно должно иметь в соответствии с сезонной закономерностью:

seasonal <- demand - trend_ma
na_values_time_in_period <- cycle(demand)[is.na(seasonal)]
value_time_in_period <- tapply(seasonal, cycle(demand), mean, na.rm = TRUE)
seasonal[is.na(seasonal)] <- value_time_in_period[na_values_time_in_period]
person josep maria porrà    schedule 10.07.2018