You are on page 1of 69

UNIVERSIDAD UTE

SISTEMAS AVANZADOS DE BASES DE DATOS

Carrera: Ingeniería Informática Y Ciencias De La Computación Fecha: 23/11/2018

Integrantes:

 Pamela Guamán  Fausto Males


 Andrés Guerra  Mishel Mena
 Bryan Hidalgo  Milton Navarro
 Antonio Iglesias  Juan Carlos Robayo
 Nicolás Jiménez  Bryan Yandun
 Roberto Malavé

Ruta 66 en tiempo real: vinculación de fuentes de datos externas


La mayoría de los datos en la naturaleza son dinámicos y tienen un ciclo de vida firme: se
crean, ingieren, analizan y luego se eliminan o almacenan en frío.

Ciudades más inteligentes, un planeta más inteligente, todo más inteligente

El impulso hacia la urbanización está estresando la infraestructura del planeta, desde el


transporte hasta la electricidad y los servicios públicos, que implica instrumentar cada aspecto
del entorno urbano para lograr una utilización óptima de los recursos, el intercambio, la
planificación de la capacidad y el monitoreo.

Hacerlo implica usar información de señales de tráfico, inductores de bucle, cámaras de CCTV y
ecosistema completo de sensores, recolectores de datos, analizadores y activadores, sistemas a
bordo para predecir la congestión o usar datos de medidores inteligentes para acoplar
estrechamente la oferta y la demanda en la generación de electricidad.

Uno de los ingredientes clave de todo más inteligente es una economía de intercambio en el
que una pluralidad de jugadores interactúa, colaboran y comparten un recurso en particular.

Los ejemplos incluyen aplicaciones para compartir viajes como Uber, alojamiento compartido a
través de Airbnb y comercio electrónico P2P habilitado por Etsy como Etsy.

El conjunto de datos de alimentación de la estación es una transmisión JSON en vivo del estado
de cada estación de bicicletas en la ciudad de Nueva York. Este estado incluye información sobre
si la estación es funcional y el número de bicicletas gratuitas.
UNIVERSIDAD UTE

ReceiverInputDStream

Un lote típico de Spark Streaming comienza con la creación de un InputDStream y se detiene


con un efecto secundario.

InputStream

 ConstantInputDStream: repite el mismo RDD en cada lote. Sólo se utiliza para la


prueba.
 FileInputDStream: Genera RDD desde archivos presentes en un sistema de archivos.
Los ejemplos incluyen textFileStream.
 datos entrantes.
 QueueInputDStream: convierte datos de una cola de Scala a DStream.
 DirectKafkaInputDStream: representa un flujo de KafkaRDD en el que cada RDD
corresponde a una partición Kafka.

Un InputDStream estándar expone los métodos start () y stop () y hereda un método compute
() de DStream. El método compute () se encarga de devolver nuevos RDD en cada lote. El servicio
/ hilo para este método se ejecuta en el nodo del controlador.

Sockets

Los sockets son un mecanismo que nos permite establecer un enlace entre dos programas que
se ejecutan independientes el uno del otro. Java por medio de la librería java.net nos provee dos
clases: Socket para implementar la conexión desde el lado del cliente y ServerSocket que nos
permitirá manipular la conexión desde el lado del servidor.

Ejemplo

Socket Cliente
UNIVERSIDAD UTE

Socket Servidor
UNIVERSIDAD UTE

MQTT

El transporte de telemetría de la cola de mensajes (MQTT (Message Queue Telemetry


Transport), por sus siglas en inglés) es un ejemplo de una cola de mensajes tradicional de
pub/sub-based en el protocolo en el que los productores publican mensajes sobre un tema
mientras los consumidores leen.

Un servidor bróker maneja almacenamiento, relé, y arbitraje. Dirigido a la comunicación


máquina a máquina, MQTT ha sido diseñado para IoT, lo que lo hace liviano, de baja latencia y
tolerante al retardo.

Soporta todo el espectro de opciones de garantía de mensajes: como máximo una vez, al menos
una vez y exactamente una vez.

Una amplia gama de los intermediarios de mensajes, incluidos ActiveMQ, IBM Websphere MQ,
RabbitMQ y Mosquitto, admiten MQTT.

El conector MQTT en Spark Streaming se implementa en una biblioteca separada. Utiliza el


Eclipse Paho Cliente MQTT.

MQTT es realmente útil para casos de uso que implican diversidad y pluralidad en consumidores
y temas.

Por ejemplo los datos de IoT que deben ser particionados en temas basados en el tipo de sensor
y deben ser consumidos por varios sistemas de flujo descendente, como una aplicación de
procesamiento en tiempo real y un almacén de datos para el almacenamiento a largo plazo.

Una clase diferente de aplicaciones requiere el envío de grandes franjas de datos de registro de
una ubicación a otra.

Estos datos generalmente no se dividen semánticamente en temas. En consecuencia, utilizando


una cola de mensajes.

Sistema MQTT como tal es una exageración. Estas aplicaciones están mejor atendidas por los
sistemas de agregación de registros, como Flume, cual es el sistema de destino.

Flume

Flume es un sistema de agregación de registros distribuidos con una arquitectura de flujo de


datos.

Una implementación de Flume consta de uno o más agentes configurados con una topología.
Flume Agent es un proceso JVM que aloja los bloques de construcción básicos de una topología
de Flume, que son la fuente, el canal y el sumidero. Los clientes de Flume envían eventos al
UNIVERSIDAD UTE

origen, que los coloca en lotes en un búfer temporal llamado canal, y desde allí los datos fluyen
a un sumidero que se conecta al destino final de los datos. Un sumidero también puede ser una
fuente de datos de seguimiento para otros agentes de Flume. Los agentes pueden estar
encadenados y tener cada uno múltiples fuentes, canales y sumideros.

Flume es un sistema distribuido que se puede usar para recopilar, agregar y transferir eventos
de transmisión a Hadoop. Viene con muchas fuentes, canales y receptores integrados, por
ejemplo, el canal Kafka y el receptor Avro. Flume se basa en la configuración y tiene
interceptores para realizar transformaciones simples en los datos en vuelo.

Es fácil perder datos usando Flume si no tienes cuidado. Por ejemplo, elegir el canal de memoria
para un alto rendimiento tiene el inconveniente de que los datos se perderán cuando el nodo
del agente se desactive. Un canal de archivos proporcionará durabilidad al precio de una mayor
latencia. Incluso entonces, dado que los datos no se replican en otros nodos, el canal de archivos
solo es tan confiable como los discos subyacentes. Flume ofrece escalabilidad a través de flujos
de abanico de entradas múltiples y abanicos. Para alta disponibilidad (HA), los agentes pueden
escalarse horizontalmente.

Kafka

Kafka es un bus de mensajes distribuido de alto rendimiento que desacopla a los productores
de datos de los consumidores. Los mensajes se organizan en temas, los temas se dividen en
particiones y las particiones se replican en los nodos, denominados intermediarios, en el clúster.
En comparación con Flume, Kafka ofrece una mejor escalabilidad y durabilidad de los mensajes.
Kafka ahora viene en dos versiones: el modelo “clásico” de productor / consumidor, y el nuevo
Kafka-Connect, que proporciona conectores configurables (fuentes / sumideros) para almacenes
de datos externos.

Kafka se puede utilizar para el procesamiento de eventos y la integración entre componentes


de grandes sistemas de software. Los picos de datos y la contrapresión (productor rápido,
consumidor lento) se manejan de forma inmediata. Además, Kafka se envía con Kafka Streams,
que se puede usar para el procesamiento de secuencias simples sin la necesidad de un clúster
separado como Apache Spark o Apache Flink.

Debido a que los mensajes se conservan en el disco y se replican dentro del clúster, los
escenarios de pérdida de datos son menos comunes que con Flume. Dicho esto, la codificación
personalizada a menudo es necesaria para los productores / fuentes y los consumidores /
receptores, ya sea utilizando clientes Kafka o mediante la API de Connect. Al igual que con
Flume, hay limitaciones en el tamaño del mensaje. Finalmente, para poder comunicarse, tanto
UNIVERSIDAD UTE

los productores como los consumidores de Kafka tienen que ponerse de acuerdo sobre el
protocolo, el formato y el esquema, lo que puede ser problemático en algunos casos.

Twitter

Twitter se ha convertido en una de las redes sociales más grande del mundo, tiene más de 300
millones de usuarios activos mensuales que envían 500 millones de tweets por día. Twitter se
ha convertido en un gran depósito de información de interés comercial. Twitter tiene una API
pública que permite a los usuarios obtener acceso a la filtración de información. Twitter4J es
utilizado por el conector Spark Streaming.

TwitterAuth es un objeto de autorización de Twitter4J con credenciales de seguridad y los filtros


son una secuencia de cuerdas para emparejar contra los filtros de twitter, un ejemplo serio que
la aplicación busca un objetivo en una ciudad de tweets relacionados y los procesa y los imprime
con un conteo de salida estándar y se archivan.

Para acceder a la API de twitter, primero se debe proporcionar las credenciales. Las credenciales
pasan por un createStream que va junto a una matriz, esta contiene las palabras clave que sirven
de filtro para que puedan coincidir los tweets.

Block Interval

Intervalo de bloque, el número de particiones en el flujo de entrada decide el paralelismo de las


tareas de primer nivel, un flujo de entrada generado al leer datos de HDFS, cada partición
corresponde a un bloque HDFS. La capacidad en un bloque antes de que se registre en el
blockStore.Spark.Streaming.blockInterval el cual tiene un valor predeterminado de 200ms. El
intervalo del bloque y el del lote van de la mano ya que el número de bloques por intervalo se
decide por batchInterval/blockInternal. Para una buena utilización de los recursos, la cantidad
de tareas debe coincidir con la cantidad de núcleos por nodo.

Custom Receiver

El receptor personalizado que se conecta por medio de InputDStream a una fuente de datos
externa debe implementar la interfas de receptor. Este receptor reside en los nodos de trabajo
y está a cargo de ingerir datos externos y escribirlos en el almacen de bloques.

La confiabilidad de un receptor está determinada por el método de almacenamiento que utiliza.


Los receptores no confiables almacen un artículo a la vez cuyo estado puede perderse en caso
de una falla. Los receptores confiables, por otro ámbito almacenan un ArrayBuffer de elementos
a través de una llamada de bloqueo que se devuelve después de un Spark Streaming el cual
recopila todos los elementos. Esto asegura una mayor tolerancia a fallos. El receptor también
UNIVERSIDAD UTE

necesita enviar confirmaciones al remitente de datos, lo que hace que el diseño de un receptor
confiable sea más complicado.

HttpInputDStream

Spark Streaming fuera de la caja no tiene conexión para HTTP. Se mplementa una API receptora

Machine Learning con Spark


Cada vez es más habitual el uso de algoritmos de aprendizaje que permiten dotar
a los programas de la inteligencia suficiente como para predecir, recomendar o
clasificar elementos. Algunos ejemplos de aplicaciones que usan este tipo de
sistemas de recomendación son Netflix o Spotify, que recomiendan películas o
canciones que podrían interesar a los usuarios en función de sus gustos.

Spark MLlib

En general, los algoritmos de Machine Learning se pueden clasificar en dos tipos:

Supervisados: estos algoritmos se entrenan con un conjunto de datos cuyo


resultado ya es conocido. Es decir, el modelo se entrena con datos de los que
ya se conoce la entrada y la salida.

No supervisados: el modelo se entrena con datos de los que todavía no se


conoce el resultado. Es decir, se conoce la entrada, pero no la salida de los
datos.

Spark MLlib aporta algoritmos tanto de aprendizaje supervisado como no


supervisado que ofrecen soluciones a las tres técnicas más utilizadas en el
mundo del Machine Learning:

Clasificación y regresión

Algoritmos supervisados que clasifican o predicen valores:

 Multilayer perceptron classifier


 Decision trees
 Random forest
UNIVERSIDAD UTE

Clusterización

Algoritmos no supervisados que agrupan datos en diferentes clusters en función


de la semejanza entre ellos:

 K-means
 LDA
 GMM

Filtrado colaborativo

Técnicas de recomendación basada en datos de preferencias de los usuarios:

 ALS

Ejemplo de clusterización

Para la implementación me he apoyado en Apache Zeppelin, que permite la


exploración de los datos de una forma más sencilla y proporciona una interfaz
visual con la que mostrar gráficas.

Como datos de entrada utilizados para el entrenamiento del modelo, se ha


utilizado un fichero CSV que contiene información sobre contaminación acústica
recogida en la ciudad de Madrid durante los años 2016 y 2017. Esta es la
información contenida en el conjunto de datos, donde cada fila del fichero CSV
contiene:
UNIVERSIDAD UTE

Dato Contenido del dato


Fecha Fecha de la medida
Ld Nivel sonoro medio a largo plazo ponderado A, determinado a lo
largo de todos los períodos día (de 7 a 19 horas) del mes.
Le Nivel sonoro medio a largo plazo ponderado A, determinado a lo
largo de todos los períodos tarde (de 19 a 23 horas) del mes.
Ln Nivel sonoro medio a largo plazo ponderado A, definido determinado
a lo largo de todos los períodos noche (de 23 a 7 horas) del mes.
LAeq24 Nivel sonoro medio a largo plazo ponderado A, determinado a lo
largo de todos los períodos diarios (24 horas) del mes.

En primer lugar se han leído los datos del fichero, se han limpiado y se ha
transformado a DataFrame:

import org.apache.spark.ml.clustering.KMeans

import org.apache.spark.ml.feature.VectorAssembler

case class AcousticData(date: String, ld: Double, le: Double, ln: Double, lAeq:
Double)

// Create DataFrame from CSV file

val acousticDF = sc.textFile("/home/dgrana/BigData/Acoustic_2016-17.csv")

.filter(x => !(x.contains("Fecha") || x.contains("N/D") || x.split(";").length<5))

