O principal problema da análise de agrupamento de dados práticos é a presença de outliers. A maioria dos métodos de agrupamento existentes não leva em consideração a sua existência, por isso, observações claramente anômalas são incluídas na composição de alguns agrupamentos, o que pode deslocar gravemente seus centros e afetar a qualidade da classificação. Claro, você pode primeiro verificar os dados iniciais quanto a valores discrepantes, eliminá-los etc., mas então a tarefa se transformará em uma de duas fases, mas gostaríamos que fosse "tudo de uma vez".
Uma das abordagens para resolver esse problema (para o método de agrupamento filtrar automaticamente outliers) foi chamada de "estimador de máxima verossimilhança robusto e inadequado" e foi descrito neste artigo de 2017 ( http://dx.doi.org/10.1080/ 01621459.2015. 1100996 ), e recentemente recebeu uma implementação em R. Vamos conversar sobre isso.
Um momento de teoria
Em suma, o agrupamento usando algoritmos EM é baseado na suposição de que clusters específicos têm uma forma próxima à forma de uma distribuição normal multivariada. Então o problema de agrupamento pode ser considerado como o problema de separação dos componentes da mistura, e os agrupamentos são determinados de acordo com a probabilidade de cair em um ou outro componente.
A atualização matemática do algoritmo clássico é que uma suposição ligeiramente diferente é feita. Acredita-se que a função de probabilidade da distribuição de pontos seja a soma de uma mistura de gaussianas e uma distribuição uniforme de pontos de ruído (assume-se que os outliers estão distribuídos uniformemente), ou seja
Isso leva a alguma complicação da solução do problema de otimização, que agora parece uma solução para o problema máximo
mas com tais restrições
Este problema de otimização (especialmente com condições impostas à razão dos autovalores) nem sempre tem solução. Os autores são honestos sobre isso, mas também afirmam que seu algoritmo é bastante fácil de lidar com clusters de uma forma bastante complexa. Vamos checar
Experimentar
- , .
library(ggplot2)
#
set.seed(739)
n <- 500 # numer of points
y <- abs(c(rnorm(n,5,2)))
x <- c(rnorm(n,5,1))/sqrt(y)
class<-rep(1,n)
dat1 <- as.data.frame(cbind(x,y,class)) # - -
y <- c(rnorm(n,8,0.4))
x <- rlnorm(n, meanlog = log(7), sdlog = 0.2)
class<-rep(2,n)
dat2 <- as.data.frame(cbind(x,y,class)) # -
y <- c(runif(n, min = 2, max = 7))
x <- c(rnorm(n,8,0.4))
class<-rep(3,n)
dat3 <- as.data.frame(cbind(x,y,class)) # -
y <- c(runif(n/10, min = 0, max = 10))
x <- c(runif(n/10, min = 0, max = 10))
class<-rep(0,n/10)
dat4 <- as.data.frame(cbind(x,y,class)) #
dat <- rbind(dat1,dat2,dat3,dat4)
colnames(dat) <- c("x","y", "class")
dat$class <- as.factor(dat$class)
dat_test <- as.data.frame(dat)
p_base <- ggplot(dat,aes(x=x,y=y,color=class)) + geom_point()
ggExtra::ggMarginal(p_base, groupColour = TRUE, groupFill = TRUE)
otrimle , , . 2 5, .
library(otrimle)
clus <- otrimleg(dat[,c(1,2)], G=2:5, monitor=1) # monitor
-
, ( , , , , iloglik . , , 4 5 3 - ). . , ,
clus$solution
Noise - , . ( 1,2,10 ) - 5 .
clus_2 <-otrimle(dat[,c(1,2)], G = 5, npr.max = 0.01, erc = 20, monitor = TRUE)
# npr.max -
# erc - /
clus_2$code
clus_2$flag
clus_2$code 0, , , clus_2$code = 1, , EM- ( ), clus_2$code = 2, , .
clus_2$flag .
clus_2$flag = 1,
, , 0.
clus_2$flag = 2,
clus_2$flag = 3,
clus_2$flag = 4,
(clus_2$code = 2, clus_2$flag = 4), .
clus_2$mean #
head(clus_2$tau) #
head(clus_2$cluster) #
. , .
Pode-se notar que mesmo que se adivinhe com o número de clusters (3), então os resultados do clustering, de fato, serão muito diferentes dos verdadeiros - e um quadro mais adequado será dado por partições com um número maior de clusters do que na realidade. Isso ocorreu devido à forma não elíptica dos clusters, mas em geral o algoritmo funciona bem mesmo em condições de ruído.