Existe um constrangimento interno para fazer algo como o seguinte? Ou seja, pegue uma lista d
e retorne uma lista filtered_d
com todos os elementos remotos removidos com base em alguma distribuição presumida dos pontos em d
.
import numpy as np
def reject_outliers(data):
m = 2
u = np.mean(data)
s = np.std(data)
filtered = [e for e in data if (u - 2 * s < e < u + 2 * s)]
return filtered
>>> d = [2,4,5,1,6,5,40]
>>> filtered_d = reject_outliers(d)
>>> print filtered_d
[2,4,5,1,6,5]
Digo 'algo como' porque a função pode permitir distribuições variáveis (poisson, gaussiana, etc.) e limites de valores discrepantes dentro dessas distribuições (como o m
que usei aqui).
Respostas:
Este método é quase idêntico ao seu, só que mais numpyst (funcionando também apenas em matrizes numpy):
fonte
m
for suficientemente grande (por exemplom=6
), mas para pequenos valoresm
isso sofre da média a variância não sendo estimadores robustos.Algo importante ao lidar com outliers é que se deve tentar usar estimadores o mais robustos possível. A média de uma distribuição será influenciada por outliers, mas, por exemplo, a mediana será muito menor.
Com base na resposta de eumiro:
Aqui, substituí a média pela mediana mais robusta e o desvio padrão pela distância absoluta da mediana até a mediana. Em seguida, dimensionei as distâncias por seus (novamente) valores medianos de modo que
m
fiquem em uma escala relativa razoável.Observe que para a
data[s<m]
sintaxe funcionar,data
deve ser uma matriz numpy.fonte
3.5 / .6745 ~= 5.189
(eles multiplicams
por 0,6745 e especificam umm
de 3,5 ... também levaabs(s)
). Alguém pode explicar a escolha de m? Ou é algo que você identificará em seu conjunto de dados específico?m
vez de afirmações fofas como "interação de pureza e eficiência"?TypeError: only integer scalar arrays can be converted to a scalar index
A resposta de Benjamin Bannier fornece uma passagem quando a mediana das distâncias da mediana é 0, portanto, achei essa versão modificada um pouco mais útil para os casos fornecidos no exemplo abaixo.
Exemplo:
Dá:
fonte
Com base no Benjamin, usando
pandas.Series
e substituindo MAD por IQR :Por exemplo, se você definir
iq_range=0.6
, os percentis do intervalo interquartil se tornará :,0.20 <--> 0.80
portanto, mais outliers serão incluídos.fonte
Uma alternativa é fazer uma estimativa robusta do desvio padrão (assumindo estatísticas gaussianas). Procurando calculadoras online, vejo que o percentil 90% corresponde a 1,2815σ e 95% é 1,645σ ( http://vassarstats.net/tabs.html?#z )
Como um exemplo simples:
O resultado que obtenho é:
Que está próximo do valor esperado de 2.
Se quisermos remover pontos acima / abaixo de 5 desvios padrão (com 1000 pontos, esperaríamos 1 valor> 3 desvios padrão):
Que dá:
Não tenho ideia de qual abordagem é a mais eficiente / robusta
fonte
Eu gostaria de fornecer dois métodos nesta resposta, solução baseada em "pontuação z" e solução baseada em "IQR".
O código fornecido nesta resposta funciona tanto em
numpy
matriz dim única quanto em matriz múltiplanumpy
.Vamos importar alguns módulos primeiro.
método baseado em pontuação z
Este método testará se o número está fora dos três desvios padrão. Com base nesta regra, se o valor for outlier, o método retornará verdadeiro, caso contrário, retornará falso.
Método baseado em IQR
Este método testará se o valor é menor
q1 - 1.5 * iqr
ou maior queq3 + 1.5 * iqr
, que é semelhante ao método de plotagem do SPSS.Finalmente, se você quiser filtrar os outliers, use um
numpy
seletor.Tenha um bom dia.
fonte
Considere que todos os métodos acima falham quando o desvio padrão fica muito grande devido a grandes valores discrepantes.
( Simalar, pois a média de cálculo falha e deveria, em vez disso, calcular a mediana. No entanto, a média é "mais propensa a um erro como o stdDv". )
Você pode tentar aplicar iterativamente seu algoritmo ou filtrar usando o intervalo interquartil: (aqui, "fator" está relacionado a um intervalo * sigma, mas apenas quando seus dados seguem uma distribuição gaussiana)
fonte
Eu queria fazer algo semelhante, exceto definir o número como NaN em vez de removê-lo dos dados, já que se você removê-lo, você altera o comprimento, o que pode atrapalhar a plotagem (ou seja, se você apenas remover outliers de uma coluna em uma tabela , mas você precisa que ele permaneça o mesmo que as outras colunas para que possa plotá-las uma contra a outra).
Para fazer isso, usei as funções de mascaramento do numpy :
fonte
se você quiser obter a posição do índice dos outliers
idx_list
, ele será retornado.fonte
Para um conjunto de imagens (cada imagem tem 3 dimensões), onde eu queria rejeitar outliers para cada pixel que usei:
Então, é possível calcular a média:
(Eu uso para subtração de fundo)
fonte