Loading [MathJax]/jax/element/mml/optable/Latin1Supplement.js

5 votos

Limpieza de datos en el análisis de regresión

Tengo un conjunto de datos para Temperatura y KwH y actualmente estoy realizando la regresión a continuación. (se realiza una regresión adicional basada en los coeficientes dentro de PHP)

# Alguna especie de estructura de lista..
UsageDataFrame  <- data.frame(Energía, Temperaturas);

# lm se usa para ajustar modelos lineales. Se puede utilizar para llevar a cabo regresiones,
# análisis de varianza de una sola estratificación y análisis de covarianza (aunque
# aov puede proporcionar una interfaz más conveniente para estos).
LinearModel     <- lm(Energía ~ 1+Temperaturas+I(Temperaturas^2), data = UsageDataFrame)

# coeficientes
Coeficientes    <- coeficientes(LinearModel)

system('clear');

cat("--- Coeficientes ---\n");
print(Coeficientes);
cat('\n\n');

El problema viene con nuestros datos, no podemos asegurar que no haya fallas de comunicación aleatorias o simplemente errores aleatorios. Esto puede dejarnos con valores como

Temperaturas <- c(16,15,13,18,20,17,20);
Energía <- c(4,3,3,4,0,60,4)

Temperaturas <- c(17,17,14,17,21,16,19);
Energía <- c(4,3,3,4,0,0,4)

Ahora, como humanos, podemos ver claramente que el 60 para Kwh es un error basado en la temperatura, sin embargo tenemos más de 2,000 sistemas cada uno con múltiples medidores y cada uno en diferentes lugares en todo el país... y con diferentes niveles de uso normal de energía.

Un conjunto de datos normal tendría 48 valores tanto para Temperaturas como para Energía por día, por medidor. En un año completo, es probable que podamos tener alrededor de 0-500 puntos malos por medidor de un total de 17520 puntos.

He leído otros posts sobre el paquete tawny sin embargo no he visto realmente ejemplos que me permitan pasar un data.frame y procesarlos a través de un análisis cruzado.

Entiendo que no se puede hacer mucho, sin embargo seguramente se podrían eliminar los valores muy grandes en función de la temperatura? Y la cantidad de veces que ocurre..

Dado que R se basa en matemáticas no veo ninguna razón para trasladarlo a otro lenguaje.

Tenga en cuenta: Soy un desarrollador de software y nunca he usado R antes.

-- Editar --

Bien, aquí hay un ejemplo del mundo real, parece que este medidor es un buen ejemplo. Se puede ver que los ceros se están acumulando y luego se inserta un valor masivo. "23, 65, 22, 24" son ejemplos de esto. Esto sucede cuando hay una falla de comunicación y el dispositivo retiene el valor de los datos y continúa sumándolos.

(Solo para decir que las fallas de comunicación están fuera de mi alcance ni puedo cambiar el software)

Sin embargo, dado que el cero es un valor válido, quiero eliminar cualquier número masivo en contra de las temperaturas o ceros donde está claro que son un error.

La idea de detectar esto y promediar los datos de nuevo no es una solución para esto tampoco, sin embargo se discutió, pero dado que los datos de este medidor son cada 30 minutos y las fallas de comunicación pueden ocurrir durante días.

La mayoría de los sistemas están usando más Energía que esto, así que tal vez sea un mal ejemplo desde el punto de vista de eliminar los ceros.

Energía: http://pastebin.com/gBa8y5sM Temperaturas: http://pastie.org/4371735

(Pastebin parece haber dejado de funcionar para mí después de publicar un archivo tan grande)

7voto

jldugger Puntos 7490

Utilice un ajuste robusto, como lmrob en el paquete robustbase. Este particular puede detectar automáticamente y ponderar a la baja hasta el 50% de los datos si parecen ser atípicos.

Para ver lo que se puede lograr, simulemos un conjunto de datos difícil con muchos valores atípicos tanto en las variables x como en $y:

library(robustbase)
set.seed(17)
n.puntos <- 17520
n.x.atípicos <- 500
n.y.atípicos <- 500
beta <- c(50, .3, -.05)
x <- rnorm(n.puntos)
y <- beta[1] + beta[2]*x + beta[3]*x^2 + rnorm(n.puntos, sd=0.5)
y[1:n.y.atípicos] <- rnorm(n.y.atípicos, sd=5) + y[1:n.y.atípicos]
x[sample(1:n.puntos, n.x.atípicos)] <- rnorm(n.x.atípicos, sd=10)

La mayoría de los valores de x deberían estar entre 4 y 4, pero hay algunos valores atípicos extremos:

Gráfico de dispersión de datos brutos

Comparemos los coeficientes de mínimos cuadrados ordinarios (lm) con los robustos:

summary(fit<-lm(y ~ 1 + x + I(x^2)))
summary(fit.rob<-lmrob(y ~ 1 + x + I(x^2)))

lm reporta coeficientes ajustados de 49.94, 0.00805 y 0.000479, en comparación con los valores esperados de 50, 0.3 y -0.05. lmrob reporta 49.97, 0.274 y $-0.0229, respectivamente. Ninguno de ellos estima con precisión el término cuadrático (porque contribuye poco y está abrumado por el ruido), pero lmrob ofrece una estimación razonable del término lineal mientras que lm ni siquiera se acerca.

Veamos más de cerca:

i <- abs(x) < 10        # Ventana de los datos de x = -10 a 10
w <- fit.rob$weights[i] # Extraer las ponderaciones robustas (cada una entre 0 y 1)
plot(x[i], y[i], pch=".", cex=4, col=hsv((w + 1/4)*4/5, w/3+2/3, 0.8*(1-w/2)), 
     main="Ajustes por mínimos cuadrados y robusto", xlab="x", ylab="y")

Gráfico de dispersión con ajustes

lmrob informa ponderaciones para los datos. Aquí, en este gráfico ampliado, las ponderaciones se muestran por color: verdes claros para los valores altamente ponderados, granates oscuros para los valores con ponderaciones completas. Claramente, el ajuste de lm es pobre: los valores atípicos de x tienen demasiada influencia. Aunque su término cuadrático es una estimación pobre, el ajuste de lmrob sigue de cerca la curva correcta en todo el rango de los buenos datos (x entre -4 y 4).

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X