Chcę wizualizować wyniki grupowania (wytworzone za pomocą protoclust{protoclust}
) poprzez tworzenie wykresów scater dla każdej pary zmiennych używanych do klasyfikowania moich danych, kolorowania według klas i nakładania się elips na 95% przedział ufności dla każdej z klas (aby sprawdzić, które klasy elipses pokrywają się pod każdą parą zmiennych).
Zaimplementowałem rysunek elips na dwa różne sposoby, a powstałe elipsy są różne! (większe elipsy dla pierwszej implementacji!) A priori różnią się jedynie rozmiarem (niektóre różne skalowanie?), ponieważ środki i kąt osi wydają się być podobne w obu. Chyba muszę coś zrobić źle, używając jednego z nich (mam nadzieję, że nie w obu przypadkach!) Lub w argumentach.
Czy ktoś może mi powiedzieć, co robię źle?
Tutaj kod dla dwóch implementacji; oba są oparte na odpowiedziach na pytanie, w jaki sposób elipsę danych można nałożyć na wykres punktowy ggplot2?
### 1st implementation
### using ellipse{ellipse}
library(ellipse)
library(ggplot2)
library(RColorBrewer)
colorpal <- brewer.pal(10, "Paired")
x <- data$x
y <- data$y
group <- data$group
df <- data.frame(x=x, y=y, group=factor(group))
df_ell <- data.frame()
for(g in levels(df$group)){df_ell <- rbind(df_ell, cbind(as.data.frame(with(df[df$group==g,], ellipse(cor(x, y),scale=c(sd(x),sd(y)),centre=c(mean(x),mean(y))))),group=g))}
p1 <- ggplot(data=df, aes(x=x, y=y,colour=group)) + geom_point() +
geom_path(data=df_ell, aes(x=x, y=y,colour=group))+scale_colour_manual(values=colorpal)
### 2nd implementation
###using function ellipse_stat()
###code by Josef Fruehwald available in: https://github.com/JoFrhwld/FAAV/blob/master/r/stat-ellipse.R
p2 <-qplot(data=df, x=x,y=y,colour=group)+stat_ellipse(level=0.95)+scale_colour_manual(values=colorpal)
Oto dwa wykresy razem (lewy wykres to p1
implementacja ( ellipse()
):
Dane są dostępne tutaj: https://www.dropbox.com/sh/xa8xrisa4sfxyj0/l5zaGQmXJt
źródło
Warning message: In cov.trob(cbind(data$x, data$y)) : Probable convergence failure
czy dzieje się tak również wtedy, gdy kod jest uruchamiany?Odpowiedzi:
Nie robisz nic złego, obie funkcje przyjmują różne podstawowe założenia dotyczące dystrybucji danych. Twoja pierwsza implementacja zakłada wielowymiarową normalność, a druga wielowymiarową dystrybucję t (patrz? Cov.trob w pakiecie MASS). Efekt łatwiej zobaczyć, jeśli wyciągniesz jedną grupę:
Więc chociaż jest blisko tego samego centrum i orientacji, nie są one takie same. Można zbliżyć się do tego samego rozmiaru za pomocą elipsy
cov.trob()
, aby uzyskać korelację i skalę dla przechodząc doellipse()
, i używając argumentu t ustawić skalowanie równa f-dystrybucji, jakstat_ellipse()
robi.ale korespondencja wciąż nie jest dokładna. Różnica musi wynikać z zastosowania chłodnego rozkładu macierzy kowariancji i utworzenia skalowania na podstawie korelacji i odchyleń standardowych. Nie jestem wystarczająco matematykiem, żeby zobaczyć, gdzie dokładnie jest różnica.
Który jest prawidłowy? Ty decydujesz!
stat_ellipse()
Realizacja będzie mniej wrażliwy na odległych punktów, podczas gdy pierwszy będzie bardziej konserwatywna.źródło