24.8 C
Colombia
lunes, julio 7, 2025

¡Nuevas fuentes de datos y capacidades de spark_apply(), mejores interfaces para extensiones sparklyr y más!


Sparklyr 1.7 ya está disponible en grua!

Para instalar sparklyr 1.7 de CRAN, ejecutar

En esta publicación de weblog, deseamos presentar los siguientes aspectos destacados del sparklyr Versión 1.7:

Fuentes de imágenes y datos binarios

Como motor de análisis unificado para el procesamiento de datos a gran escala, chispa apache
es conocido por su capacidad para abordar desafíos asociados con el volumen, la velocidad y, por último, pero no menos importante, la variedad de massive knowledge. Por lo tanto, no sorprende ver que, en respuesta a los avances recientes en los marcos de aprendizaje profundo, Apache Spark haya introducido soporte integrado para
fuentes de datos de imagen
y fuentes de datos binarios (en las versiones 2.4 y 3.0, respectivamente). Las interfaces R correspondientes para ambas fuentes de datos, es decir,
spark_read_image() y
spark_read_binary()fueron enviados recientemente como parte de sparklyr 1.7.

La utilidad de las funcionalidades de fuentes de datos como spark_read_image() Quizás se ilustra mejor con una demostración rápida a continuación, donde spark_read_image()a través del estándar Apache Spark
ImageSchemaayuda a conectar entradas de imágenes sin procesar a un clasificador y un extractor de características sofisticados, formando una poderosa aplicación Spark para clasificaciones de imágenes.

la demostración

Foto por Daniel Tuttle en
desempaquetar

En esta demostración, construiremos una canalización Spark ML escalable capaz de clasificar imágenes de perros y gatos de manera precisa y eficiente, utilizando spark_read_image() y una pink neuronal convolucional previamente entrenada cuyo nombre en código Inception (Szegedy et al. (2015)).

El primer paso para crear una demostración con máxima portabilidad y repetibilidad es crear una
extensión brillante que logra lo siguiente:

Una implementación de referencia de tal sparklyr La extensión se puede encontrar en
aquí.

El segundo paso, por supuesto, es hacer uso de lo mencionado anteriormente. sparklyr extensión para realizar algunas funciones de ingeniería. Veremos características de muy alto nivel que se extraen de forma inteligente de cada imagen de gato/perro en función de lo que muestra la imagen prediseñada. Inception-La pink neuronal convolucional V3 ya ha aprendido al clasificar una colección mucho más amplia de imágenes:

library(sparklyr)
library(sparklyr.deeperer)

# NOTE: the proper spark_home path to make use of relies on the configuration of the
# Spark cluster you might be working with.
spark_home <- "/usr/lib/spark"
sc <- spark_connect(grasp = "yarn", spark_home = spark_home)

data_dir <- copy_images_to_hdfs()

# extract options from train- and test-data
image_data <- listing()
for (x in c("prepare", "check")) {
  # import
  image_data[[x]] <- c("canine", "cats") %>%
    lapply(
      operate(label) {
        numeric_label <- ifelse(similar(label, "canine"), 1L, 0L)
        spark_read_image(
          sc, dir = file.path(data_dir, x, label, fsep = "/")
        ) %>%
          dplyr::mutate(label = numeric_label)
      }
    ) %>%
      do.name(sdf_bind_rows, .)

  dl_featurizer <- invoke_new(
    sc,
    "com.databricks.sparkdl.DeepImageFeaturizer",
    random_string("dl_featurizer") # uid
  ) %>%
    invoke("setModelName", "InceptionV3") %>%
    invoke("setInputCol", "picture") %>%
    invoke("setOutputCol", "options")
  image_data[[x]] <-
    dl_featurizer %>%
    invoke("remodel", spark_dataframe(image_data[[x]])) %>%
    sdf_register()
}

Tercer paso: equipados con funciones que resumen bien el contenido de cada imagen, podemos construir un canal Spark ML que reconozca perros y gatos usando solo regresión logística.

label_col <- "label"
prediction_col <- "prediction"
pipeline <- ml_pipeline(sc) %>%
  ml_logistic_regression(
    features_col = "options",
    label_col = label_col,
    prediction_col = prediction_col
  )
mannequin <- pipeline %>% ml_fit(image_data$prepare)

Finalmente, podemos evaluar la precisión de este modelo en las imágenes de prueba:

predictions <- mannequin %>%
  ml_transform(image_data$check) %>%
  dplyr::compute()

cat("Predictions vs. labels:n")
predictions %>%
  dplyr::choose(!!label_col, !!prediction_col) %>%
  print(n = sdf_nrow(predictions))

cat("nAccuracy of predictions:n")
predictions %>%
  ml_multiclass_classification_evaluator(
    label_col = label_col,
    prediction_col = prediction_col,
    metric_name = "accuracy"
  ) %>%
    print()
