#r #time-series #simulation #arima #autocorrelation
#r #временные ряды #Симуляция #arima #автокорреляция
Вопрос:
У меня есть существующий временной ряд (1000 выборок), и я рассчитал скользящее среднее значение, используя filter()
функцию в R, усредняя по 30 выборкам каждая. Целью этого было создать «сглаженную» версию временных рядов. Теперь я хотел бы создать искусственные данные, которые «выглядят» как исходные временные ряды, т. Е. Являются Несколько зашумленными, что привело бы к тому же скользящему среднему значению, если бы я применил ту же filter()
функцию к искусственным данным. Короче говоря, я хотел бы смоделировать временной ряд с тем же общим курсом, но не с теми же значениями, что и у существующего временного ряда. Общая цель состоит в том, чтобы выяснить, могут ли определенные методы обнаруживать сходство тенденций между временными рядами, даже если колебания вокруг тренда не совпадают.
Чтобы предоставить некоторые данные, мои временные ряды выглядят примерно так:
set.seed(576)
ts <- arima.sim(model = list(order = c(1,0,0), ar = .9), n = 1000) 900
# save in dataframe
df <- data.frame("ts" = ts)
# plot the data
plot(ts, type = "l")
Функция фильтра выдает скользящее среднее:
my_filter <- function(x, n = 30){filter(x, rep(1 / n, n), sides = 2, circular = T)}
df$rolling_mean <- my_filter(df$ts)
lines(df$rolling_mean, col = "red")
Чтобы смоделировать данные, я попробовал следующее:
- Добавление случайного шума к среднему значению.
df$sim1 <- df$rolling_mean rnorm(1000, sd = sd(df$ts))
lines(df$sim1, col = "blue")
df$sim1_rm <- my_filter(df$sim1)
lines(df$sim1_rm, col = "green")
Проблема в том, что а) дисперсия смоделированных значений выше, чем дисперсия исходных значений, б) скользящее среднее, хотя и очень похоже на исходное, иногда сильно отклоняется от оригинала, и в) автокорреляции нет. Было бы неплохо иметь автокорреляционную структуру в данных, поскольку предполагается, что она должна напоминать исходные данные.
Редактировать: проблема а) может быть решена с помощью sd = sqrt(var(df$ts)-var(df$rolling_mean))
вместо sd = sd(df$ts)
.
- Я попытался
arima.sim()
, что кажется очевидным выбором, указать автокорреляцию, которая должна присутствовать в данных. Я смоделировал исходные данныеarima()
, используя параметры модели в качестве входных данных дляarima.sim()
.
ts_arima <- arima(ts, order = c(1,0,1))
my_ar <- ts_arima$coef["ar1"]
my_ma <- ts_arima$coef["ma1"]
my_intercept <- ts_arima$coef["intercept"]
df$sim2 <- arima.sim(model = list(order = c(1,0,1), ar = my_ar, ma = my_ma), n = 1000) my_intercept
plot(df$ts)
lines(df$sim2, col = "blue")
Результирующий временной ряд сильно отличается от исходного. Возможно, более высокий порядок для ar
и ma
в arima.sim()
решит эту проблему, но я думаю, что более подходящим может быть совершенно другой метод.
Комментарии:
1. Что касается проблемы 1a) (дисперсия выше при моделировании, чем в оригинале). Я думаю, это потому, что у вас также есть разница в скользящем среднем. Вы можете представить общую дисперсию как сумму дисперсии «сглаженных» данных и шума вокруг нее. Итак, когда вы используете SD из общих данных для создания шума вокруг скользящего среднего, вы получаете дисперсию, которая включает дисперсию сглаженных данных в два раза. Может быть, это поможет:
df$sim1 <- df$rolling_mean rnorm(1000, sd = sqrt(var(df$ts)-var(df$rolling_mean)))
2. @benimwolfspelz Спасибо, это действительно хороший момент. Я соответствующим образом отредактирую вопрос.