Memvisualisasikan hasil dari beberapa model kelas laten

9

Saya menggunakan analisis kelas laten untuk mengelompokkan sampel pengamatan berdasarkan satu set variabel biner. Saya menggunakan R dan paket poLCA. Di LCA, Anda harus menentukan jumlah cluster yang ingin Anda temukan. Dalam praktiknya, orang biasanya menjalankan beberapa model, masing-masing menentukan jumlah kelas yang berbeda, dan kemudian menggunakan berbagai kriteria untuk menentukan mana yang merupakan "terbaik" penjelasan data.

Saya sering merasa sangat berguna untuk melihat berbagai model untuk mencoba memahami bagaimana pengamatan diklasifikasikan dalam model dengan kelas = (i) didistribusikan oleh model dengan kelas = (i + 1). Paling tidak Anda kadang-kadang dapat menemukan kelompok yang sangat kuat yang ada terlepas dari jumlah kelas dalam model.

Saya ingin cara membuat grafik hubungan-hubungan ini, untuk lebih mudah mengomunikasikan hasil-hasil yang rumit ini dalam makalah dan kepada rekan-rekan yang tidak berorientasi secara statistik. Saya membayangkan ini sangat mudah dilakukan di R menggunakan beberapa jenis paket grafik jaringan yang sederhana, tetapi saya tidak tahu caranya.

Adakah yang bisa mengarahkan saya ke arah yang benar? Di bawah ini adalah kode untuk mereproduksi contoh dataset. Setiap vektor xi mewakili klasifikasi 100 pengamatan, dalam model dengan kelas yang mungkin. Saya ingin menggambarkan bagaimana pengamatan (baris) bergerak dari satu kelas ke kelas lainnya di seluruh kolom.

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)

Saya membayangkan ada cara untuk menghasilkan grafik di mana node adalah klasifikasi dan ujung-ujungnya mencerminkan (dengan bobot, atau warna mungkin)% dari pengamatan bergerak dari klasifikasi dari satu model ke model berikutnya. Misalnya

masukkan deskripsi gambar di sini

UPDATE: Memiliki beberapa kemajuan dengan paket igraph. Mulai dari kode di atas ...

Hasil poLCA mendaur ulang angka yang sama untuk menggambarkan keanggotaan kelas, jadi Anda perlu melakukan sedikit pengodean ulang.

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

Maka Anda perlu mendapatkan semua tabulasi silang dan frekuensinya, dan mengikatnya menjadi satu matriks yang mendefinisikan semua sisi. Mungkin ada cara yang jauh lebih elegan untuk melakukan ini.

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)

masukkan deskripsi gambar di sini

Waktu untuk bermain lebih banyak dengan opsi igraph kurasa.

DL Dahly
sumber
1
Jika Anda menemukan solusi yang memuaskan Anda, Anda juga dapat memposting kode Anda sebagai jawaban
Gala
2
Ini berubah menjadi sesuatu seperti parset . Lihat ggparallel untuk implementasi R.
Andy W
1
Sampai saya perhatikan komentar @ Andy, saya berpikir tentang sesuatu seperti clustergram (dengan ID subjek vs cluster no.) Atau mungkin sebuah streamgraph (mungkin kurang menarik jika Anda memiliki beberapa cluster). Ini, tentu saja, menganggap Anda bersedia bekerja di tingkat individu.
chl

Jawaban:

3

Sejauh ini, opsi terbaik yang saya temukan, berkat saran Anda, adalah ini:

  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)

Selesai dengan igraph

Dengan Igraph

Dilakukan dengan ggparallel

Dengan ggparallel

Masih terlalu kasar untuk dibagikan dalam jurnal, tetapi saya pasti menemukan ini sangat berguna.

Ada juga opsi yang memungkinkan dari pertanyaan ini pada stack overflow , tetapi saya belum memiliki kesempatan untuk mengimplementasikannya; dan kemungkinan lain di sini .

DL Dahly
sumber
1
Terima kasih telah memposting contoh. Posting di CV ini menunjukkan beberapa kode yang lebih bagus untuk plot ParSets di R (maaf seharusnya menunjuk itu dulu). Perampokan saya ke dalam paket ggparallel menunjukkan cukup kasar di sekitar tepi sejauh ini (meskipun data acak seperti yang Anda tunjukkan tidak akan cenderung terlihat bagus IMO untuk ParSets).
Andy W