Я бы не стал беспокоиться stl()
об этом - пропускная способность низкочастотного сглаживателя, используемого для извлечения тренда, очень мала, что приводит к небольшим колебаниям, которые вы видите. Я бы использовал аддитивную модель. Вот пример использования данных и кода модели из книги Саймона Вуда о GAM:
require(mgcv)
require(gamair)
data(cairo)
cairo2 <- within(cairo, Date <- as.Date(paste(year, month, day.of.month,
sep = "-")))
plot(temp ~ Date, data = cairo2, type = "l")
Установите модель с трендовыми и сезонными компонентами - предупреждая, что это медленно:
mod <- gamm(temp ~ s(day.of.year, bs = "cc") + s(time, bs = "cr"),
data = cairo2, method = "REML",
correlation = corAR1(form = ~ 1 | year),
knots = list(day.of.year = c(0, 366)))
Подогнанная модель выглядит так:
> summary(mod$gam)
Family: gaussian
Link function: identity
Formula:
temp ~ s(day.of.year, bs = "cc") + s(time, bs = "cr")
Parametric coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 71.6603 0.1523 470.7 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Approximate significance of smooth terms:
edf Ref.df F p-value
s(day.of.year) 7.092 7.092 555.407 < 2e-16 ***
s(time) 1.383 1.383 7.035 0.00345 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
R-sq.(adj) = 0.848 Scale est. = 16.572 n = 3780
и мы можем визуализировать тенденцию и сезонные условия с помощью
plot(mod$gam, pages = 1)
и если мы хотим построить тренд на наблюдаемых данных, мы можем сделать это с помощью прогноза:
pred <- predict(mod$gam, newdata = cairo2, type = "terms")
ptemp <- attr(pred, "constant") + pred[,2]
plot(temp ~ Date, data = cairo2, type = "l",
xlab = "year",
ylab = expression(Temperature ~ (degree*F)))
lines(ptemp ~ Date, data = cairo2, col = "red", lwd = 2)
Или то же самое для фактической модели:
pred2 <- predict(mod$gam, newdata = cairo2)
plot(temp ~ Date, data = cairo2, type = "l",
xlab = "year",
ylab = expression(Temperature ~ (degree*F)))
lines(pred2 ~ Date, data = cairo2, col = "red", lwd = 2)
Это всего лишь пример, и более глубокому анализу, возможно, придется иметь дело с тем фактом, что существует несколько пропущенных данных, но вышеизложенное должно стать хорошей отправной точкой.
Что касается вашей точки зрения о том, как количественно оценить тренд - это проблема, потому что тренд не является линейным, ни в вашей stl()
версии, ни в версии GAM, которую я показываю. Если бы это было так, вы могли бы указать скорость изменения (уклон). Если вы хотите узнать, насколько изменился предполагаемый тренд за период выборки, мы можем использовать данные, содержащиеся в нем, pred
и вычислить разницу между началом и концом ряда только в компоненте тренда :
> tail(pred[,2], 1) - head(pred[,2], 1)
3794
1.756163
таким образом, температура в среднем на 1,76 градуса выше, чем в начале записи.
gls()
в пакете NLME). Но, как показано выше для Каира, и STL предлагает для ваших данных, тенденция не является линейной. Таким образом, линейный тренд не подходит, поскольку он не описывает данные должным образом. Вы должны попробовать это на своих данных, но AM, как я показываю, будет ухудшаться до линейного тренда, если он лучше всего соответствует данным.Гэвин дал очень подробный ответ, но для более простого и быстрого решения я рекомендую установить для параметра stl function t.window значение, кратное частоте данных ts . Я бы использовал предполагаемую периодичность интереса (например, значение 3660 для десятилетних трендов с данными суточного разрешения). Вас также может заинтересовать пакет stl2 , описанный в диссертации автора . Я применил метод Гэвина к своим собственным данным, и он тоже очень эффективен.
источник