## Predictions vs. labels:
## # Supply: spark<?> [?? x 2]
##    label prediction
##    <int>      <dbl>
##  1     1          1
##  2     1          1
##  3     1          1
##  4     1          1
##  5     1          1
##  6     1          1
##  7     1          1
##  8     1          1
##  9     1          1
## 10     1          1
## 11     0          0
## 12     0          0
## 13     0          0
## 14     0          0
## 15     0          0
## 16     0          0
## 17     0          0
## 18     0          0
## 19     0          0
## 20     0          0
##
## Accuracy of predictions:
## [1] 1

Nuevo spark_apply() capacidades

Optimizaciones y serializadores personalizados

Muchos sparklyr usuarios que han intentado ejecutar
spark_apply() o
doSpark para paralelizar los cálculos de R entre los trabajadores de Spark probablemente se hayan encontrado con algunos desafíos derivados de la serialización de los cierres de R. En algunos escenarios, el tamaño serializado del cierre R puede volverse demasiado grande, a menudo debido al tamaño del entorno R envolvente requerido por el cierre. En otros escenarios, la serialización en sí puede llevar demasiado tiempo, lo que compensa parcialmente la ganancia de rendimiento de la paralelización. Recientemente, se realizaron múltiples optimizaciones sparklyr para abordar esos desafíos. Una de las optimizaciones fue hacer un buen uso de la
variable de difusión
construya en Apache Spark para reducir la sobrecarga de distribuir estados de tareas compartidos e inmutables entre todos los trabajadores de Spark. En sparklyr 1.7, también hay soporte para personalización spark_apply() serializadores, que ofrece un management más detallado sobre el equilibrio entre velocidad y nivel de compresión de los algoritmos de serialización. Por ejemplo, se puede especificar

choices(sparklyr.spark_apply.serializer = "qs")

,

que aplicará las opciones predeterminadas de qs::qserialize() para lograr un alto nivel de compresión, o

choices(sparklyr.spark_apply.serializer = operate(x) qs::qserialize(x, preset = "quick"))
choices(sparklyr.spark_apply.deserializer = operate(x) qs::qdeserialize(x))

,

que apuntará a una velocidad de serialización más rápida con menos compresión.

Inferir dependencias automáticamente

En sparklyr 1.7, spark_apply() también proporciona el experimento
auto_deps = TRUE opción. Con auto_deps activado, spark_apply() examinará el cierre de R que se aplica, inferirá la lista de paquetes de R requeridos y solo copiará los paquetes de R requeridos y sus dependencias transitivas a los trabajadores de Spark. En muchos escenarios, el auto_deps = TRUE La opción será una alternativa significativamente mejor en comparación con la predeterminada. packages = TRUE
comportamiento, que es enviar todo dentro .libPaths() a los nodos trabajadores de Spark, o el avanzado packages = <bundle config> opción, que requiere que los usuarios proporcionen la lista de paquetes R requeridos o creen manualmente un
spark_apply() manojo.

Mejor integración con extensiones sparklyr

Se hizo un esfuerzo sustancial sparklyr 1.7 para hacer la vida más fácil a sparklyr
autores de extensiones. La experiencia sugiere dos áreas en las que cualquier sparklyr La extensión puede pasar por un camino friccional y no sencillo integrándose con
sparklyr son los siguientes:

Ampliaremos los avances recientes en ambas áreas en las subsecciones siguientes.

Personalizando el dbplyr Entorno de traducción SQL

sparklyr las extensiones ahora se pueden personalizar sparklyr‘s dbplyr Traducciones SQL a través del
spark_dependency()

especificación devuelta desde spark_dependencies() devoluciones de llamada. Este tipo de flexibilidad resulta útil, por ejemplo, en escenarios en los que un
sparklyr La extensión necesita insertar conversiones de tipo para entradas a UDF de Spark personalizadas. Podemos encontrar un ejemplo concreto de esto en
sparklyr.sedonaa sparklyr extensión para facilitar los análisis geoespaciales utilizando
apache sedona. UDF geoespaciales compatibles con Apache Sedona, como ST_Point() y ST_PolygonFromEnvelope() requieren que todas las entradas sean
DECIMAL(24, 20) cantidades en lugar de DOUBLEs. Sin ninguna personalización para
sparklyr‘s dbplyr Variante SQL, la única forma para un dplyr
consulta que involucra ST_Point() trabajar realmente en sparklyr sería implementar explícitamente cualquier conversión de tipo necesaria para la consulta utilizando dplyr::sql()p.ej,

my_geospatial_sdf <- my_geospatial_sdf %>%
  dplyr::mutate(
    x = dplyr::sql("CAST(`x` AS DECIMAL(24, 20))"),
    y = dplyr::sql("CAST(`y` AS DECIMAL(24, 20))")
  ) %>%
  dplyr::mutate(pt = ST_Point(x, y))

.

Esto sería, hasta cierto punto, antitético dplyrEl objetivo de liberar a los usuarios de R de tener que deletrear laboriosamente consultas SQL. Mientras que al personalizar sparklyr‘s dplyr Traducciones SQL (tal como se implementan en
aquí
y
aquí
), sparklyr.sedona permite a los usuarios simplemente escribir

