2012-04-19 40 views
16

Con scipy.stats.linregress estoy realizando una regresión lineal simple en algunos conjuntos de datos experimentales x, y altamente correlacionados, e inspeccionando visualmente inicialmente cada gráfico de dispersión x, y para valores atípicos. De forma más general (es decir, programáticamente), ¿hay alguna manera de identificar y enmascarar valores atípicos?¿Pueden scipy.stats identificar y enmascarar valores atípicos obvios?

Respuesta

21

El paquete statsmodels tiene lo que necesita. Mire este pequeño fragmento de código y su salida:

# Imports # 
import statsmodels.api as smapi 
import statsmodels.graphics as smgraphics 
# Make data # 
x = range(30) 
y = [y*10 for y in x] 
# Add outlier # 
x.insert(6,15) 
y.insert(6,220) 
# Make graph # 
regression = smapi.OLS(x, y).fit() 
figure = smgraphics.regressionplots.plot_fit(regression, 0) 
# Find outliers # 
test = regression.outlier_test() 
outliers = ((x[i],y[i]) for i,t in enumerate(test) if t[2] < 0.5) 
print 'Outliers: ', list(outliers) 

Example figure 1

Outliers: [(15, 220)]

Editar

Con la versión más reciente de statsmodels, las cosas han cambiado un poco. Aquí hay un nuevo fragmento de código que muestra el mismo tipo de detección de valores atípicos.

# Imports # 
from random import random 
import statsmodels.api as smapi 
from statsmodels.formula.api import ols 
import statsmodels.graphics as smgraphics 
# Make data # 
x = range(30) 
y = [y*(10+random())+200 for y in x] 
# Add outlier # 
x.insert(6,15) 
y.insert(6,220) 
# Make fit # 
regression = ols("data ~ x", data=dict(data=y, x=x)).fit() 
# Find outliers # 
test = regression.outlier_test() 
outliers = ((x[i],y[i]) for i,t in enumerate(test.icol(2)) if t < 0.5) 
print 'Outliers: ', list(outliers) 
# Figure # 
figure = smgraphics.regressionplots.plot_fit(regression, 1) 
# Add line # 
smgraphics.regressionplots.abline_plot(model_results=regression, ax=figure.axes[0]) 

Example figure 2

Outliers: [(15, 220)]

+1

¡Gracias por agregar la nueva información! Grandes ejemplos, realmente me han ayudado a entenderlo. –

7

En términos más generales (es decir, programáticamente) ¿hay alguna manera de identificar y enmascarar valores atípicos?

Existen varios algoritmos de detección de valores atípicos; scikit-learn implementa algunos de ellos.

[Negación:. Soy un colaborador scikit-learn]

7

scipy.stats no tiene nada directamente de los valores atípicos, así como la respuesta de algunos enlaces y publicidad para statsmodels (que es un complemento de las estadísticas scipy .stats)

para la identificación de los valores atípicos

http://jpktd.blogspot.ca/2012/01/influence-and-outlier-measures-in.html

http://jpktd.blogspot.ca/2012/01/anscombe-and-diagnostic-statistics.html

http://statsmodels.sourceforge.net/devel/generated/statsmodels.stats.outliers_influence.OLSInfluence.html

en lugar de enmascaramiento, un mejor enfoque es uso de un estimador robusto

http://statsmodels.sourceforge.net/devel/rlm.html

con ejemplos, en los que por desgracia, en la actualidad no muestran las parcelas http://statsmodels.sourceforge.net/devel/examples/generated/tut_ols_rlm.html

RLM downweights valores atípicos . Los resultados de la estimación tienen un atributo weights, y para valores atípicos los pesos son menores que 1. Esto también se puede utilizar para encontrar valores atípicos. RLM también es más robusto si hay varios valores atípicos.

+1

¿Qué es una matriz de diseño exógena? Tengo algunos datos x, y: y = f (x). Es una función principalmente lineal: y = mx + b. ¿Por dónde empiezo con este robusto estimador? La terminología de los documentos es impenetrable para mí. –

0

También es posible limitar el efecto de los valores atípicos utilizando scipy.optimize.least_squares.Especialmente, eche un vistazo al parámetro f_scale:

Valor del margen flexible entre inlier y valores residuales atípicos, por defecto es 1.0. ... Este parámetro no tiene ningún efecto con loss = 'linear', pero para otros valores de pérdida es de crucial importancia.

En la página se comparan 3 funciones diferentes: normal least_squares, y dos métodos que implican f_scale:

res_lsq =  least_squares(fun, x0, args=(t_train, y_train)) 
res_soft_l1 = least_squares(fun, x0, loss='soft_l1', f_scale=0.1, args=(t_train, y_train)) 
res_log =  least_squares(fun, x0, loss='cauchy', f_scale=0.1, args=(t_train, y_train)) 

Least squares comparison

Como puede verse, los mínimos cuadrados normales es mucho más afectado por valores atípicos de datos, y puede valer la pena jugar con diferentes funciones loss en combinación con diferentes f_scales. Las funciones posibles pérdidas son (tomado de la documentación):

‘linear’ : Gives a standard least-squares problem. 
‘soft_l1’: The smooth approximation of l1 (absolute value) loss. Usually a good choice for robust least squares. 
‘huber’ : Works similarly to ‘soft_l1’. 
‘cauchy’ : Severely weakens outliers influence, but may cause difficulties in optimization process. 
‘arctan’ : Limits a maximum loss on a single residual, has properties similar to ‘cauchy’. 

El scipy libro de cocina has a neat tutorial en regresión no lineal robusto.

Cuestiones relacionadas