27.3 C
Colombia
martes, julio 8, 2025

Uniones ASOF, regresión OLS y resumidores adicionales



Uniones ASOF, regresión OLS y resumidores adicionales

Desde sparklyr.flinta sparklyr extensión para aprovechar Pedernal funcionalidades de sequence temporales a través sparklyrperiod introducido En septiembre, le hemos realizado una serie de mejoras y lo hemos enviado con éxito. sparklyr.flint 0,2 a CRAN.

En esta publicación de weblog, destacamos las siguientes características nuevas y mejoras de sparklyr.flint 0.2:

Se une a ASOF

Para aquellos que no están familiarizados con el término, las uniones ASOF son operaciones de unión temporal basadas en coincidencias inexactas de marcas de tiempo. Dentro del contexto de chispa apacheuna operación de unión, en términos generales, hace coincidir registros de dos marcos de datos (llamémoslos left y proper) basándose en algunos criterios. Una unión temporal implica registros coincidentes en left y proper basado en marcas de tiempo, y con coincidencias inexactas de marcas de tiempo permitidas, generalmente es útil unirse left y proper a lo largo de una de las siguientes direcciones temporales:

  1. Mirando hacia atrás: si un registro de left tiene marca de tiempo tluego se compara con los de proper tener la marca de tiempo más reciente menor o igual a t.
  2. Mirando hacia el futuro: si un registro de left tiene marca de tiempo t, luego se compara con los de proper tener la marca de tiempo más pequeña mayor o igual que (o alternativamente, estrictamente mayor que) t.

Sin embargo, muchas veces no es útil considerar dos marcas de tiempo como “coincidentes” si están demasiado separadas. Por lo tanto, una restricción adicional sobre la cantidad máxima de tiempo para mirar hacia atrás o hacia adelante también suele ser parte de una operación de unión ASOF.

En sparklyr.flint 0.2, todas las funcionalidades de unión ASOF de Flint son accesibles a través del asof_join() método. Por ejemplo, dados 2 RDD de serie temporal left y proper:

library(sparklyr)
library(sparklyr.flint)

sc <- spark_connect(grasp = "native")
left <- copy_to(sc, tibble::tibble(t = seq(10), u = seq(10))) %>%
  from_sdf(is_sorted = TRUE, time_unit = "SECONDS", time_column = "t")
proper <- copy_to(sc, tibble::tibble(t = seq(10) + 1, v = seq(10) + 1L)) %>%
  from_sdf(is_sorted = TRUE, time_unit = "SECONDS", time_column = "t")

A continuación se imprime el resultado de hacer coincidir cada registro de left con los registros más recientes de proper que están como máximo 1 segundo detrás.

print(asof_join(left, proper, tol = "1s", route = ">=") %>% to_sdf())

## # Supply: spark<?> [?? x 3]
##    time                    u     v
##    <dttm>              <int> <int>
##  1 1970-01-01 00:00:01     1    NA
##  2 1970-01-01 00:00:02     2     2
##  3 1970-01-01 00:00:03     3     3
##  4 1970-01-01 00:00:04     4     4
##  5 1970-01-01 00:00:05     5     5
##  6 1970-01-01 00:00:06     6     6
##  7 1970-01-01 00:00:07     7     7
##  8 1970-01-01 00:00:08     8     8
##  9 1970-01-01 00:00:09     9     9
## 10 1970-01-01 00:00:10    10    10

Mientras que si cambiamos la dirección temporal a “<”, entonces cada registro de left se comparará con cualquier registro de proper eso es estrictamente en el futuro y está como máximo 1 segundo por delante del récord precise de left:

print(asof_join(left, proper, tol = "1s", route = "<") %>% to_sdf())

## # Supply: spark<?> [?? x 3]
##    time                    u     v
##    <dttm>              <int> <int>
##  1 1970-01-01 00:00:01     1     2
##  2 1970-01-01 00:00:02     2     3
##  3 1970-01-01 00:00:03     3     4
##  4 1970-01-01 00:00:04     4     5
##  5 1970-01-01 00:00:05     5     6
##  6 1970-01-01 00:00:06     6     7
##  7 1970-01-01 00:00:07     7     8
##  8 1970-01-01 00:00:08     8     9
##  9 1970-01-01 00:00:09     9    10
## 10 1970-01-01 00:00:10    10    11

Tenga en cuenta que, independientemente de la dirección temporal seleccionada, siempre se realiza una unión externa izquierda (es decir, todos los valores de marca de tiempo y u valores de left desde arriba siempre estará presente en la salida, y el v La columna en la salida contendrá NA siempre que no exista registro de proper que cumple los criterios de coincidencia).

Regresión MCO

