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


15

Як я можу генерувати двійкові часові ряди таким чином:

  1. Вказується середня ймовірність спостереження 1 (скажімо, 5%);
  2. Умовна ймовірність спостереження 1 за час задана величина при (скажімо 30%, якщо значення було 1)?tt1t1

Відповіді:


17

Використовуйте дводержавний ланцюг Маркова.

Якщо стани називаються 0 і 1, то ланцюг може бути представлена ​​матрицею 2x2 дає ймовірності переходу між станами, де - ймовірність переходу зі стану в стан . У цій матриці кожен рядок повинен становити 1,0.PPijij

З твердження 2 маємо , а просте збереження тоді говорить .P11=0.3P10=0.7

З твердження 1 потрібно, щоб довгострокова ймовірність (також її називають рівноважною або стаціонарною) була . Це говорить Розв’язування дає і матрицю переходуP1=0.05

P1=0.05=0.3P1+P01(1P1)
P01=0.0368421
P=(0.9631580.03684210.70.3)

(Ви можете перевірити матрицю переходу на правильність, піднявши її до високої потужності - у цьому випадку 14 виконує роботу - кожен рядок результату дає однакові ймовірності стаціонарного стану)

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


Цікаве рішення! У вас, можливо, є якийсь зразок коду в R? Антоні ще?
користувач333

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

Спасибі. Як я можу оцінити ланцюг Маркова (матриця переходу) за даними? Чи існує функція R для цього?
користувач333

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

/ редагувати: У відповідь на коментар Павла, ось більш елегантна формулювання

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

Чи можна робити зворотне? За даними серії оцінюють матрицю?
користувач333

Пr(Хт=i|Хт-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=(1pt)[1001]+pt[p0p0(1p0)(1p0)]=(1pt)I+ptE

1ptptp0

ptT11T11=(1pt)+pt(1p0)

Однією з корисних особливостей цього розкладу є те, що він досить прямо узагальнює клас класу корельованих моделей Маркова у задачах з більшими розмірами.


Якщо хтось бачив папір, яка розвиває це представлення, будь ласка, дайте мені знати.
Дейв
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.