Векторизованная реализация экспоненциально взвешенного скользящего стандартного отклонения с использованием R? - PullRequest
0 голосов
/ 08 февраля 2019

Я пытаюсь реализовать векторизованное экспоненциально взвешенное стандартное отклонение с использованием R. Это правильный подход?

ewma <- function (x, alpha) {
  c(stats::filter(x * ratio, 1 - ratio, "recursive", init = x[1]))
}
ewmsd <- function(x, alpha) {
  sqerror <- na.omit((x - lag(ewma(x, ratio)))^2)
  ewmvar <- c(stats::filter(sqerror * ratio, 1 - ratio, "recursive", init = 0))
  c(NA, sqrt(ewmvar))
}

Я предполагаю, что это не так, поскольку его вывод отличается от pandas.Series.ewm.std() Pythonфункция.

Когда я запускаю

ewmsd(x = 0:9, alpha = 0.96)

, вывод равен

 [1]        NA 0.2236068 0.4874679 0.7953500 1.1353903 1.4993855 1.8812961 2.2764708 2.6812160 3.0925367

Однако при

pd.Series(range(10)).ewm(alpha = 0.96).std()

вывод равен

0         NaN
1    0.707107
2    0.746729
3    0.750825
4    0.751135
5    0.751155
6    0.751156
7    0.751157
8    0.751157
9    0.751157

1 Ответ

0 голосов
/ 18 февраля 2019

Согласно документации для Pandas , функция pandas.Series.ewm() получает параметр adjust, который по умолчанию равен TRUE.Когда adjust == TRUE, экспоненциально взвешенное скользящее среднее от pandas.Series.ewm.mean() вычисляется через веса, а не рекурсивно.Естественно, это влияет и на стандартное отклонение.См. этот выпуск Github и этот вопрос для получения дополнительной информации.

Вот векторизованное решение в R:

   ewmsd <- function(x, alpha) {
      n <- length(x)
      sapply(
        1:n,
        function(i, x, alpha) {
          y <- x[1:i]
          m <- length(y)
          weights <- (1 - alpha)^((m - 1):0)
          ewma <- sum(weights * y) / sum(weights)
          bias <- sum(weights)^2 / (sum(weights)^2 - sum(weights^2))
          ewmsd <- sqrt(bias * sum(weights * (y - ewma)^2) / sum(weights))
        },
        x = x,
        alpha = alpha
      )
    }
...