Как генерировать случайные автокоррелированные двоичные данные временных рядов?


15

Как я могу генерировать двоичные временные ряды, такие что:

  1. Указана средняя вероятность наблюдения 1 (скажем, 5%);
  2. Условная вероятность наблюдения 1 в момент времени учетом значения в момент времени (скажем, 30%, если значение равно 1)?т - 1 т - 1TT-1T-1

Ответы:


17

Используйте цепочку Маркова с двумя состояниями.

Если состояния называются 0 и 1, то цепь может быть представлена ​​матрицей 2x2, дающей вероятности перехода между состояниями, где P i j - вероятность перехода из состояния i в состояние j . В этой матрице каждая строка должна быть равна 1,0.ппяJяJ

Из утверждения 2 мы имеем , и тогда простое сохранение говорит P 10 = 0,7 .п11знак равно0,3п10знак равно0.7

Из утверждения 1 вы хотите, чтобы долгосрочная вероятность (также называемая равновесным или стационарным) была . Это говорит о P 1 = 0,05 = 0,3 P 1 + P 01 ( 1 - P 1 ). Решение дает P 01 = 0,0368421 и матрицу перехода P = ( 0,963158 0,0368421 0,7 0,3 ).п1знак равно0,05

п1знак равно0,05знак равно0,3п1+п01(1-п1)
п01знак равно0.0368421
пзнак равно(0.9631580.03684210.70,3)

(Вы можете проверить правильность своей матрицы переходов, подняв ее до высокой мощности - в этом случае 14 делает свою работу - каждая строка результата дает идентичные вероятности устойчивого состояния)

Теперь в вашей программе случайных чисел начните со случайного выбора состояния 0 или 1; это выбирает, какую строку вы используете. Затем используйте равномерное случайное число, чтобы определить следующее состояние. Выплюните этот номер, промойте, повторите при необходимости.п


Интересное решение! У вас есть пример кода на R? Антон еще?
user333

@Mike Можете ли вы зарегистрировать свой аккаунт? Вы довольно активный пользователь, и мы должны снова и снова объединять его вручную. Процесс довольно прост; просто посетите stats.stackexchange.com/login

Благодарю. Как я могу оценить цепь Маркова (матрицу переходов) по данным? Есть ли функция R для этого?
user333

6

Я попробовал написать код @Mike Anderson в R. Я не мог понять, как это сделать, используя sapply, поэтому я использовал цикл. Я немного изменил пробники, чтобы получить более интересный результат, и использовал «A» и «B» для представления состояний. Дайте мне знать, что вы думаете.

set.seed(1234)
TransitionMatrix <- data.frame(A=c(0.9,0.7),B=c(0.1,0.3),row.names=c('A','B'))
Series <- c('A',rep(NA,99))
i <- 2
while (i <= length(Series)) {
    Series[i] <- ifelse(TransitionMatrix[Series[i-1],'A']>=runif(1),'A','B')
    i <- i+1
}
Series <- ifelse(Series=='A',1,0)
> Series
  [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1
 [38] 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [75] 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1

/ edit: В ответ на комментарий Павла, вот более элегантная формулировка

set.seed(1234)

createSeries <- function(n, TransitionMatrix){
  stopifnot(is.matrix(TransitionMatrix))
  stopifnot(n>0)

  Series <- c(1,rep(NA,n-1))
  random <- runif(n-1)
  for (i in 2:length(Series)){
    Series[i] <- TransitionMatrix[Series[i-1]+1,1] >= random[i-1]
  }

  return(Series)
}

createSeries(100, matrix(c(0.9,0.7,0.1,0.3), ncol=2))

Я написал оригинальный код, когда только начинал изучать R, поэтому немного расслабился. ;-)

Вот как бы вы оценили матрицу перехода, учитывая ряд:

Series <- createSeries(100000, matrix(c(0.9,0.7,0.1,0.3), ncol=2))
estimateTransMatrix <- function(Series){
  require(quantmod)
  out <- table(Lag(Series), Series)
  return(out/rowSums(out))
}
estimateTransMatrix(Series)

   Series
            0         1
  0 0.1005085 0.8994915
  1 0.2994029 0.7005971

Порядок поменяется местами с моей исходной матрицей переходов, но он получает правильные вероятности.


Большой! Я буду как можно скорее ... Выглядит достаточно хорошо ....
user333

Можно ли сделать обратное? Учитывая ряд оценивать матрицу?
user333

пр(ИксTзнак равноя|ИксT-1знак равноJ)

+1, но у меня также есть некоторые комментарии: forцикл будет немного чище, вы знаете длину Series, так что просто используйте for(i in 2:length(Series)). Это исключает необходимость i = i + 1. Кроме того, почему сначала образец A, а затем преобразовать в 0,1? Вы можете непосредственно попробовать 0и 1.
Пол Химстра,

2
В более общем случае вы можете обернуть его в новую функцию, createAutocorBinSeries = function(n=100,mean=0.5,corr=0) { p01=corr*(1-mean)/mean createSeries(n,matrix(c(1-p01,p01,corr,1-corr),nrow=2,byrow=T)) };createAutocorBinSeries(n=100,mean=0.5,corr=0.9);createAutocorBinSeries(n=100,mean=0.5,corr=0.1);чтобы учесть произвольную, заранее заданную автокорреляцию с задержкой 1
Том Венселерс

1

Вот ответ, основанный на markovchainпакете, который можно обобщить для более сложных структур зависимости.

library(markovchain)
library(dplyr)

# define the states
states_excitation = c("steady", "excited")

# transition probability matrix
tpm_excitation = matrix(
  data = c(0.2, 0.8, 0.2, 0.8), 
  byrow = TRUE, 
  nrow = 2,
  dimnames = list(states_excitation, states_excitation)
)

# markovchain object
mc_excitation = new(
  "markovchain",
  states = states_excitation,
  transitionMatrix = tpm_excitation,
  name = "Excitation Transition Model"
)

# simulate
df_excitation = data_frame(
  datetime = seq.POSIXt(as.POSIXct("01-01-2016 00:00:00", 
                                   format = "%d-%m-%Y %H:%M:%S", 
                                   tz = "UTC"), 
                        as.POSIXct("01-01-2016 23:59:00", 
                                   format = "%d-%m-%Y %H:%M:%S", 
                                   tz = "UTC"), by = "min"),
  excitation = rmarkovchain(n = 1440, mc_excitation))

# plot
df_excitation %>% 
  ggplot(aes(x = datetime, y = as.numeric(factor(excitation)))) + 
  geom_step(stat = "identity") + 
  theme_bw() + 
  scale_y_discrete(name = "State", breaks = c(1, 2), 
                   labels = states_excitation)

Это дает вам:

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


0

Я потерял след в статье, где описан этот подход, но здесь идет.

Разложить матрицу перехода на

Tзнак равно(1-пT)[1001]+пT[п0п0(1-п0)(1-п0)]знак равно(1-пT)я+пTЕ

1-пTпT что состояние становится рандомизированным, где рандомизированное означает независимое извлечение из равновесного распределения для следующего состояния (п0 - вероятность равновесия для нахождения в первом состоянии).

Обратите внимание, что из указанных вами данных вам нужно найти пT из указанного T11 через T11знак равно(1-пT)+пT(1-п0),

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


Если кто-нибудь видел документ, который развивает это представление, пожалуйста, дайте мне знать.
Дэйв
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.