여러 잠재 클래스 모델의 결과 시각화


9

잠재 클래스 분석을 사용하여 일련의 이진 변수를 기반으로 관찰 샘플을 묶습니다. R과 poLCA 패키지를 사용하고 있습니다. LCA에서 찾으려는 클러스터 수를 지정해야합니다. 실제로 사람들은 일반적으로 각각 다른 수의 클래스를 지정하는 여러 모델을 실행 한 다음 다양한 기준을 사용하여 데이터에 대한 "최상의"설명을 결정합니다.

class = (i) 모델로 분류 된 관측치가 class = (i + 1) 모델에 의해 어떻게 분포되는지 이해하기 위해 다양한 모델을 살펴 보는 것이 종종 유용하다는 것을 알았습니다. 최소한 모델의 클래스 수에 관계없이 존재하는 매우 강력한 클러스터를 찾을 수 있습니다.

이러한 관계를 그래프로 작성하고 복잡한 결과를보다 쉽게 ​​논문과 통계 지향이 아닌 동료에게보다 쉽게 ​​전달할 수있는 방법을 원합니다. 간단한 네트워크 그래픽 패키지를 사용하여 R 에서이 작업을 수행하는 것이 매우 쉽다고 생각하지만 방법을 모르겠습니다.

누구든지 올바른 방향으로 나를 가리켜 주시겠습니까? 아래는 예제 데이터 세트를 재현하는 코드입니다. 각 벡터 xi는 가능한 클래스가있는 모델에서 100 개의 관측치 분류를 나타냅니다. 관측 (행)이 열에서 클래스 간 이동하는 방법을 그래프로 표시하고 싶습니다.

x1 <- sample(1:1, 100, replace=T)
x2 <- sample(1:2, 100, replace=T)
x3 <- sample(1:3, 100, replace=T)
x4 <- sample(1:4, 100, replace=T)
x5 <- sample(1:5, 100, replace=T)

results <- cbind (x1, x2, x3, x4, x5)

노드가 분류이고 가장자리가 가중치 (색상 또는 색상)에 따라 분류에서 한 모델에서 다음 모델로 이동하는 관측치의 비율을 반영하는 그래프를 생성하는 방법이 있다고 생각합니다. 예 :

여기에 이미지 설명을 입력하십시오

업데이트 : igraph 패키지로 진행 중입니다. 위의 코드에서 시작하여 ...

poLCA 결과는 클래스 멤버십을 설명하기 위해 동일한 숫자를 재활용하므로 약간의 코딩 작업이 필요합니다.

N<-ncol(results) 
n<-0
for(i in 2:N) {
results[,i]<- (results[,i])+((i-1)+n)
n<-((i-1)+n)
}

그런 다음 모든 교차 테이블과 해당 주파수를 가져 와서 모든 모서리를 정의하는 하나의 행렬로 묶어야합니다. 이 작업을 수행하는 훨씬 더 우아한 방법이있을 것입니다.

results <-as.data.frame(results)

g1           <- count(results,c("x1", "x2"))

g2           <- count(results,c("x2", "x3"))
colnames(g2) <- c("x1", "x2", "freq")

g3           <- count(results,c("x3", "x4"))
colnames(g3) <- c("x1", "x2", "freq")

g4           <- count(results,c("x4", "x5"))
colnames(g4) <- c("x1", "x2", "freq")

results <- rbind(g1, g2, g3, g4)

library(igraph)

g1 <- graph.data.frame(results, directed=TRUE)

plot.igraph(g1, layout=layout.reingold.tilford)

여기에 이미지 설명을 입력하십시오

내가 생각하는 igraph 옵션으로 더 많은 것을 할 시간입니다.


1
만족스러운 솔루션을 찾으면 코드를 답변으로 게시 할 수도 있습니다.
Gala

2
이것은 파셋 과 같은 것으로 바뀌고 있습니다. R 구현에 대해서는 ggparallel 을 참조하십시오 .
Andy W

1
나는 앤디의 코멘트 @ 발견 할 때까지, 나는 같은 생각이었다 clustergram (NO 대 피험자의 ID와. 클러스터) 또는 어쩌면 streamgraph (당신이 몇 클러스터가 있다면 아마도 덜 호소가). 물론 이것은 개인 수준에서 기꺼이 일한다고 가정합니다.
chl

답변:


3

지금까지 내가 찾은 최고의 옵션은 다음과 같습니다.

  library (igraph)
  library (ggparallel)

# Generate random data

  x1 <- sample(1:1, 1000, replace=T)
  x2 <- sample(2:3, 1000, replace=T)
  x3 <- sample(4:6, 1000, replace=T)
  x4 <- sample(7:10, 1000, replace=T)
  x5 <- sample(11:15, 1000, replace=T)
  results <- cbind (x1, x2, x3, x4, x5)
  results <-as.data.frame(results)

# Make a data frame for the edges and counts

  g1           <- count (results, c("x1", "x2"))

  g2           <- count (results, c("x2", "x3"))
  colnames(g2) <- c     ("x1", "x2", "freq")

  g3           <- count (results, c("x3", "x4"))
  colnames(g3) <- c     ("x1", "x2", "freq")

  g4           <- count (results, c("x4", "x5"))
  colnames(g4) <- c     ("x1", "x2", "freq")

  edges        <- rbind (g1, g2, g3, g4)

# Make a data frame for the class sizes

  h1            <- count (results, c("x1"))

  h2            <- count (results, c("x2"))
  colnames (h2) <- c     ("x1", "freq")

  h3            <- count (results, c("x3"))
  colnames (h3) <- c     ("x1", "freq")

  h4            <- count (results, c("x4"))
  colnames (h4) <- c     ("x1", "freq")

  h5            <- count (results, c("x5"))
  colnames (h5) <- c     ("x1", "freq")

  cSizes        <- rbind (h1, h2, h3, h4, h5)

# Graph with igraph

  gph    <- graph.data.frame (edges, directed=TRUE)

  layout <- layout.reingold.tilford (gph, root = 1)
  plot (gph,
        layout           = layout,
        edge.label       = edges$freq, 
        edge.curved      = FALSE,
        edge.label.cex   = .8,
        edge.label.color = "black",
        edge.color       = "grey",
        edge.arrow.mode  = 0,
        vertex.label     = cSizes$x1 , 
        vertex.shape     = "square",
        vertex.size      = cSizes$freq/20)

# The same idea, using ggparallel

  a <- c("x1", "x2", "x3", "x4", "x5")

  ggparallel (list (a), 
              data        = results, 
              method      = "hammock", 
              asp         = .7, 
              alpha       = .5, 
              width       = .5, 
              text.angle = 0)

igraph로 완료

Igraph로

파 파렐로 완료

ggparallel로

여전히 저널에 공유하기에는 너무 거칠지 만, 나는 이것들이 매우 유용하다는 것을 분명히 알았습니다.

stack overflow에 대한이 질문 의 가능한 옵션도 있지만 아직 구현할 기회는 없었습니다. 또 다른 가능성 여기 .


1
예제를 게시 해 주셔서 감사합니다. CV의이 포스트 는 RParSets 플롯에 대한 더 좋은 코드를 보여줍니다 (죄송합니다). ggparallel 패키지에 대한 나의 전망은 지금까지 가장자리에서 꽤 거칠다는 것을 제안합니다 (표시 된 임의의 데이터는 ParSets에 대해 좋은 IMO처럼 보이지는 않지만).
Andy W
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.