Calcular matriz de transição (Markov) em R

29

Existe uma maneira no R (uma função interna) de calcular a matriz de transição para uma cadeia de Markov a partir de um conjunto de observações?

Por exemplo, usando um conjunto de dados como o seguinte e calculando a matriz de transição de primeira ordem?

dat<-data.frame(replicate(20,sample(c("A", "B", "C","D"), size = 100, replace=TRUE)))
B_Miner
fonte
O que essa matriz deve representar? Uma execução da cadeia de Markov para cada linha (ou coluna)? Ou...?
cardinal
Sendo 100 amostras de seqüências de estados (20 delas).
B_Miner
Você está procurando estimativas de probabilidade ou apenas conta?
cardinal
Estimativas de probabilidade. Usando as seqüências observadas, qual é a matriz de probabilidade de transição (4x4 neste exemplo).
B_Miner

Respostas:

33

Não estou imediatamente ciente de uma função "interna" (por exemplo, in baseou similar), mas podemos fazer isso com muita facilidade e eficiência em algumas linhas de código.

Aqui está uma função que usa uma matriz (não um quadro de dados) como entrada e produz as contagens de transição ( prob=FALSE) ou, por padrão ( prob=TRUE), as probabilidades estimadas de transição.

# Function to calculate first-order Markov transition matrix.
# Each *row* corresponds to a single run of the Markov chain
trans.matrix <- function(X, prob=T)
{
    tt <- table( c(X[,-ncol(X)]), c(X[,-1]) )
    if(prob) tt <- tt / rowSums(tt)
    tt
}

Se precisar chamá-lo em um quadro de dados, você sempre poderá

trans.matrix(as.matrix(dat))

Se você estiver procurando por algum pacote de terceiros, o Rseek ou o site de pesquisa do R poderá fornecer recursos adicionais.

cardeal
fonte
1
+1 Existem também vários pacotes R, incluindo HMMe RHMMque podem ser úteis.
19412 Wayne
@Wayne: (+1) eu encontrei os vários pacotes HMM disponíveis no Rser muito mimado no passado, especialmente quando se trata de montagem e eu nunca encontrou um que eu realmente gostava ou confiável. Talvez a situação esteja melhor agora. Eu imaginaria que eles acertariam isso, no entanto. Se você souber de uma solução, envie-a como resposta; Eu ficaria feliz em votar!
cardinal
1
Eu tentei, mas sem sucesso. Esse problema não envolve estados ocultos e os pacotes que encontrei não possuem funções utilitárias que fariam nada menos que o HMM completo. (Como uma observação lateral, o datquadro de dados que o OP fornece como exemplo tem colunas de dados, e eles querem uma matriz de transição por coluna ou uma matriz geral de transição ou podemos apenas transformar a matriz em um vetor?)
Wayne
@Wayne: (+1) Você levanta um bom argumento. Eu assumi que cada linha é uma execução independente da cadeia de Markov e, portanto, estamos buscando as estimativas de probabilidade de transição, a partir dessas cadeias, paralelamente. Mas, mesmo que essa fosse uma cadeia que, digamos, envolvesse de uma extremidade a uma linha até o início da próxima, as estimativas ainda seriam bem mais próximas devido à estrutura de Markov.
cardinal
1
@B_Miner: Sim, desde que você possa razoavelmente assumir que cada cliente se comporta de maneira independente de todos os outros. Tais modelos e muitas extensões são relativamente comuns no comportamento do usuário analisando, por exemplo, em visitas repetidas para um site, etc.
cardeal
25

Acabei de enviar um novo pacote R markovchain, baseado no estilo de programação S4. Juntamente com vários métodos para manipular objetos markovchain S4, ele contém uma função para ajustar uma cadeia Markov a partir de uma sequência de estados. Dê uma olhada em:

library(markovchain) 
sequence <- c("a", "b", "a", "a", "a", "a", "b", "a", "b", "a", 
              "b", "a", "a", "b", "b", "b", "a")
mcFit <- markovchainFit(data=sequence)

Isso poderia ajudar.

Giorgio Spedicato
fonte
Um pacote muito bom! Você apoiará cadeias de Markov de ordem superior?
Wayne
Me pediram uma cadeia Markov de ordem superior e outro cara está escrevendo algum código. Se você deseja participar do sistema em código desenvolvendo enviar um e-mail para o endereço mantainer e nós podemos discutir ...
Giorgio Spedicato
Olá, qual é a diferença entre markovchainFit e a função postada acima? Eles produzem os mesmos resultados? Obrigado
aaaaa
1
@aaaaa, a função deve ser mais rápida desde a compilação no Rcpp e compilada dentro de um pacote. Também lida com muito mais formatos de dados. markovchainFit
Giorgio Spedicato