Quizás se pregunte si la versión de esta funcionalidad en Flint es más o menos idéntica a lm() en R. Resulta que tiene mucho más que ofrecer que lm() hace. Una regresión OLS en Flint calculará métricas útiles como Criterio de información de Akaike y Criterio de información bayesianolos cuales son útiles para propósitos de selección de modelos, y Flint paraleliza los cálculos de ambos para utilizar completamente la potencia computacional disponible en un clúster Spark. Además, Flint admite ignorar regresores que sean constantes o casi constantes, lo que resulta útil cuando se incluye un término de intersección. Para ver por qué es así, necesitamos examinar brevemente el objetivo de la regresión MCO, que es encontrar algún vector columna de coeficientes. (mathbf{beta}) que minimiza (|mathbf{y} – mathbf{X} mathbf{beta}|^2)dónde (mathbf{y}) es el vector columna de las variables de respuesta, y (mathbf{X}) es una matriz que consta de columnas de regresores más una columna entera de (1)s representa los términos de intersección. La solución a este problema es (mathbf{beta} = (mathbf{X}^intercalmathbf{X})^{-1}mathbf{X}^intercalmathbf{y})asumiendo la matriz de Gram (mathbf{X}^intercalmathbf{X}) es no singular. Sin embargo, si (mathbf{X}) contiene una columna de todos (1)s de términos de intercepción, y otra columna formada por un regresor que es constante (o casi), luego columnas de (mathbf{X}) será linealmente dependiente (o casi) y (mathbf{X}^intercalmathbf{X}) será singular (o casi), lo que presenta un problema en cuanto a cálculo. Sin embargo, si un regresor es constante, entonces esencialmente juega el mismo papel que los términos del intercepto. Así que simplemente excluyendo tal regresor constante en (mathbf{X}) resuelve el problema. Además, hablando de invertir la matriz de Gram, los lectores que recuerden el concepto de “número de condición” del análisis numérico deben estar pensando para sí mismos cómo calcular (mathbf{beta} = (mathbf{X}^intercalmathbf{X})^{-1}mathbf{X}^intercalmathbf{y}) podría ser numéricamente inestable si (mathbf{X}^intercalmathbf{X}) tiene un número de condición grande. Esta es la razón por la que Flint también genera el número de condición de la matriz de Gram en el resultado de la regresión MCO, de modo que se pueda verificar que el problema de minimización cuadrática subyacente que se está resolviendo esté bien condicionado.

Entonces, para resumir, la funcionalidad de regresión OLS implementada en Flint no solo genera la solución al problema, sino que también calcula métricas útiles que ayudan a los científicos de datos a evaluar la cordura y la calidad predictiva del modelo resultante.

Para ver la regresión MCO en acción con sparklyr.flintse puede ejecutar el siguiente ejemplo:

mtcars_sdf <- copy_to(sc, mtcars, overwrite = TRUE) %>%
  dplyr::mutate(time = 0L)
mtcars_ts <- from_sdf(mtcars_sdf, is_sorted = TRUE, time_unit = "SECONDS")
mannequin <- ols_regression(mtcars_ts, mpg ~ hp + wt) %>% to_sdf()

print(mannequin %>% dplyr::choose(akaikeIC, bayesIC, cond))

## # Supply: spark<?> [?? x 3]
##   akaikeIC bayesIC    cond
##      <dbl>   <dbl>   <dbl>
## 1     155.    159. 345403.

# ^ output says situation variety of the Gram matrix was inside purpose

y obtener (mathbf{beta})el vector de coeficientes óptimos, con lo siguiente:

print(mannequin %>% dplyr::pull(beta))

## [[1]]
## [1] -0.03177295 -3.87783074

Resumidores adicionales

La EWMA (media móvil ponderada exponencial), la vida media de la EMA y los resúmenes de momentos estandarizados (es decir, asimetría y curtosis), junto con algunos otros que faltaban en sparklyr.flint 0.1 ahora son totalmente compatibles en sparklyr.flint 0.2.

Mejor integración con sparklyr

Mientras sparklyr.flint 0.1 incluyó un acquire() método para exportar datos de un RDD de serie temporal de Flint a un marco de datos R, no tenía un método related para extraer el marco de datos Spark subyacente de un RDD de serie temporal de Flint. Esto fue claramente un descuido. En sparklyr.flint 0.2, se puede llamar to_sdf() en un RDD de serie temporal para recuperar un marco de datos Spark que se pueda utilizar en sparklyr (por ejemplo, como se muestra en mannequin %>% to_sdf() %>% dplyr::choose(...) ejemplos de arriba). También se puede acceder a la referencia del objeto JVM del marco de datos de Spark subyacente llamando spark_dataframe() en un RDD de serie temporal de Flint (esto suele ser innecesario en la gran mayoría de los sparklyr casos de uso).

Conclusión

Hemos presentado una serie de novedades y mejoras introducidas en sparklyr.flint 0.2 y profundicé en algunos de ellos en esta publicación de weblog. Esperamos que estés tan entusiasmado con ellos como nosotros.

¡Gracias por leer!

Reconocimiento

El autor quisiera agradecer a Mara (@batpigandme), Sigrid (@skeydan), y Javier (@javierluraschi) por sus fantásticos aportes editoriales en esta publicación de weblog.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles