2010-03-25 13 views
8

interpolación de grandes conjuntos de datosinterpolación de grandes conjuntos de datos sobre la marcha

que tienen un gran conjunto de datos de alrededor de 0.5million registros que representan el tipo de cambio entre el USD/GBP en el transcurso de un día determinado.

que tienen una aplicación que quiere ser capaz de graficar estos datos o tal vez un subconjunto. Por razones obvias, no quiero trazar 0.5 millones de puntos en mi gráfico.

Lo que necesito es un conjunto de datos más pequeño (100 puntos o así) que con precisión (como sea posible) representa los datos dados. ¿Alguien sabe de alguna manera interesante y de rendimiento que estos datos se pueden lograr?

Cheers, Karl

+1

¿Puedes aclarar "representa"? ¿Te refieres solo a la vista o para realizar cálculos? – Carl

+0

El resultado final sería un conjunto de datos de un tipo que luego podría procesarse y graficarse – Karl

+1

¡Suena como un trabajo para R! – Joel

Respuesta

3

Una idea es usar el DBMS para comprimir los datos para que mediante una consulta adecuada. Algo a lo largo de las líneas de tener que tomar un medio para un rango específico, un pseudo-consulta:

SELECT truncate_to_hour(rate_ts), median(rate) FROM exchange_rates 
WHERE rate_ts >= start_ts AND rate_ts <= end_ts 
GROUP BY truncate_to_hour(rate_ts) 
ORDER BY truncate_to_hour(rate_ts) 

Dónde truncate_to_hour es algo apropiado para su DBMS. O un enfoque similar con algún tipo de función para segmentar el tiempo en bloques únicos (como ronda al intervalo de 5 minutos más cercano), u otra función matemática para agregar el grupo que sea apropiado en lugar de la mediana. Dada la complejidad del procedimiento de segmentación de tiempo y cómo su DBMS lo optimiza, puede ser más eficiente ejecutar una consulta en una tabla temporal con el valor de tiempo segmentado.

1

Algo así como RRDTool haría lo que necesita automáticamente - el tutorial debería comenzar, y drraw graficará los datos.

yo uso esto en el trabajo para cosas como gráficos de error, no necesito una resolución de 1 minuto durante un período de tiempo de 6 meses, sólo para los más recientes pocas horas. Después de eso tengo una resolución de 1 hora durante unos días, luego una resolución de 1 día durante unos meses.

1

Si quisiera escribir uno propio, una solución obvia sería romper su conjunto de registros en un número fijo de puntos, para lo cual el valor sería el promedio (promedio, mediana, ... elija uno) . Esto tiene la ventaja probable de ser el más rápido y muestra las tendencias generales.

Pero carece del dramatismo de los tics de precios. Una solución mejor probablemente implicaría buscar los puntos de inflexión, y luego seleccionarlos utilizando ventanas deslizantes. Esto tiene la ventaja de mostrar mejor los eventos reales del día, pero será más lento.

4

Existen varios métodos estadísticos para reducir un conjunto de datos grande a un conjunto de datos más pequeño y más fácil de visualizar. No está claro a partir de su pregunta qué resumen estadístico desea. Acabo de suponer que desea ver cómo cambia la tasa de cambio en función del tiempo, pero tal vez esté interesado en la frecuencia con la que la tasa de cambio supera un cierto valor o alguna otra estadística que no estoy considerando.

Resumiendo una tendencia en el tiempo

Aquí hay un ejemplo usando el método lowess en R (de la documentación sobre scatter plot smoothing): controles f

> library(graphics) 
# print out the first 10 rows of the cars dataset 
> cars[1:10,] 
    speed dist 
1  4 2 
2  4 10 
3  7 4 
4  7 22 
5  8 16 
6  9 10 
7  10 18 
8  10 26 
9  10 34 
10 11 17 

# plot the original data 
> plot(cars, main = "lowess(cars)") 
# fit a loess-smoothed line to the points 
> lines(lowess(cars), col = 2) 
# plot a finger-grained loess-smoothed line to the points 
> lines(lowess(cars, f=.2), col = 3) 

El parámetro la fuerza con la regresión se ajusta a tu información. Use algo de consideración con esto, ya que quiere algo que se ajuste con precisión a sus datos sin sobreajuste.En lugar de velocidad y distancia, puede trazar el tipo de cambio en función del tiempo.

También es sencillo acceder a los resultados del suavizado. Aquí está cómo hacerlo:

> data = lowess(cars$speed, cars$dist) 
> data 
$x 
[1] 4 4 7 7 8 9 10 10 10 11 11 12 12 12 12 13 13 13 13 14 14 14 14 15 15 15 16 16 17 17 17 18 18 18 18 19 19 
[38] 19 20 20 20 20 20 22 23 24 24 24 24 25 

$y 
[1] 4.965459 4.965459 13.124495 13.124495 15.858633 18.579691 21.280313 21.280313 21.280313 24.129277 24.129277 
[12] 27.119549 27.119549 27.119549 27.119549 30.027276 30.027276 30.027276 30.027276 32.962506 32.962506 32.962506 
[23] 32.962506 36.757728 36.757728 36.757728 40.435075 40.435075 43.463492 43.463492 43.463492 46.885479 46.885479 
[34] 46.885479 46.885479 50.793152 50.793152 50.793152 56.491224 56.491224 56.491224 56.491224 56.491224 67.585824 
[45] 73.079695 78.643164 78.643164 78.643164 78.643164 84.328698 

El objeto de datos que vuelvas contiene entradas denominadas X e Y, que corresponden a los valores X e Y pasados ​​a la función lowess. En este caso, xey representan la velocidad y dist.

0

Cómo hacer la enumeración/iterador de la envoltura. No estoy familiarizado con Java, pero es posible que se ve similar a:

class MedianEnumeration implements Enumeration<Double> 
{ 
    private Enumeration<Double> frameEnum; 
    private int frameSize; 

    MedianEnumeration(Enumeration<Double> e, int len) { 
     frameEnum = e; 
     frameSize = len; 
    } 

    public boolean hasMoreElements() { 
     return frameEnum.hasMoreElements(); 
    } 

    public Double nextElement() { 
     Double sum = frameEnum.nextElement(); 

     int i; 
     for(i=1; (i < frameSize) && (frameEnum.hasMoreElements()); ++i) { 
      sum += (Double)frameEnum.nextElement(); 
     } 

     return (sum/i); 
    } 
} 
1

El enfoque ingenuo es simplemente el cálculo de un promedio por TimeInterval que corresponde a un píxel.

http://commons.wikimedia.org/wiki/File:Euro_exchange_rate_to_AUD.svg

Esto no muestra flunctuations. Sugeriría también calcular la desviación estándar en cada intervalo de tiempo y trazar eso también (esencialmente haciendo que cada píxel sea más alto que un solo píxel). No pude encontrar un ejemplo, pero sé que Gnuplot puede hacerlo (pero no está escrito en Java).

+0

La solución _really_ ingenua sería simplemente tomar cada valor N-ésimo. Espero tomar, p. cada valor 100 en un conjunto de datos de 100k aún proporcionaría una muy buena imagen del historial del valor medido y ningún otro método podría tocarlo en términos de rendimiento. –

+0

cierto. Parece que la velocidad es más importante que la precisión del píxel. –

+0

Esta respuesta parece extraña ... familiar. ;] – CPerkins

Cuestiones relacionadas