Separando duas populações da amostra

13

Estou tentando separar dois grupos de valores de um único conjunto de dados. Eu posso assumir que uma das populações está normalmente distribuída e tem pelo menos metade do tamanho da amostra. Os valores do segundo são mais baixos ou mais altos que os valores do primeiro (a distribuição é desconhecida). O que estou tentando fazer é encontrar os limites superior e inferior que encerrariam a população normalmente distribuída da outra.

Minha suposição me fornece um ponto de partida:

  • todos os pontos dentro da faixa interquartil da amostra são da população normalmente distribuída.

Estou tentando testar se os outliers os tiram do restante da amostra até que eles não se encaixem no 3º.dev da população normalmente distribuída. O que não é o ideal, mas parece produzir resultados razoáveis ​​o suficiente.

Minha suposição é estatisticamente correta? Qual seria a melhor maneira de fazer isso?

ps por favor corrija as tags alguém.

SilentGhost
fonte
Você pode assumir que os outros dois grupos são de diferentes distribuições normais?
csgillespie
@cgillespie: é o mesmo grupo, apenas com dois modos, eu acho, e, portanto, provavelmente não posso assumir isso.
SilentGhost
1
Você sabia que os membros do segundo grupo não estão incluídos no primeiro grupo ou apenas deseja rotular erroneamente esses membros como pertencentes ao primeiro grupo?
Christian

Respostas:

10

Se bem entendi, você pode ajustar uma mistura de duas normais aos dados. Existem muitos pacotes R disponíveis para isso. Este exemplo usa o mixtools pacote:

#Taken from the documentation
library(mixtools)
data(faithful)
attach(faithful)

#Fit two Normals
wait1 = normalmixEM(waiting, lambda = 0.5)
plot(wait1, density=TRUE, loglik=FALSE)

Isto dá:

Mistura de duas normais http://img294.imageshack.us/img294/4213/kernal.jpg

O pacote também contém métodos mais sofisticados - verifique a documentação.

csgillespie
fonte
A imagem que você anexou expirou.
naktinis
3
  1. Para dados no intervalo IQR, você deve usar a distribuição normal truncada (por exemplo, R package gamlss.tr) para estimar os parâmetros dessa distribuição.
  2. Outra abordagem é usar modelos de mistura com 2 ou 3 componentes (distribuições). Você pode ajustar esses modelos usando o pacote gamlss.mx (as distribuições do pacote gamlss.dist podem ser especificadas para cada componente da mistura).
Wojtek
fonte
2

Isso pressupõe que você nem sabe se a segunda distribuição é normal ou não; Basicamente, manejo essa incerteza concentrando-me apenas na distribuição normal. Esta pode ou não ser a melhor abordagem.

Se você pode assumir que as duas populações estão completamente separadas (ou seja, todos os valores da distribuição A são menores que todos os valores da distribuição B), uma abordagem é usar a função optimize () em R para procurar o ponto de interrupção que gera estimativas da média e do dp da distribuição normal que tornam os dados mais prováveis:

#generate completely separated data
a = rnorm(100)
b = rnorm(100,10)
while(!all(a<b)){
    a = rnorm(100)
    b = rnorm(100,10)
}

#create a mix
mix = c(a,b)

#"forget" the original distributions
rm(a)
rm(b)

#try to find the break point between the distributions
break_point = optimize(
    f = function(x){
        data_from_a = mix[mix<x]
        likelihood = dnorm(data_from_a,mean(data_from_a),sd(data_from_a))
        SLL = sum(log(likelihood))
        return(SLL)
    }
    , interval = c(sort(mix)[2],max(mix))
    , maximum = TRUE
)$maximum

#label the data
labelled_mix = data.frame(
    x = mix
    , source = ifelse(mix<break_point,'A','B')
)
print(labelled_mix)

Se você não pode assumir a separação completa, acho que terá que assumir alguma distribuição para a segunda distribuição e usar a modelagem de mistura. Observe que a modelagem da mistura não rotulará os pontos de dados individuais, mas fornecerá a proporção da mistura e as estimativas dos parâmetros de cada distribuição (por exemplo, média, sd, etc.).

Mike Lawrence
fonte
optimizerequer que duas distribuições estejam lado a lado como eu entendo. No meu caso, um está dentro do outro, ou seja, os valores da segunda população estão nos dois lados dos limites.
SilentGhost
1

Estou surpreso que ninguém tenha sugerido a solução óbvia:

 #generate completely separated data
library(robustbase)
set.seed(123)  
x<-rnorm(200)
x[1:40]<-x[1:40]+10  
x[41:80]<-x[41:80]-10
Rob<-ltsReg(x~1,nsamp="best")
#all the good guys
which(Rob$raw.weights==1)

Agora, a explicação: a ltsRegfunção no pacote robustbase, quando chamada com a opção

nsamp="best"

produz os pesos univariados (exatos) do MCD. (esses são os pesos n-vetor 0-1 armazenados no $raw.weightsobjeto. O algoritmo para identificá-los é o estimador MCD (1)).

h=(n+2)/2

hx(Eu)Euth
(x(1),...,x(h+1))(x(2),...,x(h+2))

n-h

(1) PJ Rousseeuw (1984). Mínima mediana da regressão de quadrados, Jornal da Associação Estatística Americana.

user603
fonte