.map({

line =>

val row = line.split(";")

AcousticData(

row(0),

row(1).replace(",",".").toDouble,

row(2).replace(",",".").toDouble,

row(3).replace(",",".").toDouble,
UNIVERSIDAD UTE

row(4).replace(",",".").toDouble

}).toDF()

acousticDF.createOrReplaceTempView("ACOUSTIC_DATA")

Una vez obtenido el DataFrame, se entrena el modelo con un algoritmo K-means,


indicando que nos clusterice los datos en cinco clústers diferentes. Además,
creamos una tabla con los resultados de la predicción:

// Asembler to create a features vector

val assemblerKmeans = new


VectorAssembler().setInputCols(Array("ld","le","ln","lAeq"))

.setOutputCol("features")

// Set the features column

val vd = assemblerKmeans.transform(acousticDF)

// Trains a k-means model.

val kmeans = new KMeans().setK(5).setSeed(1L)

val model = kmeans.fit(vd)

// Evaluate clustering by computing Within Set Sum of Squared Errors.

val WSSSE = model.computeCost(vd)

println(s"Within Set Sum of Squared Errors = $WSSSE")

val predictions = model.transform(vd)

predictions.createOrReplaceTempView("ACOUSTIC_DATA_KMEANS")

Por último, se comprueban los resultados obtenidos:

SELECT prediction, COUNT(*) FROM ACOUSTIC_DATA_KMEANS GROUP


BY 1
UNIVERSIDAD UTE

Spark sobresale en los procesos de cálculos iterativo permitiendo que los


procesos escritos en las librerias MLlib se ejecuten rápidamente permitiendo su
uso y tambien sobre todo a nivel industrial.

MLlib proporciona muchos tipos de algoritmos, así como numerosas funciones


de utilidad. ML incluye algoritmos de clasificación, regresión, árboles de decisión,
algoritmos de recomendación, agrupamiento. Entre las utilidades más utilizados
puede incluir las características de las transformaciones, la estandarización y
normalización, funciones estadísticas y álgebra lineal.

Primero que todo cargamos la base de datos

val data =MLUtils.loadLibSVMFile(sc, "data/mllib/sample_libsvm_data.txt")

El conjunto de datos se divide en una parte utilizada para entrenar el modelo


(60%) y otra parte para las prueba (40%).

val splits = data.randomSplit(Array(0.6, 0.4), seed=11L)

val training = splits(0).cache()

val test = splits(1)

Se ejecuta el modelo en la base de datos de prueba.

val model = new LogisticRegressionWithLBFGS()

.setNumClasses(10)&amp;amp;nbsp

.run(training)

Se entrena el algoritmo y se construye el modelo

val predictionAndLabels = test.map {case LabeledPoint(label, features) =>

val prediction = model.predict(features)

(prediction, label)}

De esta forma, se obtiene la métrica del modelo y la precisión del pronóstico.

val metrics = new MulticlassMetrics(predictionAndLabels)

val accuracy = metrics.accuracy


UNIVERSIDAD UTE

println("Accuracy = $accuracy")

Es posible guardar el modelo recién entrenado y volver a cargarlo en la memoria


para su uso posterior.

model.save(sc, "target/tmp/scalaLogisticRegressionWithLBFGSModel")

val sameModel = LogisticRegressionModel.load(sc,

"target/tmp/scalaLogisticRegressionWithLBFGSModel")

Capitulo 7

Spark SQL

La facilidad de uso es una de las razones por las que Spark se hizo popular. Proporciona un
modelo de programación más simple que Hadoop MapReduce para procesar grandes datos. Sin
embargo, la cantidad de personas que dominan los idiomas admitidos por la API principal de
Spark es mucho menor que la cantidad de personas que conocen SQL. SQL es un lenguaje
estándar ANSI / ISO para trabajar con datos. Especifica una interfaz no solo para almacenar,
modificar y recuperar datos, sino también para analizar datos. SQL es un lenguaje declarativo.
Es mucho más fácil de aprender y usar en comparación con los lenguajes de programación de
uso general, como Scala, Java y Python. Sin embargo, es un lenguaje poderoso para trabajar con
datos. Como resultado, SQL se ha convertido en el caballo de batalla para el análisis de datos.
HiveQL es un lenguaje similar al SQL ampliamente utilizado en el mundo Hadoop. Es una de las
interfaces preferidas para Hadoop MapReduce. En lugar de escribir programas Java que utilizan
la API de Hadoop MapReduce de bajo nivel, las personas prefieren usar HiveQL para procesar
datos.

Introducción a Spark SQL

Spark SQL es una librería de Spark que se ejecuta sobre Spark. Este provee un nivel más alto de
abstracción que el núcleo de la API de Spark para procesar datos estructurados. Los datos
estructurados incluyen datos almacenados en una base de datos, un almacén de datos NoSQL,
Parquet, ORC, Avro, JSON, CSV o cualquier otro formato estructurado.

Spark SQL es más que solo proporcionar una interfaz SQL a Spark. Fue diseñado con los objetivos
más amplios de hacer que Spark sea más fácil de usar, aumentar la productividad de los
desarrolladores y hacer que las aplicaciones de Spark se ejecuten más rápido. Spark SQL es más
que solo proporcionar una interfaz SQL a Spark. Fue diseñado con los objetivos más amplios de
hacer que Spark sea más fácil de usar, aumentar la productividad de los desarrolladores y hacer
que las aplicaciones de Spark se ejecuten más rápido.

Spark SQL se puede usar como una biblioteca para desarrollar aplicaciones de procesamiento
de datos en Scala, Java, Python o R. Admite múltiples lenguajes de consulta, incluidos SQL,
HiveQL y consultas integradas de lenguaje. Además, se puede usar para analítica interactiva solo
con SQL / HiveQL. En ambos casos, utiliza internamente la API central de Spark para ejecutar
consultas en un clúster de Spark.
UNIVERSIDAD UTE

Integración con otras librerías de Spark

Spark SQL se puede integrar con otras librerias como Spark Streaming, Spark ML y GraphX.
Puede usarse no solo para el procesamiento interactivo y por lotes de datos históricos, sino
también para el procesamiento de flujos de datos en vivo junto con Spark Streaming. Del mismo
modo, se puede utilizar en aplicaciones de aprendizaje automático con MLlib y Spark ML. Por
ejemplo, Spark SQL se puede utilizar para la ingeniería de características en una aplicación de
aprendizaje automático.

Usabilidad

Spark SQL hace que Spark sea más fácil de usar que la API básica de Spark. Proporciona una API
de nivel superior y una abstracción para procesar datos estructurados. Por ejemplo, la API Spark
SQL proporciona funciones para seleccionar columnas, filtrar filas, agregar columnas, unir
conjuntos de datos y otras tareas analíticas y de procesamiento de datos comunes.

Fuentes de Datos

Spark SQL soporta una variedad de fuentes de datos. Puede utilizarse para procesar datos
almacenados en un archivo, un almacén de datos NoSQL o una base de datos. Un archivo puede
estar en HDFS, S3 o sistema de archivos local. Los formatos de archivo compatibles con Spark
SQL incluyen CSV, JSON, Parquet, ORC y Avro.

Interfaz de Procesamiento de Datos

Spark SQL expone tres interfaces de procesamiento de datos: SQL, HiveQL y consultas integradas
de lenguaje. Traduce las consultas escritas usando cualquiera de estas interfaces en llamadas a
la API del núcleo de Spark.

Interoperabilidad de la Colmena

Spark SQL es compatible con Hive. No solo es compatible con HiveQL, sino que también puede
acceder a metástasis de Hive, SerDes y UDF. Por lo tanto, si tiene una implementación de Hive
existente, puede usar Spark SQL junto con Hive. No es necesario que mueva datos o realice
cambios en su almacén de datos de Hive existente.

Rendimiento

Spark SQL hace que las aplicaciones de procesamiento de datos se ejecuten más rápido
utilizando una combinación de técnicas, que incluyen una E / S de disco reducida,
almacenamiento en caché de columnas en memoria, optimización de consultas y generación de
código.
UNIVERSIDAD UTE

Reducción de E / S de disco

La E / S del disco es lenta. Puede ser un contribuyente importante para consultar el tiempo de
ejecución. Por lo tanto, Spark SQL reduce la E / S del disco siempre que sea posible. Por ejemplo,
dependiendo de la fuente de datos, puede omitir particiones, filas o columnas no necesarias
mientras lee datos.

Particionamiento

Leer un conjunto de datos completo para analizar solo una parte de los datos es ineficiente. Por
ejemplo, una consulta puede tener una cláusula de filtrado que elimina una parte significativa
de los datos antes del procesamiento posterior. Por lo tanto, una gran cantidad de E / S se
desperdicia en datos que nunca son utilizados por una aplicación. Se puede evitar mediante la
partición de un conjunto de datos.

Almacenamiento Columnar

Un conjunto de datos estructurado tiene un formato tabular. Está organizado en filas y


columnas. Un conjunto de datos puede tener un gran número de columnas. Sin embargo, una
aplicación de análisis generalmente procesa solo un pequeño porcentaje de las columnas en un
conjunto de datos. Sin embargo, si los datos se almacenan en un formato de almacenamiento
orientado a filas, todas las columnas deben leerse desde el disco. La lectura de todas las
columnas es un desperdicio y ralentiza una aplicación. Spark SQL admite formatos de
almacenamiento en columnas, como Parquet, que permiten leer solo las columnas que se
utilizan en una consulta.

Almacenamiento en memoria caché en columna

Spark SQL permite que una aplicación almacene datos en caché en un formato de columnas en
memoria desde cualquier fuente de datos. Por ejemplo, puede usar Spark SQL para almacenar
en caché un archivo CSV o Avro en la memoria en un formato de columnas.

Saltar Filas

Si un origen de datos mantiene información estadística sobre un conjunto de datos, Spark SQL
lo aprovecha. Por ejemplo, como se explicó en el Capítulo 1, los formatos de serialización como
Parquet y ORC almacenan los valores mínimos y máximos de cada columna en un grupo de filas
o un trozo de filas. Utilizando esta información, Spark SQL puede omitir la lectura de trozos de
filas.

Predicado Pushdown

Spark SQL también reduce la E / S del disco utilizando empujes de predicados si un origen de
datos lo admite. Por ejemplo, si lee datos de una base de datos relacional utilizando Spark SQL
y luego le aplica alguna operación de filtrado, Spark SQL enviará la operación de filtrado a la base
UNIVERSIDAD UTE

de datos. En lugar de leer una tabla completa y luego ejecutar una operación de filtrado, Spark
SQL le pedirá a la base de datos que ejecute de forma nativa la operación de filtrado. Como las
bases de datos generalmente indexan datos, el filtrado nativo es mucho más rápido que el
filtrado en la capa de aplicación.

Optimización de Consultas

Al igual que en los sistemas de bases de datos, Spark SQL optimiza una consulta antes de
ejecutarla. Genera un plan de consulta física optimizado cuando se le da una consulta para su
ejecución. Viene con un optimizador de consultas llamado Catalyst, que admite optimizaciones
basadas tanto en reglas como en costos. Incluso puede optimizar a través de funciones.

La fase de análisis comienza con un plan lógico no resuelto y genera un plan lógico. Un plan
lógico sin resolver contiene atributos sin resolver. Un atributo no resuelto, por ejemplo, podría
ser una columna cuyo tipo de datos o tabla de origen aún no se conoce. Spark SQL usa reglas y
un catálogo para resolver atributos no vinculados en una expresión de consulta. El objeto de
catálogo Spark SQL rastrea las columnas y tablas en todas las fuentes de datos.

En la fase de optimización lógica, Spark SQL aplica optimizaciones basadas en reglas al plan
lógico generado por la fase de análisis. Las optimizaciones basadas en reglas incluyen el plegado
constante, el empuje del predicado, la poda de proyección, la propagación nula, la simplificación
de expresiones booleanas y otras optimizaciones.

La siguiente fase es la fase de planificación física. En esta fase, Spark SQL selecciona un plan físico
óptimo utilizando un modelo de costo. Toma como entrada el plan lógico optimizado generado
por la fase de optimización lógica. Usando reglas, genera uno o más planes físicos que pueden
ser ejecutados por el motor de ejecución Spark. A continuación, calcula sus costos y selecciona
un plan óptimo para la ejecución. Además, realiza optimizaciones físicas basadas en reglas, como
la canalización de proyecciones o filtros en una operación Spark. También empuja las
operaciones del plan lógico a las fuentes de datos que admiten el empuje de predicado o
proyección. Spark SQL genera planes físicos optimizados incluso para planes lógicos ineficientes.

La última fase es la fase de generación de código, donde Spark SQL compila partes de una
consulta directamente al código de bytes de Java. Utiliza una función de lenguaje Scala especial
para transformar un árbol que representa una expresión SQL en un AST (árbol de sintaxis
abstracta) de Scala, que se alimenta al compilador de Scala en tiempo de ejecución para generar
el bytecode. Por lo tanto, evita el uso del analizador Scala en tiempo de ejecución. Esto acelera
la ejecución de consultas. El código generado generalmente funciona tan rápido o más rápido
que el programa Scala o Java sintonizado a mano.

Aplicaciones

Con su interfaz unificada fácil de usar, su motor de ejecución de alto rendimiento y el soporte
para una variedad de fuentes de datos, Spark SQL puede usarse para una variedad de tareas de
análisis y procesamiento de datos. El análisis interactivo de datos es solo una aplicación de Spark
SQL. En esta sección se analizan algunas de las otras aplicaciones comunes de Spark SQL.

ETL (Extraer Transformar Cargar)


UNIVERSIDAD UTE

ETL es el proceso de leer datos de una o más fuentes, aplicar alguna transformación en los datos
y escribirlos en otra fuente de datos. Conceptualmente, consta de tres pasos: extraer,
transformar y cargar. Estos pasos no necesitan ser secuenciales; una aplicación no tiene que
extraer todos los datos antes de moverla al paso de transformación. Una vez que ha extraído
una parte de los datos, puede ejecutar los tres pasos en paralelo. El paso de extracción implica
la lectura de datos de uno o más sistemas operativos. La fuente de datos podría ser una base de
datos, API o un archivo. La base de datos de origen puede ser una base de datos relacional o un
almacén de datos NoSQL. Un archivo puede estar en CSV, JSON, XML, Parquet, ORC, Avro,
Protocol Buffers o algún otro formato. El paso de transformación consiste en limpiar y modificar
los datos de origen utilizando algunas reglas. Por ejemplo, las filas con datos no válidos pueden
eliminarse o las columnas con valores nulos pueden completarse con algún valor. Las
transformaciones pueden incluir, concatenar dos columnas, dividir una columna en múltiples
columnas, codificar una columna, traducir una columna de una codificación a una codificación
diferente, o aplicar alguna otra transformación para preparar los datos para el sistema de
destino. El paso de carga escribe los datos en un origen de datos de destino. El destino puede
ser una base de datos o un archivo. En general, ETL se utiliza para el almacenamiento de datos.
Los datos se recopilan de varios sistemas operativos diferentes, se limpian, se transforman y se
almacenan en un almacén de datos. Sin embargo, ETL no es exclusivo del almacenamiento de
datos. Por ejemplo, se puede usar para permitir el intercambio de datos entre dos sistemas
dispares. Se puede utilizar para convertir datos de un formato a otro. Del mismo modo, la
migración de datos de un sistema heredado a un nuevo sistema es un proceso ETL.

Virtualización de datos

Spark SQL proporciona una abstracción unificada para procesar datos de una variedad de
fuentes de datos. Se puede usar para procesar o analizar datos de cualquier fuente de datos
compatible utilizando SQL, HiveQL o consultas integradas de lenguaje escritas en Scala, Java,
Python o R.

Motor de consulta SQL distribuido JDBC / ODBC

Como se mencionó anteriormente, Spark SQL se puede utilizar de dos maneras. En primer lugar,
puede ser utilizado como una biblioteca. En este modo, las tareas de procesamiento de datos se
pueden expresar como consultas integradas de SQL, HiveQL o lenguaje dentro de una aplicación
Scala, Java, Python o R. En segundo lugar, Spark SQL se puede utilizar como un motor de consulta
de SQL distribuido. Viene preempaquetado con un servidor Thrift / JDBC / ODBC. Una aplicación
cliente puede conectarse a este servidor y enviar consultas de SQL / HiveQL utilizando la interfaz
de Thrift, JDBC u ODBC.

Almacenamiento de datos

Un almacén de datos convencional es esencialmente una base de datos que se utiliza para
almacenar y analizar grandes cantidades de datos. Consta de tres componentes estrechamente
integrados: tablas de datos, tablas del sistema y un motor de consulta SQL. Las tablas de datos,
como su nombre lo indica, almacenan los datos del usuario. Las tablas del sistema almacenan
metadatos sobre los datos en las tablas de datos. Tanto los datos como las tablas del sistema se
UNIVERSIDAD UTE

almacenan como archivos utilizando el sistema de archivos del sistema operativo subyacente. El
motor de consulta SQL proporciona una interfaz SQL para almacenar y analizar los datos en las
tablas de datos. Los tres componentes generalmente se empaquetan juntos como un software
o dispositivo propietario.

Interfaz de programación de aplicaciones (API)

La biblioteca Spark SQL proporciona una interfaz de programación de aplicaciones (API) en varios
idiomas. Al momento de escribir este libro, admite Scala, Java, Python y R. También le permite
incrustar SQL / HiveQL dentro de su aplicación. Incluso puede ir y venir entre SQL / HiveQL y la
API del idioma nativo.

Abstracciones clave

La API Spark SQL consta de tres abstracciones clave: SQLContext, HiveContext y DataFrame. Una
aplicación Spark SQL procesa datos usando estas abstracciones.

SQLContext

SQLContext es el punto de entrada principal en la biblioteca Spark SQL. Es una clase definida en
la biblioteca Spark SQL. Una aplicación Spark SQL debe crear una instancia de la clase SQLContext
o HiveContext. Se requiere SQLContext para crear instancias de las otras clases proporcionadas
por la biblioteca Spark SQL. También es necesario para ejecutar consultas SQL.

import org.apache.spark._

import org.apache.spark.sql._

val config = new SparkConf().setAppName("My Spark SQL app")

val sc = new SparkContext(config)

val sqlContext = new SQLContext(sc)

HiveContext

HiveContext es un punto de entrada alternativo a la biblioteca Spark SQL. Extiende la clase


SQLContext para procesar datos almacenados en Hive. También proporciona un analizador de
HiveQL. Una aplicación Spark SQL debe crear una instancia de esta clase o de la clase
SQLContext.

<?xml version="1.0"?>

<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>

<property>

<name>hive.metastore.warehouse.dir</name>

<value>/path/to/hive/warehouse</value>
UNIVERSIDAD UTE

<description>

Local or HDFS directory for storing tables.

</description>

</property>

<property>

<name>javax.jdo.option.ConnectionURL</name>

<value>jdbc:derby:;databaseName=/path/to/hive/metastore_db;create=true</value>

<description>

JDBC connection URL.

</description>

</property>

</configuration>

Marco de datos

DataFrame es la abstracción de datos primaria de Spark SQL. Representa una colección


distribuida de filas organizadas en columnas nombradas. Está inspirado en DataFrames en R y
Python. Conceptualmente, es similar a una tabla en una base de datos relacional.

Fila

Fila es una abstracción de Spark SQL para representar una fila de datos. Conceptualmente, es
equivalente a una tupla o fila relacional en una tabla. Spark SQL proporciona métodos de fábrica
para crear objetos de fila. A continuación, se muestra un ejemplo.

import org.apache.spark.sql._

val row1 = Row("Barack Obama", "President", "United States")

val row2 = Row("David Cameron", "Prime Minister", "United Kingdom")

val presidentName = row1.getString(0)

val country = row1.getString(2)

Creando marcos de datos

Un DataFrame se puede crear de dos maneras. En primer lugar, se puede crear a partir de una
fuente de datos. Spark SQL proporciona métodos de creación para crear un DataFrame a partir
de una variedad de fuentes de datos. Algunas de las fuentes de datos tienen soporte
incorporado y otras requieren bibliotecas externas. En segundo lugar, se puede crear un
DataFrame desde un RDD.
UNIVERSIDAD UTE

Creación de un DataFrame a partir de un origen de datos

Spark SQL proporciona una interfaz unificada para crear un DataFrame a partir de una variedad
de fuentes de datos. Por ejemplo, la misma API se puede usar para crear un DataFrame desde
una tabla MySQL, PostgreSQL, Oracle o Cassandra. De manera similar, la misma API se puede
utilizar para crear un DataFrame desde un archivo Parquet, JSON, ORC o CSV en el sistema de
archivos local, HDFS o S3.

JSON

La clase DataFrameReader proporciona un método llamado json para leer un conjunto de datos
JSON. Toma una ruta como argumento y devuelve un DataFrame. La ruta puede ser el nombre
de un archivo JSON o de un directorio que contenga varios archivos JSON.

val jsonDF = sqlContext.read.json("path/to/JSON-file-or-directory")

val jsonHdfsDF = sqlContext.read.json("hdfs://NAME_NODE/path/to/data.json")

val jsonS3DF = sqlContext.read.json("s3a://BUCKET_NAME/FOLDER_NAME/data.json")

import org.apache.spark.sql.types._

val userSchema = StructType(List(

StructField("name", StringType, false),

StructField("age", IntegerType, false),

StructField("gender", StringType, false)

val userDF = sqlContext.read

.schema(userSchema)

.json("path/to/user.json")

Parquet

La clase DataFrameReader proporciona un método llamado parquet para leer archivos de


parquet. Toma una ruta de uno o más archivos de Parquet como argumento y devuelve un
DataFrame.

val parquetDF = sqlContext.read.parquet("path/to/parquet-file-or-directory")

val parquetHdfsDF = sqlContext.read.parquet("hdfs://NAME_NODE/path/to/data.parquet")

val parquetS3DF =
sqlContext.read.parquet("s3a://BUCKET_NAME/FOLDER_NAME/data.parquet")

ORC
UNIVERSIDAD UTE

La clase DataFrameReader proporciona un método llamado orc para leer un conjunto de datos
almacenado en formato de archivo ORC. Toma una ruta como argumento y devuelve un
DataFrame.

val orcDF = hiveContext.read.orc("path/to/orc-file-or-directory")

val orcHdfsDF = sqlContext.read.orc("hdfs://NAME_NODE/path/to/data.orc")

val orcS3DF = sqlContext.read.orc("s3a://BUCKET_NAME/FOLDER_NAME/data.orc")

Hive

Puede crear un DataFrame a partir de una tabla Hive de dos maneras. Primero, puede usar el
método de tabla definido en la clase DataFrameReader. Toma el nombre de una tabla en un
metastore de Hive y devuelve un DataFrame.

val hiveDF = hiveContext.read.table("hive-table-name")

val hiveDF = hiveContext.sql("SELECT col_a, col_b, col_c from hive-table")

Base de datos compatible con JDBC

El método jdbc definido en la clase DataFrameReader crea un DataFrame desde cualquier base
de datos compatible con JDBC, incluidos MySQL, PostgresSQL, H2, Oracle, SQL Server, SAP Hana
y DB2. La clase DataFrameReader proporciona varias variantes sobrecargadas del método jdbc.
La más simple toma tres argumentos: la URL de JDBC de una base de datos, el nombre de la
tabla y las propiedades de conexión. Las propiedades de conexión especifican argumentos de
conexión como el nombre de usuario y la contraseña.

val jdbcUrl ="jdbc:mysql://host:port/database"

val tableName = "table-name"

val connectionProperties = new java.util.Properties

connectionProperties.setProperty("user","database-user-name")

connectionProperties.setProperty("password"," database-user-password")

val jdbcDF = hiveContext.read

.jdbc(jdbcUrl, tableName, connectionProperties)

val predicates = Array("country='Germany'")

val usersGermanyDF = hiveContext.read

.jdbc(jdbcUrl, tableName, predicates, connectionProperties)

Procesando datos programáticamente con SQL / HiveQL

El método sql en la clase HiveContext le permite procesar un conjunto de datos utilizando


instrucciones HiveQL, mientras que el método sql en la clase SQLContext le permite procesar un
conjunto de datos utilizando declaraciones SQL. La tabla a la que se hace referencia en una
declaración SQL / HiveQL debe tener una entrada en un almacén de metadatos de Hive. Si no
UNIVERSIDAD UTE

tiene una implementación de Hive existente, puede crear una tabla temporal utilizando el
método registerTempTable proporcionado por la clase DataFrame. Discutiré este método con
más detalle en la siguiente sección.

import org.apache.spark.sql.types._

val userSchema = StructType(List(

StructField("name", StringType, false),

StructField("age", IntegerType, false),

StructField("gender", StringType, false)

val userDF = sqlContext.read

.schema(userSchema)

.json("path/to/user.json")

userDF.registerTempTable("user")

val cntDF = hiveContext.sql("SELECT count(1) from user")

val cntByGenderDF = hiveContext.sql(

"SELECT gender, count(1) as cnt FROM user GROUP BY gender ORDER BY cnt")

Procesando datos con la API DataFrame

La sección anterior trató el método sql en las clases SQLContext y HiveContext para procesar un
conjunto de datos utilizando sentencias de SQL o HiveQL incrustadas. La API DataFrame
proporciona una forma alternativa de procesar un conjunto de datos.

$ cd SPARK_HOME

$ ./bin/spark-shell --master local[*]

case class Customer(cId: Long, name: String, age: Int, gender: String)

val customers = List(Customer(1, "James", 21, "M"),

Customer(2, "Liz", 25, "F"),

Customer(3, "John", 31, "M"),

Customer(4, "Jennifer", 45, "F"),

Customer(5, "Robert", 41, "M"),

Customer(6, "Sandra", 45, "F"))

val customerDF = sc.parallelize(customers).toDF()


UNIVERSIDAD UTE

case class Product(pId: Long, name: String, price: Double, cost: Double)

val products = List(Product(1, "iPhone", 600, 400),

Product(2, "Galaxy", 500, 400),

Product(3, "iPad", 400, 300),

Product(4, "Kindle", 200, 100),

Product(5, "MacBook", 1200, 900),

Product(6, "Dell", 500, 400))

val productDF = sc.parallelize(products).toDF()

case class Home(city: String, size: Int, lotSize: Int,

bedrooms: Int, bathrooms: Int, price: Int)

val homes = List(Home("San Francisco", 1500, 4000, 3, 2, 1500000),

Home("Palo Alto", 1800, 3000, 4, 2, 1800000),

Home("Mountain View", 2000, 4000, 4, 2, 1500000),

Home("Sunnyvale", 2400, 5000, 4, 3, 1600000),

Home("San Jose", 3000, 6000, 4, 3, 1400000),

Home("Fremont", 3000, 7000, 4, 3, 1500000),

Home("Pleasanton", 3300, 8000, 4, 3, 1400000),

Home("Berkeley", 1400, 3000, 3, 3, 1100000),

Home("Oakland", 2200, 6000, 4, 3, 1100000),

Home("Emeryville", 2500, 5000, 4, 3, 1200000))

val homeDF = sc.parallelize(homes).toDF

Operaciones básicas

Esta sección describe las operaciones básicas comúnmente utilizadas proporcionadas por la
clase DataFrame.

Cache

El método de caché almacena el DataFrame de origen en la memoria usando un formato de


columnas. Escanea solo las columnas requeridas y las almacena en formato de columnas
comprimidas en memoria. Spark SQL selecciona automáticamente un códec de compresión para
cada columna en función de las estadísticas de datos.

customerDF.cache()
UNIVERSIDAD UTE

sqlContext.setConf("spark.sql.inMemoryColumnarStorage.compressed", "true")

sqlContext.setConf("spark.sql.inMemoryColumnarStorage.batchSize", "10000")

Columnas

El método de las columnas devuelve los nombres de todas las columnas en el DataFrame de
origen como una matriz de String.

val cols = customerDF.columns

cols: Array[String] = Array(cId, name, age, gender)

Dtypes

El método dtypes devuelve los tipos de datos de todas las columnas en el DataFrame de origen
como una matriz de tuplas. El primer elemento en una tupla es el nombre de una columna y el
segundo elemento es el tipo de datos de esa columna.

val columnsWithTypes = customerDF.dtypes

columnsWithTypes: Array[(String, String)] = Array((cId,LongType), (name,StringType),

(age,IntegerType), (gender,StringType))

Explain

El método de explicación imprime el plan físico en la consola. Es útil para la depuración.

customerDF.explain()

== Physical Plan ==

InMemoryColumnarTableScan [cId#0L,name#1,age#2,gender#3], (InMemoryRelation

[cId#0L,name#1,age#2,gender#3], true, 10000, StorageLevel(true, true, false, true, 1),

(Scan PhysicalRDD[cId#0L,name#1,age#2,gender#3]), None)

Persistencia

El método de persistencia almacena en caché el DataFrame de origen en la memoria.

customerDF.persist

PrintSchema

El método printSchema imprime el esquema del DataFrame de origen en la consola en un


formato de árbol.
UNIVERSIDAD UTE

customerDF.printSchema()

root

|-- cId: long (nullable = false)

|-- name: string (nullable = true)

|-- age: integer (nullable = false)

|-- gender: string (nullable = true)

RegisterTempTable

El método registerTempTable crea una tabla temporal en el metastore de Hive. Toma un nombre
de tabla como argumento. Se puede consultar una tabla temporal utilizando el método sql en
SQLContext o HiveContext. Está disponible solo durante la vida útil de la aplicación que lo crea.

customerDF.registerTempTable("customer")

val countDF = sqlContext.sql("SELECT count(1) AS cnt FROM customer")

countDF: org.apache.spark.sql.DataFrame = [cnt: bigint]

Métodos de consulta integrados en el lenguaje

Esta sección describe los métodos de consulta integrados en el lenguaje que se utilizan
comúnmente en la clase DataFrame.

Agg

El método agg realiza agregaciones especificadas en una o más columnas en el DataFrame de


origen y devuelve el resultado como un nuevo DataFrame.

val aggregates = productDF.agg(max("price"), min("price"), count("name"))

aggregates: org.apache.spark.sql.DataFrame = [max(price): double, min(price): double,

count(name): bigint]

Aplicación

El método de aplicación toma el nombre de una columna como un argumento y devuelve la


columna especificada en el DataFrame de origen como una instancia de la clase Column. La clase
Columna proporciona operadores para manipular una columna en un DataFrame.

val priceColumn = productDF.apply("price")

priceColumn: org.apache.spark.sql.Column = price

val discountedPriceColumn = priceColumn * 0.5


UNIVERSIDAD UTE

discountedPriceColumn: org.apache.spark.sql.Column = (price * 0.5)

Cubo

El método del cubo toma los nombres de una o más columnas como argumentos y devuelve un
cubo para el análisis multidimensional. Es útil para generar informes de tablas cruzadas.

class SalesSummary(date: String, product: String, country: String, revenue: Double)

val sales = List(SalesSummary("01/01/2015", "iPhone", "USA", 40000),

SalesSummary("01/02/2015", "iPhone", "USA", 30000),

SalesSummary("01/01/2015", "iPhone", "China", 10000),

SalesSummary("01/02/2015", "iPhone", "China", 5000),

SalesSummary("01/01/2015", "S6", "USA", 20000),

SalesSummary("01/02/2015", "S6", "USA", 10000),

SalesSummary("01/01/2015", "S6", "China", 9000),

SalesSummary("01/02/2015", "S6", "China", 6000))

val salesDF = sc.parallelize(sales).toDF()

val salesCubeDF = salesDF.cube($"date", $"product", $"country").sum("revenue")

salesCubeDF: org.apache.spark.sql.DataFrame = [date: string, product: string, country:

string, sum(revenue): double]

salesCubeDF.withColumnRenamed("sum(revenue)", "total").show(30)

Distinto

El método distinto devuelve un nuevo DataFrame que contiene solo las filas únicas en el
DataFrame de origen.

val dfWithoutDuplicates = customerDF.distinct

Explotar

El método de explosión genera cero o más filas de una columna usando una función
proporcionada por el usuario. Se necesitan tres argumentos. El primer argumento es la columna
de entrada, el segundo argumento es la columna de salida y el tercer argumento es una función
proporcionada por el usuario que genera uno o más valores para la columna de salida para cada
valor en la columna de entrada.

case class Email(sender: String, recepient: String, subject: String, body: String)

val emails = List(Email("James", "Mary", "back", "just got back from vacation"),
UNIVERSIDAD UTE

Email("John", "Jessica", "money", "make million dollars"),

Email("Tim", "Kevin", "report", "send me sales report ASAP"))

val emailDF = sc.parallelize(emails).toDF()

val wordDF = emailDF.explode("body", "word") { body: String => body.split(" ")}

wordDF.show

Filtro

El método de filtro filtra filas en el DataFrame de origen utilizando una expresión SQL que se le
proporciona como argumento. Devuelve un nuevo DataFrame que contiene solo las filas
filtradas. La expresión SQL se puede pasar como un argumento de cadena.

val filteredDF = customerDF.filter("age > 25")

filteredDF: org.apache.spark.sql.DataFrame = [cId: bigint, name: string, age: int, gender: string]

Groupby
El método groupBy agrupa las filas en el DataFrame de origen usando las columnas
proporcionadas como argumentos. La agregación se puede realizar en los datos agrupados
devueltos por este método.

val countByGender = customerDF.groupBy("gender").count

countByGender: org.apache.spark.sql.DataFrame = [gender: string, count: bigint]

countByGender.show

val revenueByProductDF = salesDF.groupBy("product").sum("revenue")

revenueByProductDF: org.apache.spark.sql.DataFrame = [product: string, sum(revenue):


double]

revenueByProductDF.show
UNIVERSIDAD UTE

Intersect

El método de intersección toma un DataFrame como un argumento y devuelve un nuevo


DataFrame que contiene solo las filas tanto en la entrada como en el DataFrame de origen.

val customers2 = List(Customer(11, "Jackson", 21, "M"),

Customer(12, "Emma", 25, "F"),

Customer(13, "Olivia", 31, "F"),

Customer(4, "Jennifer", 45, "F"),

Customer(5, "Robert", 41, "M"),

Customer(6, "Sandra", 45, "F"))

val customer2DF = sc.parallelize(customers2).toDF()

val commonCustomersDF = customerDF.intersect(customer2DF)

commonCustomersDF.show

Join

El método de unión realiza una unión SQL del DataFrame de origen con otro DataFrame. Toma
tres argumentos, un DataFrame, una expresión de unión y un tipo de combinación.

case class Transaction(tId: Long, custId: Long, prodId: Long, date: String, city: String)

val transactions = List(Transaction(1, 5, 3, "01/01/2015", "San Francisco"),


Transaction(2, 6, 1, "01/02/2015", "San Jose"),

Transaction(3, 1, 6, "01/01/2015", "Boston"),

Transaction(4, 200, 400, "01/02/2015", "Palo Alto"),

Transaction(6, 100, 100, "01/02/2015", "Mountain View"))

val transactionDF = sc.parallelize(transactions).toDF()

val innerDF = transactionDF.join(customerDF, $"custId" === $"cId", "inner")


UNIVERSIDAD UTE

innerDF.show

val outerDF = transactionDF.join(customerDF, $"custId" === $"cId", "outer") outerDF.show

val leftOuterDF = transactionDF.join(customerDF, $"custId" === $"cId", "left_outer")


leftOuterDF.show

val rightOuterDF = transactionDF.join(customerDF, $"custId" === $"cId", "right_outer")


rightOuterDF.show
UNIVERSIDAD UTE

limit

El método de límite devuelve un DataFrame que contiene el número especificado de filas del
DataFrame de origen.

val fiveCustomerDF = customerDF.limit(5) fiveCustomer.show

orderBy

El método orderBy devuelve un DataFrame ordenado por las columnas dadas. Toma los
nombres de una o más columnas como argumentos.

val sortedDF = customerDF.orderBy("name")

sortedDF.show

Por defecto, el método orderBy ordena en orden ascendente. Puede especificar


explícitamente el orden de clasificación utilizando una expresión de columna, como se muestra
a continuación.

val sortedByAgeNameDF = customerDF.sort($"age".desc, $"name".asc)

sortedByAgeNameDF.show
UNIVERSIDAD UTE

randomSplit

El método randomSplit divide el DataFrame de origen en múltiples DataFrames. Toma una


matriz de pesos como argumento y devuelve una matriz de DataFrames. Es un método útil
para el aprendizaje automático, en el que desea dividir el conjunto de datos sin procesar en
conjuntos de datos de entrenamiento, validación y prueba.

val dfArray = homeDF.randomSplit(Array(0.6, 0.2, 0.2))

dfArray(0).count

dfArray(1).count

dfArray(2).count

rollup

El método de resumen toma los nombres de una o más columnas como argumentos y
devuelve un resumen multidimensional. Es útil para la subagregación a lo largo de una
dimensión jerárquica como la geografía o el tiempo. Supongamos que tiene un conjunto de
datos que rastrea las ventas anuales por ciudad, estado y país. El método de acumulación se
puede usar para calcular el total general y los subtotales por ciudad, estado y país.

case class SalesByCity(year: Int, city: String, state: String,

country: String, revenue: Double)

val salesByCity = List(SalesByCity(2014, "Boston", "MA", "USA", 2000),

SalesByCity(2015, "Boston", "MA", "USA", 3000),

SalesByCity(2014, "Cambridge", "MA", "USA", 2000),

SalesByCity(2015, "Cambridge", "MA", "USA", 3000),

SalesByCity(2014, "Palo Alto", "CA", "USA", 4000),

SalesByCity(2015, "Palo Alto", "CA", "USA", 6000),

SalesByCity(2014, "Pune", "MH", "India", 1000),


UNIVERSIDAD UTE

SalesByCity(2015, "Pune", "MH", "India", 1000),

SalesByCity(2015, "Mumbai", "MH", "India", 1000),

SalesByCity(2014, "Mumbai", "MH", "India", 2000))

val salesByCityDF = sc.parallelize(salesByCity).toDF()

val rollup = salesByCityDF.rollup($"country", $"state", $"city").sum("revenue")

rollup.show

sample

El método de muestra devuelve un DataFrame que contiene la fracción especificada de las filas
en el DataFrame de origen. Se necesitan dos argumentos. El primer argumento es un valor
booleano que indica si el muestreo debe realizarse con reemplazo. El segundo argumento
especifica la fracción de las filas que deben devolverse.

val sampleDF = homeDF.sample(true, 0.10)

select

El método de selección devuelve un DataFrame que contiene solo las columnas especificadas
del DataFrame de origen.

val namesAgeDF = customerDF.select("name", "age")

namesAgeDF.show
UNIVERSIDAD UTE

Una variante del método de selección permite una o más expresiones de columna como
argumentos.

val newAgeDF = customerDF.select($"name", $"age" + 10)

newAgeDF.show

selectExpr

El método selectExpr acepta una o más expresiones SQL como argumentos y devuelve un
DataFrame generado al ejecutar las expresiones SQL especificadas.

val newCustomerDF = customerDF.selectExpr("name", "age + 10 AS new_age",

"IF(gender = 'M', true, false) AS male")

newCustomerDF.show

withColumn

El método withColumn agrega una nueva columna o reemplaza una columna existente en el
DataFrame de origen y devuelve un nuevo DataFrame. Se necesitan dos argumentos. El primer
argumento es el nombre de la nueva columna y el segundo argumento es una expresión para
generar los valores de la nueva columna.

val newProductDF = productDF.withColumn("profit", $"price" - $"cost")

newProductDF.show
UNIVERSIDAD UTE

RDD Operaciones

La clase DataFrame admite operaciones RDD de uso común como map, flatMap, foreach,
foreachPartition, mapPartition, coalesce y repartition. Estos métodos funcionan de manera
similar a sus operaciones homónimas en la clase RDD. Además, si necesita acceder a otros
métodos RDD que no están presentes en la clase DataFrame, puede obtener un RDD desde un
DataFrame. Esta sección analiza las técnicas utilizadas comúnmente para generar un RDD a
partir de un DataFrame.

rdd

se define como un valor perezoso en la clase DataFrame. Representa el DataFrame de origen


como un RDD de instancias de fila. Como se mencionó anteriormente, una Fila representa una
tupla relacional en el DataFrame de origen. Permite tanto el acceso genérico como el acceso
primitivo nativo de campos por su ordinal. A continuación, se muestra un ejemplo.

val rdd = customerDF.rdd

rdd: org.apache.spark.rdd.RDD[org.apache.spark.sql.Row] = MapPartitionsRDD[405] at rdd at


<console>:27

val firstRow = rdd.first

firstRow: org.apache.spark.sql.Row = [1,James,21,M]

val name = firstRow.getString(1)

name: String = James

val age = firstRow.getInt(2)

age: Int = 21

Los campos en una fila también se pueden extraer utilizando la coincidencia de patrones de
Scala.

import org.apache.spark.sql.Row val rdd = customerDF.rdd

rdd: org.apache.spark.rdd.RDD[org.apache.spark.sql.Row] = MapPartitionsRDD[113] at rdd at


<console>:28
UNIVERSIDAD UTE

val nameAndAge = rdd.map {

case Row(cId: Long, name: String, age: Int, gender: String) => (name, age)

nameAndAge: org.apache.spark.rdd.RDD[(String, Int)] = MapPartitionsRDD[114] at map at


<console>:30

nameAndAge.collect

res79: Array[(String, Int)] = Array((James,21), (Liz,25), (John,31), (Jennifer,45), (Robert,41),


(Sandra,45))

toJSON

El método toJSON genera un RDD de cadenas JSON desde el DataFrame de origen. Cada
elemento en el RDD devuelto es un objeto JSON.

val jsonRDD = customerDF.toJSON

jsonRDD: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[408] at toJSON at


<console>:28

jsonRDD.collect

res80: Array[String] = Array({"cId":1,"name":"James","age":21,"gender":"M"},


{"cId":2,"name":"Liz","age":25,"gender":"F"}, {"cId":3,"name":"John","age":31,"gender":"M"},
{"cId":4,"name":"Jennifer","age":45,"gender":"F"},
{"cId":5,"name":"Robert","age":41,"gender":"M"},
{"cId":6,"name":"Sandra","age":45,"gender":"F"})

Actions

Al igual que las acciones RDD, los métodos de acción en la clase DataFrame devuelven los
resultados al programa Driver. Esta sección cubre los métodos de acción comúnmente
utilizados en la clase DataFrame.

collect

El método de recopilación devuelve los datos en un marco de datos como una matriz de filas.

val result = customerDF.collect

result: Array[org.apache.spark.sql.Row] = Array([1,James,21,M], [2,Liz,25,F], [3,John,31,M],


[4,Jennifer,45,F], [5,Robert,41,M], [6,Sandra,45,F])

count

El método de conteo devuelve el número de filas en el DataFrame de origen.

val count = customerDF.count


UNIVERSIDAD UTE

count: Long = 6

describe

El método de descripción se puede utilizar para el análisis de datos exploratorios. Devuelve


estadísticas de resumen para columnas numéricas en el DataFrame de origen. Las estadísticas
de resumen incluyen mín, máx, conteo, media y desviación estándar. Toma los nombres de
una o más columnas como argumentos.

val summaryStatsDF = productDF.describe("price", "cost")

summaryStatsDF: org.apache.spark.sql.DataFrame = [summary: string, price: string, cost:


string]

summaryStatsDF.show

first

El primer método devuelve la primera fila en el DataFrame de origen.

val first = customerDF.first

first: org.apache.spark.sql.Row = [1,James,21,M]

Show

El método show muestra las filas en el DataFrame de origen en la consola del controlador en
un formato tabular. Opcionalmente toma un entero N como argumento y muestra las N filas
superiores. Si no se proporciona ningún argumento, muestra las 20 filas superiores.

customerDF.show(2)

only showing top 2 rows

take

El método de toma toma un entero N como argumento y devuelve las primeras N filas del
DataFrame de origen como una matriz de Filas.
UNIVERSIDAD UTE

val first2Rows = customerDF.take(2)

first2Rows: Array[org.apache.spark.sql.Row] = Array([1,James,21,M], [2,Liz,25,F])

Operaciones de salida (Output Operations)

Una operación de salida guarda un DataFrame en un sistema de almacenamiento. Antes de la


versión 1.4, DataFrame incluía varios métodos diferentes para guardar un DataFrame en una
variedad de sistemas de almacenamiento. A partir de la versión 1.4, esos métodos fueron
reemplazados por el método de escritura.

Write

El método de escritura devuelve una instancia de la clase DataFrameWriter, que proporciona


métodos para guardar el contenido de un DataFrame en una fuente de datos. La siguiente
sección cubre la clase DataFrameWriter.

Guardar un DataFrame

Spark SQL proporciona una interfaz unificada para guardar un DataFrame en una variedad de
fuentes de datos. La misma interfaz se puede utilizar para escribir datos en bases de datos
relacionales, almacenes de datos NoSQL y una variedad de formatos de archivo. La clase
DataFrameWriter define la interfaz para escribir datos en un origen de datos. A través de sus
métodos de construcción, le permite especificar diferentes opciones para guardar datos. Por
ejemplo, puede especificar el formato, la partición y el manejo de los datos existentes. Los
siguientes ejemplos muestran cómo guardar un DataFrame en diferentes sistemas de
almacenamiento.

// guarda un DataFrame en formato JSON

customerDF.write

.format ("org.apache.spark.sql.json")

.save ("ruta / a / directorio de salida")

// guarda un DataFrame en formato Parquet

homeDF.write

.format ("org.apache.spark.sql.parquet")

.partitionBy ("ciudad")

.save ("ruta / a / directorio de salida")

// guardar un DataFrame en formato de archivo ORC

homeDF.write
UNIVERSIDAD UTE

.format ("orc")

.partitionBy ("ciudad")

.save ("ruta / a / directorio de salida")

// guardar un DataFrame como una tabla de base de datos Postgres

df.write

.format ("org.apache.spark.sql.jdbc")

.options (Map ("url" -> "jdbc: postgresql: // host: port / database? user = <USER> & password =
<PASS>",

"dbtable" -> "schema-name.table-name"))

.salvar()

// guarda un DataFrame en una tabla Hive

df.write.saveAsTable ("hive-table-name")

Puede guardar un DataFrame en formato Parquet, JSON, ORC o CSV en cualquier sistema de
almacenamiento compatible con Hadoop, incluido el sistema de archivos local, HDFS o Amazon
S3. Si un origen de datos admite el diseño particionado, la clase DataFrameWriter lo admite a
través del método partitionBy. Dividirá las filas por la columna especificada y creará un
subdirectorio separado para cada valor único en la columna especificada.

homeDF.write .format("parquet")

.partitionBy("city")

.save("homes")

El código anterior divide las filas por la columna de la ciudad. Se creará un subdirectorio para
cada valor único de ciudad. Por ejemplo, los subdirectorios llamados city = Berkeley, city =
Fremont, city = Oakland, etc., se crearán en el directorio de casas.

val newHomesDF = sqlContext.read.format("parquet").load("homes")

newHomesDF.registerTempTable("homes")

val homesInBerkeley = sqlContext.sql("SELECT * FROM homes WHERE city = 'Berkeley'")

Al guardar un DataFrame, si la ruta o tabla de destino ya existe, Spark SQL lanzará una
excepción de manera predeterminada. Puede cambiar este comportamiento llamando al
método de modo en la clase DataFrameWriter. Toma un argumento, que especifica el
UNIVERSIDAD UTE

comportamiento si la ruta o la tabla de destino ya existen. El método de modo soporta las


siguientes opciones:

error (predeterminado): lanza una excepción si la ruta / tabla de destino ya existe.

anexar - anexar a los datos existentes si ya existe la ruta / tabla de destino.

sobrescribir: sobrescribe los datos existentes si existe una ruta / tabla de destino.

ignorar: ignora la operación si existe la ruta / tabla de destino.

A continuación se muestran algunos ejemplos.

customerDF.write .format("parquet")

.mode("overwrite")

.save("path/to/output-directory")

customerDF.write .mode("append")

.saveAsTable("hive-table-name")

Además de los métodos que se muestran aquí para escribir datos en un origen de datos, la
clase DataFrameWriter proporciona métodos especiales para escribir datos en los orígenes de
datos para los cuales tiene soporte incorporado. Estas fuentes de datos incluyen bases de
datos compatibles con Parquet, ORC, JSON, Hive y JDBC.

JSON

El método json guarda el contenido de un DataFrame en formato JSON. Toma como


argumento una ruta, que puede estar en un sistema de archivos local, HDFS o S3.

customerDF.write.json("path/to/directory")

Parquet

El método de parquet guarda el contenido de un DataFrame en formato Parquet. Toma una


ruta como argumento y guarda un DataFrame en la ruta especificada.

customerDF.write.parquet("path/to/directory")

ORC

El método orc guarda un DataFrame en formato de archivo ORC. Similar a los métodos JSON y
Parquet, toma un camino como argumento.

customerDF.write.orc ("ruta / a / directorio")

Hive

El método saveAsTable guarda el contenido de un DataFrame como una tabla de Hive. Guarda
un DataFrame en un archivo y registra los metadatos como una tabla en el metastore de Hive.

customerDF.write.saveAsTable ("hive-table-name")
UNIVERSIDAD UTE

JDBC-Compliant Database

El método jdbc guarda un DataFrame en una base de datos utilizando la interfaz JDBC. Toma
tres argumentos: la URL de JDBC de una base de datos, el nombre de la tabla y las propiedades
de conexión. Las propiedades de conexión especifican argumentos de conexión como el
nombre de usuario y la contraseña.

val jdbcUrl ="jdbc:mysql://host:port/database" val tableName = "table-name"

val connectionProperties = new java.util.Properties


connectionProperties.setProperty("user","database-user-name")
connectionProperties.setProperty("password"," database-user-password")

customerDF.write.jdbc(jdbcUrl, tableName, connectionProperties)

Built-in Functions

Spark SQL viene con una lista completa de funciones integradas, que están optimizadas para
una ejecución rápida. Implementa estas funciones con técnicas de generación de código. Las
funciones integradas se pueden usar tanto desde la API DataFrame como desde la interfaz SQL.
Para usar las funciones integradas de Spark desde la API DataFrame, debe agregar la siguiente
declaración de importación a su código fuente.

importar org.apache.spark.sql.functions._

Las funciones incorporadas se pueden clasificar en las siguientes categorías: agregados,


recopilación, fecha / hora, matemáticas, cadenas, ventanas y funciones varias.

Aggregate

Las funciones agregadas se pueden utilizar para realizar agregaciones en una columna. Las
funciones agregadas incorporadas incluyen approxCountDistinct, avg, count, countDistinct,
first, last, max, mean, min, sum y sumDistinct.

El siguiente ejemplo ilustra cómo puede utilizar una función incorporada.

val minPrice = homeDF.select(min($"price")) minPrice.show

Colección (Collection)

Las funciones de colección operan en columnas que contienen una colección de elementos.
Las funciones de colección integradas incluyen array_contains, explode, size y sort_array.

Fecha y hora (Date/Time)


UNIVERSIDAD UTE

Las funciones de fecha / hora facilitan el procesamiento de columnas que contienen valores de
fecha / hora. Estas funciones pueden subdividirse en las siguientes categorías: conversión,
extracción, aritmética y funciones varias.

Conversión (Conversion)

Las funciones de conversión convierten los valores de fecha / hora de un formato a otro. Por
ejemplo, puede convertir una cadena de marca de tiempo en formato aaaa-MM-dd HH: mm:
ss a un valor de época Unix usando la función unix_timestamp. A la inversa, la función
from_unixtime convierte un valor de época de Unix en una representación de cadena. Spark
SQL también proporciona funciones para convertir marcas de tiempo de una zona horaria a
otra. Las funciones de conversión integradas incluyen unix_timestamp, from_unixtime,
to_date, quarter, day, dayofyear, weekofyear, from_utc_timestamp y to_utc_timestamp.

Extracción de campo (Field Extraction)

Las funciones de extracción de campo le permiten extraer año, mes, día, hora, minuto y
segundo de un valor de Fecha / Hora. Las funciones de extracción de campo incorporadas
incluyen año, trimestre, mes, semana de año, día de año, día de mes, hora, minuto y segundo.

Fecha aritmética (Date Arithmetic)

Las funciones aritméticas le permiten realizar operaciones aritméticas en columnas que


contienen fechas. Por ejemplo, puede calcular la diferencia entre dos fechas, agregar días a
una fecha o restar días de una fecha. Las funciones aritméticas de fecha incorporadas incluyen
dateiff, date_add, date_sub, add_months, last_day, next_day y months_between.

Miscellaneous

Además de las funciones mencionadas anteriormente, Spark SQL proporciona algunas otras
funciones útiles relacionadas con la fecha y la hora, como current_date, current_timestamp,
trunc, date_format.

Math

Las funciones matemáticas operan en columnas que contienen valores numéricos. Spark SQL
viene con una larga lista de funciones matemáticas integradas. Los ejemplos incluyen abs, ceil,
cos, exp, factorial, floor, hex, hypot, log, log10, pow, round, shiftLeft, sin, sqrt, tan y otras
funciones matemáticas de uso común.

String

Spark SQL proporciona una variedad de funciones incorporadas para procesar columnas que
contienen valores de cadena. Por ejemplo, puede dividir, recortar o cambiar el caso de una
cadena. Las funciones de cadena incorporadas incluyen ascii, base64, concat, concat_ws,
decodificar, codificar, format_number, format_string, get_json_object, initcap, instr, length,
levenshtein, localizar, bajar, lpad, ltrim, printf, regexp_extract, regexp_replace, repetir, invertir
UNIVERSIDAD UTE

, rpad, rtrim, soundex, space, split, subcadena, substring_index, translate, trim, unbase64,
upper y otras funciones de cadena de uso común.

Window

Spark SQL soporta funciones de ventana para análisis. Una función de ventana realiza un
cálculo a través de un conjunto de filas que están relacionadas con la fila actual. Las funciones
de ventana integradas que proporciona Spark SQL incluyen cumeDist, denseRank, lag, lead,
ntile, percentRank, rank y rowNumber.

UDFs and UDAFs

Spark SQL permite funciones definidas por el usuario (UDF) y funciones de agregación
definidas por el usuario (UDAF). Tanto las UDF como las UDAF realizan cálculos personalizados
en un conjunto de datos. Un UDF realiza un cálculo personalizado fila por fila y devuelve un
valor para cada fila.

Interactive Analysis Example

Spark SQL puede usarse como una herramienta de análisis de datos interactiva. Las secciones
anteriores usaron ejemplos de juguetes para que fueran fáciles de entender. Esta sección
muestra cómo se puede utilizar Spark SQL para el análisis interactivo de datos en un conjunto
de datos del mundo real. Puede utilizar consultas integradas en el idioma o SQL / HiveQL para
el análisis de datos.

El ejemplo utiliza el archivo yelp_academic_dataset_business.json, que contiene información


sobre negocios. Contiene un objeto JSON por línea. Cada objeto JSON contiene información
sobre un negocio, incluido su nombre, ciudad, estado, revisiones, calificación promedio,
categoría y otros atributos.

path/to/spark/bin/spark-shell --master local[*]

Para las declaraciones de código de varias líneas, puede usar el modo de pegado del shell
Spark (: paste). Alternativamente, ingrese una declaración completa en una sola línea.

Ejemplo.

biz.filter ("...")

.seleccionar("...")

.espectáculo()

En el shell de Spark, escríbalo sin los saltos de línea, como se muestra a continuación.
UNIVERSIDAD UTE

biz.filter ("..."). select ("..."). show ()

Ejemplo.

sqlContext.sql ("SELECT x, count (y) como total DE t

GRUPO POR X

ORDEN POR total ")

.show (50)

Escriba el código anterior en el shell de Spark sin saltos de línea, como se muestra a
continuación.

sqlContext.sql ("SELECCIONE x, cuenta (y) como total DE t GRUPO POR x ORDEN POR total")
.show (50)

Vamos a empezar ahora. Dado que utilizará algunas clases y funciones de la biblioteca Spark
SQL, necesitará la siguiente declaración de importación.

importar org.apache.spark.sql._

Vamos a crear un DataFrame a partir del conjunto de datos de las empresas de Yelp.

val biz = sqlContext.read.json ("path / to / yelp_academic_dataset_business.json")

La declaración anterior es equivalente a esto:

val biz = sqlContext.read.format ("json"). load ("path / to /


yelp_academic_dataset_business.json")

Hay que asegurarse de especificar la ruta de archivo correcta. Reemplace "ruta / a" con el
nombre del directorio donde desempaquetó el conjunto de datos de Yelp. Spark SQL lanzará
una excepción si no puede encontrar el archivo en la ruta especificada. Spark SQL lee todo el
conjunto de datos una vez para inferir el esquema de un archivo JSON. Revisemos el esquema
inferido por Spark SQL.

biz.printSchema()

utilice la interfaz SQL / HiveQL, debe registrar el DataFrame biz como una tabla temporal.
UNIVERSIDAD UTE

biz.registerTempTable ("biz")

Ahora se puede analizar el conjunto de datos de las empresas de Yelp utilizando la API
DataFrame o SQL / HiveQL. Mostraré el código para ambos, pero mostraré el resultado solo
para las consultas SQL / HiveQL. Vamos a almacenar en caché los datos en la memoria, ya que
los consultarás más de uno una vez.

Consulta de idioma integrado

biz.cache ()

SQL

sqlContext.cacheTable ("biz")

También puede almacenar en caché una tabla utilizando la instrucción CACHE TABLE, como se
muestra a continuación.

sqlContext.sql ("biz de CACHE TABLE")

Tener en cuenta que, a diferencia del almacenamiento en caché RDD, Spark SQL almacena
inmediatamente una tabla en caché cuando utiliza la instrucción CACHE TABLE.

Consulta de idioma integrado

cuenta val = biz.count ()

SQL

sqlContext.sql("SELECT count(1) as businesses FROM biz").show

Consulta de idioma integrado

val bizCountByState = biz.groupBy("state").count bizCountByState.show(50)

SQL

sqlContext.sql("SELECT state, count(1) as businesses FROM biz GROUP BY state").show(50)


UNIVERSIDAD UTE

A continuación, encontremos el recuento de empresas por estado y clasifiquemos el resultado


en orden descendente.

Consulta de idioma integrado

val resultDF = biz.groupBy("state").count

resultDF.orderBy($"count".desc).show(5)

sqlContext.sql("SELECT state, count(1) as businesses FROM biz GROUP BY state ORDER BY


businesses DESC").show(5)

solo se muestran las 5 filas principales

También podría haber escrito la versión de consulta integrada en el idioma de la siguiente


manera:

resultDF = biz.groupBy("state").count

resultDF.orderBy(resultDF("count").desc).show(5)

La diferencia entre la primera y la segunda versión es cómo hace referencia a la columna de


recuento en el marco de datos resultF. Puede pensar en $ "recuento" como acceso directo
para resultDF ("recuento"). Si un método o una función espera un argumento de tipo Columna,
UNIVERSIDAD UTE

puede usar cualquiera de las dos sintaxis. A continuación, encontremos cinco negocios con una
calificación de cinco estrellas.

Consulta de idioma integrado

biz.filter(biz("stars") <=> 5.0) .select("name","stars", "review_count", "city", "state")


.show(5)

SQL

sqlContext.sql("SELECT name, stars, review_count, city, state FROM biz WHERE


stars=5.0").show(5)

Consulta de idioma integrado

biz.filter($"stars" <=> 5.0 && $"state" <=> "NV") .select("name","stars", "review_count",


"city", "state") .show(3)

SQL

sqlContext.sql("SELECT name, stars, review_count, city, state FROM biz WHERE state = 'NV'
AND stars = 5.0").show(3)

Consulta de idioma integrado

biz.groupBy("state").sum("review_count").show()

SQL

sqlContext.sql("SELECT state, sum(review_count) as reviews FROM biz GROUP BY


state").show()
UNIVERSIDAD UTE

Consulta de idioma integrado

biz.groupBy("stars").count.show()

SQL

sqlContext.sql("SELECT stars, count(1) as businesses FROM biz GROUP BY stars").show()

Consulta de idioma integrado

val avgReviewsByState = biz.groupBy("state").avg("review_count") avgReviewsByState.show()

SQL

sqlContext.sql("SELECT state, AVG(review_count) as avg_reviews FROM biz GROUP BY


state").show()
UNIVERSIDAD UTE

Consulta de idioma integrado

biz.groupBy("state") .avg("review_count") .withColumnRenamed("AVG(review_count)",


"rc") .orderBy($"rc".desc) .selectExpr("state", "ROUND(rc) as avg_reviews") .show(5)

SQL

sqlContext.sql("SELECT state, ROUND(AVG(review_count)) as avg_reviews FROM biz GROUP


BY state ORDER BY avg_reviews DESC LIMIT 5").show()

Consulta de idioma integrado

biz.filter($"city" === "Las Vegas") .sort($"stars".desc, $"review_count".desc)


.select($"name", $"stars", $"review_count") .show(5)

SQL

sqlContext.sql("SELECT name, stars, review_count FROM biz WHERE city = 'Las Vegas' ORDER
BY stars DESC, review_count DESC LIMIT 5 ").show

A continuación, vamos a escribir los datos en formato Parquet.


UNIVERSIDAD UTE

biz.write.mode ("sobrescribir"). parquet ("ruta / a / yelp_business.parquet")

Puede leer los archivos de parquet creados en el paso anterior, como se muestra a
continuación.

val ybDF = sqlContext.read.parquet ("path / to / yelp_business.parquet")

Análisis interactivo con Spark SQL JDBC Server

Esta sección muestra cómo puede explorar el conjunto de datos de Yelp utilizando solo SQL /
HiveQL. Scala no se utiliza en absoluto. Para este análisis, utilizará el servidor Spark SQL Thrift /
JDBC / ODBC y el cliente Beeline. Ambos vienen preempacados con Spark. El primer paso es
iniciar el servidor Spark SQL Thrift / JDBC / ODBC desde un terminal. El directorio sbin de Spark
contiene una secuencia de comandos para iniciarlo.

ruta / a / spark / sbin / start-thriftserver.sh --master local [*]

El segundo paso es iniciar Beeline, que es un cliente CLI (interfaz de línea de comandos) para el
servidor Spark SQL Thrift / JDBC. Conceptualmente, es similar al cliente mysql para MySQL o el
cliente psql para PostgreSQL. Le permite escribir una consulta HiveQL, envía la consulta escrita
a un servidor Spark SQL Thrift / JDBC para su ejecución y muestra los resultados en la consola.
El directorio bin de Spark contiene una secuencia de comandos para iniciar Beeline. Vamos a
abrir otra terminal y lanzar Beeline.

path/to/spark/bin/beeline

Ahora debería estar dentro del shell de Beeline y ver el indicador de Beeline, como se muestra
a continuación.

Beeline versión 1.5.2 por Apache Hive beeline>

El tercer paso es conectarse al servidor Spark SQL Thrift / JDBC desde el shell de Beeline.

beeline>! connect jdbc: hive2: // localhost: 10000

El comando de conexión requiere una URL de JDBC. El puerto JDBC predeterminado para el
servidor Spark SQL Thrift / JDBC es 10000. Beeline le pedirá un nombre de usuario y una
contraseña. Ingrese el nombre de usuario que usa para iniciar sesión en su sistema y una
contraseña en blanco.

beeline> !connect jdbc:hive2://localhost:10000

scan complete in 26ms

Connecting to jdbc:hive2://localhost:10000

Enter username for jdbc:hive2://localhost:10000: your-user-name

Enter password for jdbc:hive2://localhost:10000:

Connected to: Spark SQL (version 1.5.2)


UNIVERSIDAD UTE

Driver: Spark Project Core (version 1.5.2)

Transaction isolation: TRANSACTION_REPEATABLE_READ 0: jdbc:hive2://localhost:10000>

En este punto, tiene una conexión activa entre el cliente Beeline y el servidor Spark SQL. Sin
embargo, el servidor Spark SQL aún no conoce el conjunto de datos de Yelp. Vamos a crear una
tabla temporal que apunta al conjunto de datos de Yelp.

0: jdbc:hive2://localhost:10000> CREATE TEMPORARY TABLE biz USING


org.apache.spark.sql.json OPTIONS (path "path/to/yelp_academic_dataset_business.json");

Asegúrese de reemplazar "ruta / a" con la ruta del directorio donde desempaquetó el conjunto
de datos de Yelp en su máquina. Spark SQL lanzará una excepción si no puede encontrar el
archivo en la ruta especificada. El comando CREAR TABLA TEMPORAL crea una tabla temporal
externa en el metastore de Hive. Solo existe una tabla temporal mientras se ejecuta el servidor
JDBC de Spark SQL.

0: jdbc:hive2://localhost:10000> SHOW TABLES;

0: jdbc:hive2://localhost:10000> SELECT count(1) from biz;

0: jdbc:hive2://localhost:10000> SELECT state, count(1) as cnt FROM biz GROUP BY state


ORDER BY cnt DESC LIMIT 5;

0: jdbc:hive2://localhost:10000> SELECT state, count(1) as businesses, sum(review_count) as


reviews FROM biz GROUP BY state ORDER BY businesses DESC LIMIT 5;
UNIVERSIDAD UTE

0: jdbc:hive2://localhost:10000> SELECT name, review_count, stars, city, state from biz WHERE
stars = 5.0 ORDER BY review_count DESC LIMIT 5;

Capítulo 8

Machine Learning with Spark

El interés por Machine Learning crece a pasos agigantados. Ha ganado mucho impulso en los
últimos Años por algunas razones. La primera razón son las mejoras de rendimiento en hardware
y algoritmos. Machine Learning es un cómputo-intensivo Con proliferación de máquinas multi-
CPU y multi-core que poseen algoritmos eficientes, se ha hecho factible hacer cálculos de
aprendizaje automático en un tiempo razonable.

La segunda razón es que el software de aprendizaje automático está disponible gratuitamente.


Muchos de buena calidad de código abierto.

La tercera razón es que los MOOCs (cursos en línea abiertos masivos) han creado una tremenda
conciencia sobre el aprendizaje automático. Estos cursos Se han democratizado los
conocimientos requeridos para utilizar el aprendizaje automático. Las habilidades de
aprendizaje automático no son ya está limitado a unas pocas personas con Ph.D. en estadística.
Cualquiera puede aprender y aplicar el aprendizaje automático.

¿Qué es?

El aprendizaje automático es la ciencia de entrenar un sistema para aprender a partir de datos


y actuar. La lógica que impulsa el comportamiento de un sistema basado en aprendizaje
automático no está programada explícitamente, sino que se aprende de los datos. Es decir,
entrenamos un sistema con datos en lugar de programar explícitamente su comportamiento.
Para ser específico, un algoritmo de aprendizaje automático infiere patrones y relaciones entre
diferentes Variables en un conjunto de datos. Luego utiliza ese conocimiento para generalizar
más allá del conjunto de datos de entrenamiento. En otras palabras, Un algoritmo de
aprendizaje automático aprende a predecir a partir de datos.
UNIVERSIDAD UTE

Características

Una característica representa un atributo o una propiedad de una observación. También se le


llama variable. una característica representa una variable independiente En un conjunto de
datos tabulares, una fila representa una observación y la columna representa una característica.
Cada campo en este conjunto de datos es una característica en el contexto del aprendizaje
automático. Cada fila que contiene un perfil de usuario es una observación. Las características
también se conocen colectivamente como dimensiones. Así, un conjunto de datos con alta
dimensionalidad tiene un Gran cantidad de características.

Características categóricas

Una característica categórica o variable es una característica descriptiva. Puede tomar uno de
un número fijo de discreto valores. Representa un valor cualitativo, que es un nombre o una
etiqueta. Los valores de una característica categórica no tienen orden.

Características numéricas

Una característica o variable numérica es una variable cuantitativa que puede tomar cualquier
valor numérico. Describe una cantidad medible como un número. Los valores en una
característica numérica tienen ordenamiento matemático. Un numero discreto es aquel que
solo puede tomar ciertos valores. Una característica numérica continua puede tomar cualquier
valor dentro de un intervalo finito o infinito.

Etiquetas

Una etiqueta es una variable que un sistema de aprendizaje automático aprende a predecir. Es
la variable dependiente en un conjunto de datos, Las etiquetas se pueden clasificar en dos
categorías amplias: categóricas y numéricas. Una etiqueta categórica representa una clase o
categoría. Una etiqueta numérica es una variable dependiente numérica.

Modelos

Un modelo es una construcción matemática para capturar patrones dentro de un conjunto de


datos. Se estima la relación entre las variables dependientes e independientes en un conjunto
de datos. Tiene capacidad predictiva. Dados los valores De las variables independientes, puede
calcular o predecir el valor de la variable dependiente, Un modelo es básicamente una función
matemática que toma características como entrada y genera un valor. Puede ser Representado
en el software de numerosas maneras. Un modelo junto con un algoritmo de aprendizaje
automático constituye el corazón de un sistema de aprendizaje automático. Un algoritmo de
aprendizaje automático enseña un modelo con datos; se ajusta a un modelo sobre un conjunto
de datos, para que el modelo pueda Predecir la etiqueta para una nueva observación. Capacitar
a un modelo es una tarea de computo intensiva, mientras que su uso no es tan intensivo en
computo. Un modelo lo general se guarda en el disco, de modo que se puede usar en el futuro
sin tener que pasar por el procesamiento intensivo pasando por la enseñanza de nuevo. Un
modelo serializado también se puede compartir con otras aplicaciones. una que entrena un
modelo y otra que usa un modelo.

Datos de Entrenamiento

Los datos utilizados por un algoritmo de aprendizaje automático para entrenar un modelo se
denominan datos de entrenamiento o conjunto de entrenamiento. Son Datos históricos o
UNIVERSIDAD UTE

conocidos, Los datos de entrenamiento se pueden clasificar en dos categorías: etiquetados y sin
etiquetar.

Etiquetados

Este conjunto de datos tiene una etiqueta para cada observación. Una de las columnas en el
conjunto de datos contiene las etiquetas.

Sin Etiquetar

Un conjunto de datos sin etiqueta no tiene una columna que se pueda usar como etiqueta.

Datos de prueba

Los datos utilizados para evaluar el rendimiento predictivo de un modelo se denominan datos
de prueba o conjunto de pruebas. Después de que el modelo ha sido entrenado, sus capacidades
predictivas deben probarse en un conjunto de datos conocido antes de usarse en nuevos datos.
Los datos de la prueba deben reservarse antes de entrenar un modelo. No debe utilizarse en
absoluto durante el entrenamiento. Debe probarse con datos que no se usaron para entrenarlo.
En general, una pequeña proporción de un conjunto de datos se retiene para probar antes de
entrenar un modelo. El porcentaje depende de una serie de factores, como el tamaño de un
conjunto de datos y el número de datos independientes. variables Una regla general es usar el
80% de los datos para entrenar un modelo y reservar un 20% como datos de prueba.

Aplicaciones de aprendizaje automático

 Clasificación
 Regresión
 agrupamiento
 Detección de anomalías
 Recomendación
 Reducción de dimensionalidad

Clasificación

El objetivo al resolver un problema de clasificación es predecir una clase o categoría para una
observación. Una clase Está representada por una etiqueta. Las etiquetas para las observaciones
en el conjunto de datos de entrenamiento son conocidas, y el objetivo es entrenar un modelo
que predice la etiqueta para una nueva observación sin etiqueta. Matemáticamente, en una
clasificación. un modelo predice el valor de una variable categórica. La clasificación es una tarea
común en muchos campos, El aprendizaje automático se puede utilizar para la clasificación tanto
binaria como multi clase. En la clasificación binaria, las observaciones en un conjunto de datos
pueden Ser agrupados en dos clases mutuamente excluyentes. Cada observación o muestra es
positiva o negativa.

Regresión

El objetivo al resolver un problema de regresión es predecir una etiqueta numérica para una
observación sin etiquetar. Las etiquetas numéricas son conocidas por las observaciones en el
conjunto de datos de entrenamiento y se entrena un modelo para predecir La etiqueta para una
nueva observación.

Agrupamiento
UNIVERSIDAD UTE

En la agrupación en clúster, un conjunto de datos se divide en un número específico de clústeres


o segmentos. Los Elementos en el cluster. son más similares entre sí que a los de otros grupos.
El número de grupos depende de la solicitud. La agrupación se utiliza sin etiqueta de conjuntos
de datos Además, aunque un algoritmo de agrupación agrupa un conjunto de datos en un
número específico de agrupaciones, No asigna una etiqueta a ningún grupo. Un usuario tiene
que determinar qué representa cada grupo.

Detección de anomalías

En la detección de anomalías, el objetivo es encontrar valores atípicos en un conjunto de datos.


El supuesto subyacente es que un valor atípico Representa una observación anómala. Los
algoritmos de detección de anomalías se utilizan con datos sin etiquetar. La detección de
anomalías tiene muchas aplicaciones en diferentes campos.

Recomendación

El objetivo de un sistema de recomendación es recomendar un producto para un usuario.


Aprende del comportamiento pasado de los usuarios para determinar sus preferencias. Un
usuario califica diferentes productos, y Con el tiempo, un sistema de recomendaciones aprende
las preferencias de este usuario. En algunos casos, Los sistemas de recomendación se utilizan
para recomendar noticias. Artículos, películas, programas de televisión, canciones, libros y otros
productos. Las dos técnicas más utilizadas para construir sistemas de recomendación son el
filtrado colaborativo. y la recomendación basada en el contenido. En el filtrado colaborativo, las
propiedades de un producto o usuario. Las preferencias no están programadas explícitamente.
El algoritmo asume que las preferencias y productos del usuario tienen características latentes,
que aprende automáticamente de las calificaciones de diferentes productos de diferentes
usuarios. El conjunto de datos de entrada está en un formato tabular, donde cada fila contiene
solo una identificación de usuario, una identificación de producto y una calificación. El filtrado
colaborativo aprende el usuario latente y la característica del producto solo desde estos tres
campos. Aprende los usuarios Con preferencias similares y productos con propiedades similares.
El modelo entrenado puede ser usado para Recomendar productos a un usuario. Los productos
recomendados para un usuario son aquellos altamente calificados por otros usuarios con
preferencias similares. Un sistema de recomendación basado en contenido usa propiedades del
producto explícitamente especificadas para determinar Similitud de productos y
recomendaciones.

Reducción de dimensionalidad

La reducción de la dimensionalidad es una técnica útil para reducir el costo y el tiempo que toma
entrenar una máquina sistema de aprendizaje, El aprendizaje automático es una tarea de
computo intensiva. La complejidad del cálculo y los aumentos de costes. con el número de
características o dimensiones en un conjunto de datos. El objetivo en la reducción de la
dimensionalidad es reducir el Número de características en un conjunto de datos sin afectar
significativamente el rendimiento predictivo de un modelo. Un conjunto de datos puede tener
tantas dimensiones que es prohibitivamente caro usarlo para el aprendizaje automático, La idea
básica detrás de la reducción de dimensionalidad es que un conjunto de datos puede tener
varias características que tienen poca o cero poder predictivo. Un algoritmo de reducción de
dimensionalidad elimina automáticamente estas características de un conjunto de datos. Solo
las características con mayor poder predictivo se utilizan para el aprendizaje automático. Así, la
dimensionalidad. Las técnicas de reducción reducen la complejidad computacional y el costo del
aprendizaje automático.
UNIVERSIDAD UTE

Algoritmos de aprendizaje automático

Los algoritmos de aprendizaje automático utilizan datos para entrenar un modelo. El proceso de
entrenamiento de un modelo también se conoce como Ajustando un modelo con datos. En otras
palabras, un algoritmo de aprendizaje automático se ajusta a un modelo en un conjunto de datos
de entrenamiento. Dependiendo del tipo de datos de entrenamiento, los algoritmos de
aprendizaje automático se agrupan en dos Categorías, Aprendizaje automático supervisado y no
supervisado.

Algoritmos supervisados de aprendizaje automático

Un algoritmo de aprendizaje automático supervisado entrena un modelo con un conjunto de


datos etiquetado. Se puede usar solo con conjuntos de datos de entrenamiento etiquetados.
Cada observación en el conjunto de datos de entrenamiento tiene un conjunto de características
y una etiqueta. La variable dependiente, también conocida como la variable de respuesta,
representa la etiqueta. Las variables independientes, también conocidas como explicativas. o
variables predictoras, representan las características. Un algoritmo de aprendizaje automático
supervisado aprende de los datos a estimar o aproximar la relación entre una variable de
respuesta y una o más variables predictoras. Las etiquetas en un conjunto de datos de
entrenamiento pueden generarse manualmente o provenir de otro sistema Los algoritmos
supervisados de aprendizaje automático se pueden agrupar en dos categorías: regresión y
algoritmos de clasificación.

Algoritmos de regresión

Un algoritmo de regresión entrena un modelo con un conjunto de datos que tiene una etiqueta
numérica. El modelo entrenado puede entonces Predecir etiquetas numéricas para nuevas
observaciones sin etiquetar. Según la cantidad de predictor y las variables de respuesta, las
tareas de regresión se pueden agrupar en tres Categorías: Regresión simple, múltiple y
multivariable. La regresión simple implica una respuesta y una variable predictor La regresión
múltiple implica una respuesta y múltiples variables predictoras. Multivariable La regresión
implica varias respuestas y varias variables predictoras.

Regresión lineal

Los algoritmos de regresión lineal se ajustan a un modelo lineal con coeficientes utilizando datos
de entrenamiento. Un modelo lineal es un Combinación lineal de un conjunto de coeficientes y
variables explicativas. El algoritmo estima lo desconocido. Coeficientes, también conocidos
como parámetros del modelo, a partir de datos de entrenamiento. Los coeficientes ajustados
minimizan la suma. de los cuadrados de la diferencia entre las etiquetas observadas
pronosticadas y reales en el conjunto de datos de entrenamiento. Un ejemplo simple de un
modelo lineal se muestra aquí.
UNIVERSIDAD UTE

Regresión isotónica

El algoritmo de regresión isotónica ajusta una función no decreciente a un conjunto de datos de


entrenamiento. Encuentra lo mejor los mínimos cuadrados se ajustan a un conjunto de datos de
entrenamiento con la restricción de que el modelo entrenado no debe disminuir función. Una
función de mínimos cuadrados minimiza la suma de los cuadrados de la diferencia entre la
predicción y Etiquetas reales en el conjunto de datos de formación. A diferencia de la regresión
lineal, el algoritmo de regresión isotónica no asume cualquier forma para la función objetivo,
como la linealidad.

Árboles de decisión

El algoritmo del árbol de decisión infiere un conjunto de reglas de decisión de un conjunto de


datos de entrenamiento. Esencialmente, crea un árbol de decisión que se puede usar para
predecir la etiqueta numérica de una observación.

Conjuntos

Aunque el algoritmo del árbol de decisión tiene muchas ventajas, también tiene una gran
desventaja. Los árboles no tienen el mismo nivel de precisión predictiva que los modelos
UNIVERSIDAD UTE

entrenados con algoritmos que son más sofisticado. Este problema se resuelve utilizando una
colección de árboles de decisión en lugar de solo uno árbol de decisión.

Los algoritmos de aprendizaje automático que combinan múltiples modelos para generar un
modelo más poderoso. Se llaman algoritmos de aprendizaje conjunto. Un modelo entrenado por
un algoritmo de aprendizaje conjunto combina las predicciones de varios modelos base para
mejorar la generalización y la precisión predictiva en un solo modelo. Los algoritmos de
aprendizaje en conjunto se encuentran entre los de mejor desempeño en tareas de clasificación
y regresión.

• Bosques aleatorios. El algoritmo de bosque aleatorio entrena cada árbol de decisión en una
Ensamble de forma independiente utilizando una muestra aleatoria de datos. El árbol se entrena
usando un subconjunto de las características. El número de árboles en un conjunto es de El
orden de los cientos. Random Forest crea un modelo de conjunto que tiene un mejor
rendimiento predictivo que el de un modelo de árbol de decisión único. Para una tarea de
regresión, un modelo de bosque aleatorio toma un vector de entidad de entrada y obtiene una
predicción de cada árbol de decisión en el conjunto. Promedia en Las etiquetas numéricas
devuelven todos los árboles y devuelven el promedio según su predicción.

• Árboles impulsados por gradiente. El algoritmo de árboles impulsados por gradiente (GBT)
también entrena Un conjunto de árboles de decisión. Sin embargo, entrena secuencialmente
cada árbol de decisión. Optimiza cada nuevo árbol utilizando información de árboles
previamente entrenados. Así, El modelo se vuelve mejor con cada nuevo árbol. GBT puede
tardar más en entrenar un modelo, ya que entrena un árbol a la vez. Adicionalmente, es
propenso a sobre ajustar si se utiliza una gran cantidad de árboles en un conjunto. Sin embargo,
cada árbol en un conjunto GBT puede ser poco profundo, que es más rápido para entrenar

Algoritmos de clasificación

Los algoritmos de clasificación entrenan modelos que predicen valores categóricos. La variable
dependiente o de respuesta en El conjunto de datos de entrenamiento es una variable
categórica. En otras palabras, la etiqueta es una variable categórica. El modelo entrenado por
un algoritmo de clasificación puede ser un clasificador binario, de clases múltiples o de etiquetas
múltiples. Un clasificador binario clasifica las observaciones en dos categorías: positivo o
negativo. La etiqueta predicha tiene solo dos clases. Un clasificador de clases múltiples predice
una etiqueta que puede tener más de dos clases. Por ejemplo, una multi-clase El clasificador se
puede utilizar para clasificar imágenes de animales. La etiqueta en este ejemplo puede ser cat,
dog, hamster, lion, o algún otro animal. Un clasificador de etiquetas múltiples puede generar
más de una etiqueta para la misma observación. Por ejemplo, un El clasificador que clasifica los
artículos de noticias puede generar más de una etiqueta para un artículo relacionado con ambos.
deportes y negocios Los algoritmos de aprendizaje automático supervisado que se utilizan
comúnmente para tareas de clasificación incluyen los siguientes algoritmos.

Regresión logística

El algoritmo de regresión logística entrena un modelo lineal que puede usarse para tareas de
clasificación. Específicamente, El modelo generado puede usarse para predecir la probabilidad
de ocurrencia de un evento.
UNIVERSIDAD UTE

Máquina de vectores de soporte (SVM)

El algoritmo de la Máquina de vectores de soporte (SVM) entrena un clasificador óptimo.


Conceptualmente, se aprende de un entrenamiento del conjunto de datos un hiperplano óptimo
para clasificar un conjunto de datos. Encuentra el mejor hiperplano. que separa las
observaciones de entrenamiento de una clase de las de la otra clase. Los vectores de soporte
son los Los vectores de características más cercanos al hiperplano de separación.

Naïve Bayes

El algoritmo Naïve Bayes usa el teorema de Bayes para entrenar a un clasificador. El modelo
entrenado por los ingenuos bayes. El algoritmo es un clasificador probabilístico. Para una
observación dada, calcula una distribución de probabilidad sobre un conjunto de clases.

Árboles de decisión

El algoritmo del árbol de decisión se cubrió en la sección que cubre los algoritmos de regresión.
Como se mencionó Anteriormente, los árboles de decisión se pueden utilizar para las tareas de
regresión y clasificación. El algoritmo trabaja el de la misma manera en ambos casos, excepto
por una cosa: los valores almacenados en los nodos terminales (hoja). Para las tareas de
regresión, cada nodo terminal almacena un valor numérico; Mientras que para las tareas de
clasificación, cada El nodo terminal almacena una etiqueta de clase. Múltiples hojas pueden
tener la misma etiqueta de clase. Para predecir una etiqueta para una En la observación, un
modelo de árbol de decisión comienza en el nodo raíz de un árbol de decisión y prueba las
características en comparación con Nodos internos hasta que llega a un nodo hoja. El valor en
el nodo hoja es la etiqueta predicha

Conjuntos

Los algoritmos de Conjunto como Random Forests y Gradient-Boosted Trees también se pueden
usar para tareas de clasificación. La lógica para predecir una etiqueta de clase utilizando Random
Forests es diferente para las tareas de clasificación. Cualquiera El modelo de bosques recopila
las predicciones de su conjunto de árboles de decisión y genera la etiqueta de clase predicho
por el número máximo de árboles según su predicción.
UNIVERSIDAD UTE

Red neuronal

Los algoritmos de redes neuronales están inspirados en redes neuronales biológicas. Intentan
imitar el cerebro. Un comúnmente El algoritmo de red neuronal utilizado para las tareas de
clasificación es la red neuronal de avance. Un clasificador entrenado por El algoritmo de red
neuronal feedforward también se conoce como un clasificador de perceptrón multicapa.

Algoritmos de aprendizaje automático no supervisados

Se utiliza un algoritmo de aprendizaje automático no supervisado cuando un conjunto de datos


no está etiquetado. Extrae inferencias de conjuntos de datos sin etiqueta. En general, el objetivo
es encontrar una estructura oculta en datos sin etiquetar. Los algoritmos de aprendizaje se usan
generalmente para agrupamiento, detección de anomalías y reducción de dimensionalidad. La
lista de algoritmos de aprendizaje automático no supervisados de uso común incluye k-means,
Principal Análisis de componentes y descomposición de valores singulares.

Error cuadrático medio (RMSE)

La métrica RMSE se usa generalmente para evaluar modelos generados por algoritmos de
regresión. Un relacionado La métrica es el error cuadrático medio (MSE). Un error en el contexto
de un algoritmo de regresión es la diferencia. entre la etiqueta numérica real y predicha de una
observación. Como su nombre lo indica, MSE es la media. Del cuadrado de los errores. Se calcula
matemáticamente al cuadrar el error para cada observación y calculando la media del cuadrado
de los errores. RMSE se calcula matemáticamente tomando una raíz cuadrada de MSE. RMSE y
MSE representan error de entrenamiento. Indican qué tan bien un modelo se ajusta a un
conjunto de entrenamiento. Ellos capturan la discrepancia entre las etiquetas observadas y las
etiquetas predichas por un modelo. Un modelo con un MSE o RMSE más bajo representa un
mejor modelo de ajuste que uno con un MSE o RMSE más alto.

Integración con otras bibliotecas Spark

MLlib se integra con otras bibliotecas Spark como Spark Streaming y Spark SQL. Puede ser
utilizado tanto con datos por lotes como de transmisión.

Los pasos de preparación de datos, como la limpieza de datos y la ingeniería de características,


se hacen más fáciles con la API de DataFrame proporcionada por Spark SQL. En general, los datos
UNIVERSIDAD UTE

en bruto no se pueden utilizar directamente con la máquina algoritmos de aprendizaje. Las


características deben ser extraídas de los datos en bruto.

Utilidades estadísticas

MLlib proporciona clases y funciones para el análisis estadístico común. Es compatible con
estadísticas de resumen, correlaciones, muestreo estratificado, pruebas de hipótesis,
generación de datos aleatorios y estimación de la densidad del núcleo.

Algoritmos de aprendizaje automático

MLlib se puede utilizar para tareas comunes de aprendizaje automático, como regresión,
clasificación, agrupación, Detección de anomalías, reducción de dimensionalidad y
recomendación. La lista de algoritmos que vienen. Liado con MLlib está en constante
crecimiento. Esta sección enumera los algoritmos enviados con MLlib en el momento de
escribiendo este libro.

Regresión y Clasificación

 Regresión lineal
 Regresión logística
 Máquinas de vectores soporte
 Naïve Bayes
 Árbol de decisión
 Bosque aleatorio
 Árboles de gradiente
 Regresión isotónica

Agrupación

 K-significa
 Streaming k-means
 Mezcla gaussiana
 Agrupación de iteración de energía (PIC)
 Asignación de Dirichlet latente (LDA)

Reducción de dimensionalidad

 Análisis de componentes principales (PCA)


 Descomposición en valores singulares (SVD)

Extracción y transformación de características

 TF-IDF
 Word2Vec
 Escalador estándar
 Normalizador
 Selección de características de Chi-cuadrado
 Producto elementwise

Frequent pattern mining

 FP-growth
UNIVERSIDAD UTE

 Association rules
 PrefixSpan

Recommendation

 Collaborative filtering with Alternating Least Squares (ALS)

La API de MLlib

La biblioteca MLlib se puede usar con aplicaciones desarrolladas en Scala, Java, Python o R. Esta
sección cubre la versión de Scala de la API de MLlib. Las clases y los objetos singleton
proporcionados por MLlib están disponibles en el paquete org.apache.spark.mllib

Puede probar los ejemplos de código que se muestran en esta sección en el Spark REPL. Vamos
a lanzar el shell Spark desde una terminal.

ruta / a / SPARK_HOME / bin / spark-shell --master local [*]

Tipos de datos

Las abstracciones de datos primarios de MLlib son Vector, LabeledPoint y Rating. Los algoritmos
de aprendizaje automático y las utilidades estadísticas en MLlib operan sobre datos
representados por estas abstracciones.

Vector

El tipo Vector representa una colección indexada de valores de tipo Doble con índice de tipo
cero basado en cero. Generalmente se usa para representar las características de una
observación en un conjunto de datos. Conceptualmente, un vector de longitud n representa una
observación con n características. En otras palabras, representa un elemento en una espacio n-
dimensional.

El tipo de Vector proporcionado por MLlib no debe confundirse con el tipo de Vector en la
colección Scala biblioteca. Ellos son diferentes. El tipo MLlib Vector implementa el concepto de
vector numérico de lineal álgebra. Una aplicación debe importar
org.apache.spark.mllib.linalg.Vector para usar el rasgo vectorial proporcionado por MLlib.

La biblioteca MLlib admite dos tipos de vectores: densos y dispersos. Se define el tipo de vector
MLlib como un rasgo, por lo que una aplicación no puede crear directamente una instancia de
Vector. En su lugar, debe utilizar la fábrica. Métodos proporcionados por MLlib para crear una
instancia de la clase DenseVector o SparseVector. Estas dos clases implementan el rasgo
vectorial. Los métodos de fábrica para crear una instancia de DenseVector o ña clase
SparseVector se define en el objeto de vectores.

DenseVector

Una instancia de la clase DenseVector almacena un valor de tipo doble en cada posición del
índice. Está respaldado por una formación. Generalmente se usa un vector denso si un conjunto
de datos no tiene demasiados valores de cero. Se puede crear, como se muestra aquí.

importar org.apache.spark.mllib.linalg._ val denseVector = Vectors.dense (1.0, 0.0, 3.0)

El método denso crea una instancia de la clase DenseVector a partir de los valores
proporcionados como argumentos Una variante del método denso toma un tipo Array of Double
como argumento y devuelve una instancia de la clase DenseVector.
UNIVERSIDAD UTE

SparseVector

La clase SparseVector representa un vector disperso, que almacena solo valores distintos de
cero. Es un dato eficiente.

Escriba para almacenar un conjunto de datos grande con muchos valores cero. Una instancia de
la clase SparseVector está respaldada por dos matrices; uno almacena los índices para valores
distintos de cero y el otro almacena los valores distintos de cero.

Se puede crear un vector disperso, como se muestra aquí.

importar org.apache.spark.mllib.linalg._ val sparseVector = Vectors.sparse (10, Array (3, 6),


Array (100.0, 200.0))

El método disperso devuelve una instancia de la clase SparseVector. El primer argumento a los
escasos método es la longitud de un vector disperso. El segundo argumento es una matriz que
especifica los índices para valores distintos de cero entradas. El tercer argumento es una matriz
que especifica los valores. Los índices y la matriz de valores deben tener la mismo largo.

Alternativamente, se puede crear un vector disperso especificando su longitud, y las entradas


que no sean cero junto con Sus posiciones, como se muestra aquí.

importar org.apache.spark.mllib.linalg._val sparseVector = Vectors.sparse (10, Seq ((3, 100.0),


(6, 200.0)))

LabeledPoint

El tipo LabeledPoint representa una observación en un conjunto de datos etiquetado. Contiene


tanto la etiqueta (dependiente variable) y características (variables independientes) de una
observación. La etiqueta se almacena como un valor de tipo doble y las características se
almacenan como un tipo de vector.

Un RDD de LabeledPoints es la abstracción principal de MLlib para representar un conjunto de


datos etiquetado. Ambos algoritmos de regresión y clasificación proporcionados por MLlib
operan solo en RDD de LabeledPoints.

Por lo tanto, un conjunto de datos debe transformarse en un RDD de LabeledPoints antes de


que pueda usarse para entrenar un modelo. Dado que el campo de etiqueta en un LabeledPoint
es de tipo Doble, puede representar tanto numérica como categóricas etiquetas. Cuando se
utiliza con un algoritmo de regresión, la etiqueta en un LabeledPoint almacena un valor
numérico por clasificación binaria, una etiqueta debe ser 0 o 1. 0 representa una etiqueta
negativa y 1 representa una positiva etiqueta.

Para la clasificación de múltiples clases, una etiqueta almacena un índice de clase basado en
cero de una observación. Los puntos etiquetados se pueden crear, como se muestra aquí.

importar org.apache.spark.mllib.linalg.Vectors

importar org.apache.spark.mllib.regression.LabeledPoint

val positivo = LabeledPoint (1.0, Vectors.dense (10.0, 30.0, 20.0))

val negativo = LabeledPoint (0.0, Vectors.sparse (3, Array (0, 2), Array (200.0, 300.0)))

Este código crea dos LabeledPoints. El primer LabeledPoint representa una observación positiva
con
UNIVERSIDAD UTE

tres caracteristicas El segundo LabeledPoint representa una observación negativa con tres
características.

Clasificación

El tipo de calificación se utiliza con algoritmos de recomendación. Representa la calificación de


un usuario para un producto o artículo. Un conjunto de datos de entrenamiento debe
transformarse en un RDD de Calificaciones antes de que se pueda usar para entrenar a un
modelo de recomendación.

La calificación se define como una clase de caso que consta de tres campos. El primer campo se
denomina usuario, que es de tipo En t. Representa un identificador de usuario. El segundo
campo se denomina producto, que también es de tipo Int. Representa un identificador de
producto o artículo. El tercer campo se denomina calificación, que de tipo doble.

Se puede crear una instancia de Clasificación, como se muestra aquí.

importar org.apache.spark.mllib.recommendation._

val rating = Rating (100, 10, 3.0)

Este código crea una instancia de la clase de calificación. Esta instancia representa una
calificación de 3.0 dada por un usuario con identificador 100 a un producto con identificador 10.

Algoritmos y Modelos

Esta sección describe brevemente las abstracciones de MLlib para representar algoritmos de
aprendizaje automático y modelos

Un modelo en MLlib está representado por una clase. MLlib ofrece diferentes clases para
representar modelos. Formado con diferentes algoritmos de aprendizaje automático.

Del mismo modo, un algoritmo de máquina está representado por una clase. MLlib también
proporciona generalmente un compañero. Objeto singleton con el mismo nombre para cada
clase de algoritmo de aprendizaje automático. Es más conveniente para entrenar un modelo
utilizando un objeto singleton que representa un algoritmo de aprendizaje automático.

Entrenar y usar un modelo generalmente involucra dos métodos clave: entrenar y predecir. El
metodo de tren es proporcionado por los objetos singleton que representan algoritmos de
aprendizaje automático. Se entrena un modelo con un determinado conjunto de datos y
devuelve una instancia de una clase de modelo específica de algoritmo. El método de predicción
es proporcionado por las clases representativas de modelos. Devuelve una etiqueta para un
conjunto dado de características.

Spark viene preempaquetado con conjuntos de datos de muestra que pueden usarse para
experimentar con la API de MLlib. Por la simplicidad, los ejemplos utilizan esos conjuntos de
datos de muestra.

Algunos de los archivos de datos están en formato LIBSVM. Cada línea almacena una
observación. La primera columna es una etiqueta. Le siguen las características, que se
representan como offset: valor, donde offset es el índice en el vector de entidad, y valor es el
valor de una entidad.
UNIVERSIDAD UTE

La biblioteca MLlib proporciona funciones de ayuda que crean RDD [LabeledPoint] a partir de
archivos que contienen datos etiquetados en el formato LIBSVM. Estos métodos los proporciona
el objeto MLUtils, que está disponible en

el paquete org.apache.spark.mllib.util

Algoritmos de regresión

La lista de clases MLlib que representan diferentes algoritmos de regresión incluye


LinearRegressionWithSGD, RidgeRegressionWithSGD, LassoWithSGD, ElasticNetRegression,
IsotonicRegression, DecisionTree, GradientBoostedTrees, y RandomForest. MLlib también
proporciona objetos singleton complementarios con los mismos nombres Estas clases y objetos
proporcionan métodos para entrenar modelos de regresión. Esta sección describe los métodos
proporcionados por los objetos singleton para entrenar un modelo.

Entrenar

El método de tren de un objeto de algoritmo de regresión entrena o ajusta un modelo de


regresión lineal con un conjunto de dato se le proporciona como entrada. Toma un RDD de
LabeledPoints como argumento y devuelve un algoritmo específico modelo de regresión. Por
ejemplo, el método de tren en el objeto LinearRegressionWithSGD devuelve una instancia de la
clase LinearRegressionModel. Del mismo modo, el método de tren en el objeto DecisionTree
devuelve una instancia de la clase DecisionTreeModel.

El método del tren también toma unos pocos parámetros adicionales específicos del algoritmo
como argumentos. por ejemplo, el método del tren en el objeto RidgeRegressionWithSGD toma
como argumentos el número de iteraciones de pendiente de gradiente a ejecutar, tamaño de
paso para cada iteración de pendiente de gradiente, parámetro de regularización, fracción de
datos a utilizar en cada iteración y conjunto inicial de ponderaciones. Del mismo modo, el
método del tren en el objeto GradientBoostedTrees toma una estrategia de impulso como un
argumento.

El siguiente ejemplo muestra cómo entrenar un modelo con LinearRegressionWithSGD. Puedes


usar los otros algoritmos de regresión de forma similar.

trenRegresor

El método trainRegressor es proporcionado por los objetos singleton que representan


algoritmos basados en árboles tales como DecisionTree y RandomForest. Entrena o ajusta un
modelo de regresión no lineal con un conjunto de datos proporcionado a ella como entrada.
Toma un RDD de LabeledPoint e hiperparámetros específicos de algoritmo como argumentos.

Por ejemplo, en el caso de RandomForest, toma como argumentos el número de árboles, la


profundidad máxima de un árbol, número máximo de contenedores, semillas aleatorias para
arranque, características categóricas y número de funciones para considere las divisiones en
cada nodo.

El método trainRegressor devuelve un modelo de regresión no lineal específico del algoritmo.


Por ejemplo, el método trainRegressor en el objeto DecisionTree devuelve una instancia de
UNIVERSIDAD UTE

DecisionTreeModel clase. De manera similar, el método trainRegressor en el objeto


RandomForest devuelve una instancia de Clase RandomForestModel.

El siguiente ejemplo muestra cómo entrenar un modelo con RandomForest. Usaremos lo mismo
conjunto de datos que utilizamos anteriormente para entrenar un modelo con
LinearRegressionWithSGD

Modelos de regresión

Las clases que representan modelos de regresión incluyen LinearRegressionModel,


RidgeRegressionModel, LassoModel, IsotonicRegressionModel, DecisionTreeModel,
GradientBoostedTreesModel, y RandomForestModel.

Las instancias de estas clases son devueltas por los métodos trainRegressor del train o train de
los objetos mencionados en la sección anterior.Los métodos comúnmente utilizados en estas
clases se describen brevemente a continuación.

Predecir

El método de predicción de un modelo de regresión devuelve una etiqueta numérica para un


conjunto dado de características. Toma un Vector como argumento y devuelve un valor de tipo
Double. Una variante del método de predicción toma un RDD de Vector como argumento y
devuelve un RDD de Doble. Por lo tanto, se puede utilizar para predecir una etiqueta para una
observación o un conjunto de datos.

Salvar

El método de guardar persiste un modelo entrenado a disco. Toma un SparkContext y una ruta
como argumentos y guarda el modelo de origen a la ruta dada. El modelo guardado se puede
leer más tarde con el método de carga.

Carga

El método de carga se define en los objetos del modelo complementario. Genera una instancia
de un modelo desde un Modelo previamente guardado. Toma como argumentos un
SparkContext y la ruta a un modelo guardado y devuelve una instancia de una clase modelo.

Algoritmos de clasificación

La lista de clases de MLlib que representan diferentes algoritmos de clasificación incluye


LogisticRegressionWithSGD, LogisticRegressionWithLBFGS, SVMWithSGD, NaiveBayes,
DecisionTree, GradientBoostedTrees, y RandomForest. MLlib también proporciona objetos
singleton complementarios con los mismos nombres Estas clases y objetos proporcionan
métodos para entrenar modelos de clasificación, que también se mencionan a como
clasificadores.

Esta sección describe brevemente los métodos proporcionados por los objetos singleton que
representan la clasificación algoritmos para entrenar un modelo.

Modelos de clasificación

Las clases que representan modelos de clasificación incluyen LogisticRegressionModel,


NaiveBayesModel, SVMModel, DecisionTreeModel, GradientBoostedTreesModel y
RandomForestModel. Instancias de estas clases son devueltas por los métodos train o
UNIVERSIDAD UTE

trainClassifier de la clasificación correspondiente algoritmos Los métodos comúnmente


utilizados de estas clases se describen brevemente a continuación.

Predecir

El método de predicción devuelve una clase o etiqueta categórica para un conjunto dado de
características. Toma un vector como un argumento y devuelve un valor de tipo doble.

Algoritmos de agrupamiento

La lista de clases MLlib que representan diferentes algoritmos de agrupamiento incluye KMeans,
StreamingKMeans, GaussianMixture, LDA, y PowerIterationClustering. MLlib también
proporciona objetos singleton complementarios con los mismos nombres.

A continuación, se describen brevemente los métodos proporcionados para los modelos de


formación de grupos.

Correr

El método de ejecución es proporcionado por las clases relacionadas con la agrupación. Similar
al método del tren, toma un RDD de Vector como argumento y devuelve un modelo específico
de algoritmo. Para el ejemplo, el método de ejecución en la clase PowerIterationClustering
devuelve una instancia de la clase PowerIterationClusteringModel.

El siguiente código de ejemplo utiliza una instancia de la clase KMeans para entrenar un
KMeansModel.

Modelos de clustering

Las clases que representan modelos de agrupamiento incluyen KMeansModel,


GaussianMixtureModel, PowerIterationClusteringModel, StreamingKMeansModel y
DistributedLDAModel. Instancias de estos las clases son devueltas por los métodos de tren de
los objetos relacionados con el algoritmo de agrupación y los métodos de ejecución de clases
relacionadas con algoritmos de clustering.

Los métodos comúnmente utilizados de la clase KMeansModel se describen brevemente a


continuación.

Predecir

El método de predicción devuelve un índice de agrupación para una observación dada. Toma un
vector como argumento y devuelve un valor de tipo int. El siguiente código de ejemplo
determina los índices de cluster para un par de observaciones usando El KMeansModel entrenó
antes.

val obs1 = Vectors.dense (0.0, 0.0, 0.0)

val obs2 = Vectors.dense (9.0, 9.0, 9.0)

Algoritmos de recomendación

MLlib admite el filtrado colaborativo, que aprende los factores latentes que describen a los
usuarios y productos de un conjunto de datos que contiene solo identificadores de usuario,
identificadores de producto y calificaciones. Basado en el filtrado colaborativo se puede
UNIVERSIDAD UTE

desarrollar un sistema de recomendaciones en MLlib usando el algoritmo ALS (alternar mínimos


cuadrados).

MLlib proporciona una clase denominada ALS, que implementa la factorización de matriz de
mínimos cuadrados alternos. También proporciona un objeto singleton compañero con el
mismo nombre.

MLlib admite tanto valoraciones como comentarios implícitos. Una calificación está disponible
cuando un usuario califica explícitamente un producto. Por ejemplo, los usuarios califican
películas y programas en Netflix. Del mismo modo, los usuarios califican canciones en iTunes,
Spotify, Pandora, y otros servicios de música. Sin embargo, a veces una calificación explícita no
está disponible, pero una implícita la preferencia puede ser determinada a partir de las
actividades del usuario.

Por ejemplo, la compra de un producto por un usuario transmite la retroalimentación implícita


del usuario para un producto. De forma similar, un usuario proporciona comentarios implícitos
para un producto haciendo clic en un botón de me gusta o compartir los métodos
proporcionados por el objeto ALS para entrenar un modelo de recomendación se describen
brevemente a continuación

Modelos de recomendación
Un modelo de recomendación está representado por una instancia de la clase
MatrixFactorizationModel. MLLib también proporciona un objeto compañero con el mismo
nombre. Los métodos comúnmente utilizados se describen brevemente a continuación.
Método predecir.
El método de predicción en la clase MatrixFactorizationModel devuelve una calificación para un
usuario y producto dados. Este método va a tomar una identificación de usuario y una
identificación de producto, que son de tipo Int, como argumentos y devuelve una calificación,
que es de tipo “Double”. Una variante del método de predicción acepta un RDD de pares de ID
de usuario e ID de producto y devuelve un RDD de Clasificación. Por lo tanto, se puede usar para
predecir tanto la calificación para un solo par de producto-usuario o una lista de pares de
producto-usuario.
Método RecommendProducts.
Este método recomienda el número especificado de productos para un usuario determinado. Lo
que hace es tomar un ID de usuario y número de productos para recomendar como argumentos
y devuelve una matriz de clasificación. Cada calificación del objeto incluye la identificación de
usuario, la identificación del producto y una puntuación de calificación pronosticada. La matriz
devuelta está ordenada por puntuación en orden descendente y nos indica que una puntuación
alta tiene una recomendación fuerte.
Método recommendProductsForUsers.
Este método recomienda el número especificado de productos principales para todos los
usuarios, lo que hace es tomar la cantidad de productos para recomendar como argumento y
devuelve un RDD de usuarios con los mejores productos recomendados correspondientes.
Método recommendUsers.
Este método recomienda el número especificado de usuarios para un producto determinado. Lo
que nos devuelve este método es una lista de los usuarios que tienen más probabilidades de
estar interesados en un producto determinado. Se necesita un número de identificación del
UNIVERSIDAD UTE

producto de los usuarios para recomendar como argumentos y devuelve una matriz de
calificación.
Método recommendUsersForProducts.
Este método recomienda el número especificado de usuarios para todos los productos. Lo que
hace es tomar la cantidad de usuarios para recomendar como argumento y devuelve un RDD de
productos y los mejores usuarios recomendados correspondientes.

Método Save.
Este método toma un SparkContext y una ruta como argumentos y guarda el modelo de origen
a la ruta dada. El modelo guardado puede leerse posteriormente con la carga.

Método Load.
El método Load se puede utilizar para leer previamente el modelo guardado de un archivo. Este
modelo también toma un SparkContext y la ruta a un modelo guardado y devuelve una instancia
de la clase MatrixFactorizationModel.

Evaluación del modelo.


Evaluar un modelo de aprendizaje automático antes de usarlo con datos nuevos es un paso
importante que se debe realizar. No es necesario calcular manualmente las métricas
cuantitativas que evalúan la efectividad del modelo. MLlib viene pre empaquetado con clases
que facilitan la evaluación de modelos.

Métricas de regresión.
Tenemos la clase RegressionMetrics la cual se puede usar para evaluar modelos generados por
algoritmos de regresión. Esto lo que va a hacer es proporcionarnos métodos para calcular el
error cuadrático medio, error cuadrático medio, error absoluto medio, R2, y otras métricas.

Métricas de clasificación binaria.


Esta clase BinaryClassificationMetrics se puede usar para evaluar clasificadores binarios, y lo que
nos proporciona son métodos para calcular la curva de características operativas del receptor
(ROC), área debajo del receptor operativa curva característica (AUC), y otras métricas.

Métricas de clasificación multiclase.


Esta clase se puede usar para evaluar clasificadores multi-clase o multi-nominal. En una tarea de
clasificación multi-clase, una etiqueta no es binaria. Para evaluar un clasificador multi-nominal,
la clase MulticlassMetrics, nos proporciona métodos para la precisión de cálculo, recuperación,
medida F, y otras métricas.

Métricas de Clasificación Multilabel.


Esta clase MultilabelMetrics se puede usar para evaluar clasificadores de etiquetas múltiples.
La diferencia entre una entre una multi-etiqueta y un conjunto de datos de varias clases es que
las etiquetas no se excluyen mutuamente en una tarea de clasificación de múltiples etiquetas,
mientras que las etiquetas se excluyen mutuamente en una tarea de clasificación de múltiples
clases. Una observación en una tarea de clasificación de múltiples clases puede tomar solo una
de muchas etiquetas.

Métricas de Recomendación.
La clase RankingMetrics se puede utilizar para evaluar modelos de recomendación, esto no
proporciona métodos para calcular la efectividad predictiva de un modelo de recomendación.
UNIVERSIDAD UTE

Las métricas soportadas por la clase de RankingMetrics incluyen la media de precisión promedio,
normalizada, ganancia acumulada descontada, y precisión en k.

Spark ML.
Spark ML es otra biblioteca de aprendizaje automático que se ejecuta sobre Spark.
Spark ML proporciona una abstracción de mayor nivel que MLlib para crear flujos de trabajo de
aprendizaje automático o tuberías y les permite a los usuarios ensamblar y ajustar rápidamente
las líneas de aprendizaje automático. Hace que sea fácil crear una canalización para entrenar,
ajustar un modelo mediante la evaluación de un modelo con diferentes métricas. También
proporciona muchas clases y objetos “singleton” proporcionados por la biblioteca MLlib.
Generalmente, una tarea de aprendizaje automático consiste en los siguientes pasos:
1) Leer los datos.
2) Pre proceso o preparación de datos para su procesamiento.
3) Extraer características.
4) Dividir datos para entrenamiento, validación y pruebas.
5) Entrena un modelo con un conjunto de datos de entrenamiento.
6) Afine un modelo utilizando técnicas de validación cruzada.
7) Evaluar un modelo sobre un conjunto de datos de prueba.
8) Implementar un modelo.
Cada paso representa una etapa en una línea de aprendizaje automático. Spark ML proporciona
abstracciones para estas etapas en comparación con MLlib.
Las abstracciones clave introducidas por Spark ML incluyen Transformer, Estimator, Pipeline,
Parameter Grid, CrossValidator, y Evaluador.

Conjunto de datos ML.


Spark ML utiliza DataFrame como la abstracción de datos primaria, estos modelos
proporcionados operan en DataFrames.
DataFrame proporciona una abstracción de mayor nivel que la API RDD para representar datos
estructurados. Admite un esquema flexible que permite columnas con nombre de diferentes
datos.
La API DataFrame facilita la generación de una nueva columna a partir de una existente y la
agrega a la fuente DataFrame.

Transformador.
Un transformador genera un nuevo DataFrame a partir de un DataFrame existente. Lo hace
implementando un método llamado transform, que toma un DataFrame como entrada y
devuelve un nuevo DataFrame añadiendo una o más columnas nuevas a la entrada DataFrame.
Spark ML ofrece dos tipos de transformadores: transformador de características y modelo de
aprendizaje automático, y el transformador de funciones.

Modelo.
Un modelo representa un modelo de aprendizaje automático. Esta toma un DataFrame como
entrada y genera un nuevo DataFrame que contiene etiquetas predichas para cada entidad de
entrada Vector. El conjunto de datos de entrada debe tener una columna que contenga la
característica.

Estimador.
Un estimador entrena o ajusta un modelo de aprendizaje automático en un conjunto de datos
de entrenamiento. Representa una máquina de aprendizaje de algoritmo y lo que hace es
implementar un método llamado fit, que toma un DataFrame como argumento y devuelve un
modelo de aprendizaje automático.
UNIVERSIDAD UTE

Pipeline.
Pipeline o tubería conecta múltiples transformadores y estimadores en una secuencia específica
para formar una máquina o flujo de trabajo de aprendizaje.
Un Pipeline consiste en una secuencia de etapas, donde cada etapa es un transformador o un
estimador. Luego se ejecutan estas etapas en el orden en que se especifican. Se implementa un
método de ajuste, que toma un DataFrame como argumento y lo pasa por las etapas del
oleoducto, este DataFrame de entrada es transformado por cada etapa.

PipelineModel.
Representa una tubería ajustada. Se genera mediante el método de ajuste de un Pipeline. Tiene
las mismas etapas como el Oleoducto que lo generó, a excepción de los Estimadores, que son
reemplazados por modelos entrenados por esos estimadores. En otras palabras, todos los
estimadores son reemplazados por transformadores.
A diferencia de un Pipeline, que es un estimador, un PipelineModel es un transformador. Se
puede aplicar a un conjunto de datos.

Evaluador.
Evalúa el rendimiento predictivo o la efectividad de un modelo y roporciona un método llamado
eval, que toma un DataFrame como entrada y devuelve una métrica escalar.
CrossValidator.
Un CrossValidator encuentra la mejor combinación de valores de híper parámetro para entrenar
el modelo óptimo para una tarea de aprendizaje automático.
Un CrossValidator utiliza la validación cruzada de k-fold y la búsqueda de cuadrícula para el híper
parámetro y el ajuste del modelo. La operación que realizar es dividir un conjunto de datos de
entrenamiento en K-pliegues, donde k es un número especificado por un usuario.

You might also like