Есть ли способ имитировать данные временных рядов с определенным скользящим средним и автокорреляцией в R?

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

Чтобы смоделировать данные, я попробовал следующее:

  1. Добавление случайного шума к среднему значению.
 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) .

  1. Я попытался 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 Спасибо, это действительно хороший момент. Я соответствующим образом отредактирую вопрос.