my_geospatial_sdf <- my_geospatial_sdf %>% dplyr::mutate(pt = ST_Point(x, y))

en su lugar, y las conversiones de tipo Spark SQL requeridas se generan automáticamente.

Interfaz mejorada para invocar funciones Java/Scala

En sparklyr 1.7, la interfaz R para invocaciones de Java/Scala experimentó una serie de mejoras.

Con versiones anteriores de sparklyrmuchos sparklyr Los autores de extensiones tendrían problemas al intentar invocar funciones Java/Scala que acepten una
Array[T] como uno de sus parámetros, donde T ¿Hay algún tipo vinculado más específico que java.lang.Object / AnyRef. Esto se debía a que cualquier conjunto de objetos que pasara a través sparklyrLa interfaz de invocación Java/Scala se interpretará simplemente como una matriz de java.lang.Objects en ausencia de información de tipo adicional. Por esta razón, una función auxiliar
jarray() fue implementado como parte de sparklyr 1.7 como una forma de superar el problema antes mencionado. Por ejemplo, ejecutando

sc <- spark_connect(...)

arr <- jarray(
  sc,
  seq(5) %>% lapply(operate(x) invoke_new(sc, "MyClass", x)),
  element_type = "MyClass"
)

asignará a arr a referencia a un Array[MyClass] de longitud 5, en lugar de un Array[AnyRef]. Después, arr se vuelve adecuado para ser pasado como parámetro a funciones que aceptan solo Array[MyClass]s como entradas. Anteriormente, algunas posibles soluciones a este problema sparklyr La limitación incluía cambiar las firmas de funciones para aceptar. Array[AnyRef]s en lugar de Array[MyClass]s, o implementar una versión “envuelta” de cada función que acepte Array[AnyRef]
entradas y convertirlas a Array[MyClass] antes de la invocación actual. Ninguna de estas soluciones fue una solución perfect al problema.

Otro obstáculo comparable que se abordó en sparklyr 1.7 también implica parámetros de función que deben ser números de punto flotante de precisión easy o matrices de números de punto flotante de precisión easy. Para esos escenarios,
jfloat() y
jfloat_array()

son las funciones auxiliares que permiten pasar cantidades numéricas en R a
sparklyrLa interfaz de invocación Java/Scala como parámetros con los tipos deseados.

Además, aunque las versiones anteriores de sparklyr no se pudieron serializar los parámetros con NaN valores correctamente, sparklyr 1.7 conservas NaNs como se esperaba en su interfaz de invocación Java/Scala.

Otras noticias interesantes

Hay muchas otras características nuevas, mejoras y correcciones de errores realizadas en
sparklyr 1.7, todos enumerados en el
NOTICIAS.md
archivo de la sparklyr repositorio y documentado en sparklyr‘s
referencia HTML páginas. En aras de la brevedad, no los describiremos todos con gran detalle en esta publicación de weblog.

Reconocimiento

En orden cronológico, nos gustaría agradecer a las siguientes personas que fueron autores o coautores de solicitudes de extracción que formaron parte del sparklyr Versión 1.7:

También estamos muy agradecidos a todos los que enviaron solicitudes de funciones o informes de errores, muchos de los cuales han sido de gran ayuda para dar forma. sparklyr en lo que es hoy.

Además, el autor de esta publicación de weblog está en deuda con
@skeydan por sus increíbles sugerencias editoriales. Sin sus conocimientos sobre la buena escritura y la narración, exposiciones como ésta habrían sido menos legibles.

Si deseas aprender más sobre sparklyrrecomendamos visitar
sparklyr.ai, spark.rstudio.comy también leyendo algunos anteriores sparklyr publicar publicaciones como
brillante 1.6
y
brillante 1.5.

Eso es todo. ¡Gracias por leer!

Ladrillos de datos, Inc. 2019. Canalizaciones de aprendizaje profundo para Apache Spark (versión 1.5.0). https://spark-packages.org/bundle/databricks/spark-deep-learning.

Elson, Jeremy, John (JD) Douceur, Jon Howell y Jared Saul. 2007. “Asirra: un CAPTCHA que explota la categorización guide de imágenes alineada con intereses”. En Actas de la 14ª Conferencia ACM sobre seguridad informática y de las comunicaciones (CCS)Actas de la 14ª Conferencia ACM sobre seguridad informática y de las comunicaciones (CCS). Asociación de Maquinaria de Computación, Inc. https://www.microsoft.com/en-us/analysis/publication/asirra-a-captcha-that-exploits-interest-aligned-manual-image-categorization/.

Szegedy, Christian, Wei Liu, Yangqing Jia, Pierre Sermanet, Scott Reed, Dragomir Anguelov, Dumitru Erhan, Vincent Vanhoucke y Andrew Rabinovich. 2015. “Profundizando con las convoluciones”. En Visión por computadora y reconocimiento de patrones (CVPR). http://arxiv.org/abs/1409.4842.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles