PySpark Tutorial para principiantes: aprende con EJEMPLOS

⚡ Resumen inteligente

PySpark son los Python API para Apache Spark, permitiendo a los analistas ejecutar procesamiento de datos distribuido, consultas SQL y aprendizaje automático en clústeres. Este tutorial lo instala y explica SparkContexto y SQLContext, luego construye un clasificador de regresión logística.

  • 🔘 Conceptos básicos del motor: Spark programa, distribuye y supervisa el trabajo en un grupo de máquinas de trabajo, mantieneping cálculo en memoria.
  • ☑️ Python puente: PySpark expone RDD, DataFrames y MLlib a Python, de modo que los usuarios de pandas superan los límites de una sola máquina.
  • ✅ Dos rutas de instalación: Una imagen Docker en una instancia de AWS o un entorno conda dedicado en Windows y Mac.
  • 🧪 Puntos de entrada: SparkContext abre la conexión del clúster; SQLContext (SparkLa sesión sobre versiones modernas crea DataFrames a partir de archivos.
  • 🛠️ API de canalización: Las etapas StringIndexer, OneHotEncoder y VectorAssembler ensamblan las características exactamente de la misma manera que lo hacen las canalizaciones de scikit-learn.
  • 📊 Recompensa de ajuste: La validación cruzada del parámetro de regularización eleva la precisión del clasificador del conjunto de datos para adultos del 82.376% al 85.316%.

PySpark Tutorial para principiantes

Antes de aprender PySpark, entendamos:

que es apache Spark?

Spark es una solución de big data que ha demostrado ser más fácil y rápida que Hadoop MapReduce. Spark es un software de código abierto desarrollado por el laboratorio RAD de UC Berkeley en 2009. Desde su lanzamiento al público en 2010, Spark ha ganado popularidad y se utiliza en la industria a una escala sin precedentes.

En la era del Big Data, los profesionales necesitan más que nunca herramientas rápidas y confiables para procesar flujos de datos. Herramientas anteriores como MapReduce eran las favoritas, pero eran lentas. Para superar este problema, Spark ofrece una solución rápida y de uso general. La principal diferencia entre Spark y MapReduce es que Spark Ejecuta cálculos en la memoria durante el transcurso del tiempo en el disco duro. Permite el acceso y procesamiento de datos a alta velocidad, reduciendo los tiempos de horas a minutos.

¿Qué es Py?Spark?

PySpark es una herramienta creada por Apache Spark Comunidad para usar Python con Spark. Permite trabajar con RDD (Resilient Distributed Dataset) en Python. También ofrece PySpark Shell para vincular Python API con Spark núcleo para iniciar Spark Contexto. Spark es el nombre del motor para realizar la computación en clúster, mientras que PySpark is Pythonbiblioteca para usar Spark.

La biblioteca se envía como la pyspark paquete en PyPI, por lo que un solo pip install pyspark incorpora el motor Scala/JVM más el puente Py4J que permite Python Los objetos lo utilizan como interfaz. Todo lo que sigue se basa en ese paquete.

Cómo Se Compara Spark funciona?

Spark Se basa en un motor computacional, lo que significa que se encarga de la programación, distribución y monitorización de la aplicación. Cada tarea se realiza en varias máquinas de trabajo llamadas clúster de computación. Un clúster de computación se refiere a la división de tareas. Una máquina realiza una tarea, mientras que las demás contribuyen al resultado final a través de una tarea diferente. Al final, todas las tareas se agregan para producir un resultado. Spark El administrador ofrece una descripción general de 360 ​​grados de varios Spark Empleo.

El siguiente diagrama muestra cómo un programa controlador distribuye el trabajo a las máquinas trabajadoras que componen dicho clúster.

Spark Clúster informático que muestra la programación de tareas del controlador en las máquinas de trabajo.

¿Cómo Spark Portafolio

Spark está diseñado para trabajar con

  • Python
  • Java
  • Scala
  • SQL

Una característica significativa de Spark es la gran cantidad de bibliotecas integradas, incluyendo MLlib para aprendizaje automático. Spark También está diseñado para funcionar con clústeres Hadoop y puede leer una amplia variedad de archivos, incluidos datos Hive, CSV, JSON, Cassandra datos entre otros.

¿Por qué utilizar Spark?

Como futuro profesional de datos, deberías estar familiarizado con PythonLas famosas bibliotecas de Pandas y scikit-aprenderEstas dos bibliotecas son fantásticas para explorar conjuntos de datos de tamaño medio. Los proyectos habituales de aprendizaje automático se basan en la siguiente metodología:

  • Cargar los datos al disco.
  • Importar los datos a la memoria de la máquina.
  • Procesar/analizar los datos
  • Construya el modelo de aprendizaje automático
  • Almacenar la predicción en el disco

El problema surge cuando el científico de datos quiere procesar datos demasiado grandes para un solo ordenador. En los inicios de la ciencia de datos, los profesionales solían muestrear los datos, ya que no siempre era necesario entrenar con conjuntos de datos enormes. El científico de datos encontraba una buena muestra estadística, realizaba una comprobación de robustez adicional y obtenía un modelo excelente.

Sin embargo, existen algunos problemas con esto:

  • ¿El conjunto de datos refleja el mundo real?
  • ¿Los datos incluyen un ejemplo específico?
  • ¿Es el modelo apto para el muestreo?

Tomemos como ejemplo las recomendaciones de los usuarios. Los recomendadores se basan en comparar usuarios con otros usuarios para evaluar sus preferencias. Si el profesional de datos toma solo un subconjunto de datos, no habrá una cohorte de usuarios que sean muy similares entre sí. Los recomendadores deben ejecutarse en todo el conjunto de datos o no ejecutarse en absoluto.

¿Cuál es la solución?

La solución ha sido evidente durante mucho tiempo: dividir el problema en varias computadoras. La computación paralela también conlleva múltiples problemas. Los desarrolladores a menudo tienen problemas para escribir código paralelo y terminan teniendo que resolver una serie de problemas complejos relacionados con el multiprocesamiento en sí.

PySpark Proporciona al científico de datos una API que puede utilizarse para resolver problemas de procesamiento de datos en paralelo. PySpark Gestiona las complejidades del procesamiento paralelo, como la distribución de datos, la distribución de código y la recopilación de la salida de los procesos en un clúster de máquinas.

Spark Puede ejecutarse de forma independiente, pero la mayoría de las veces se ejecuta sobre un marco de computación en clúster como Hadoop. Sin embargo, en pruebas y desarrollo, un científico de datos puede ejecutar de manera eficiente Spark en sus cajas de desarrollo o portátiles sin clúster

  • Una de las principales ventajas de Spark Se trata de construir una arquitectura que abarque la gestión de la transmisión de datos, consultas de datos sin problemas, predicción de aprendizaje automático y acceso en tiempo real a diversos análisis.
  • Spark trabaja en estrecha colaboración con SQL lenguaje, es decir, datos estructurados. Permite consultar los datos en tiempo real.
  • La principal función de un científico de datos es analizar y crear modelos predictivos. En resumen, un científico de datos debe saber cómo consultar datos mediante SQL, generar informes estadísticos y utilizar el aprendizaje automático para realizar predicciones. Dedica una cantidad considerable de tiempo a limpiar, transformar y analizar los datos. Una vez que el conjunto de datos o el flujo de trabajo está listo, utiliza diversas técnicas para descubrir información valiosa y patrones ocultos. La manipulación de datos debe ser robusta y, a la vez, fácil de usar. Spark es la herramienta adecuada gracias a su velocidad y sus ricas API.

En este PySpark tutorial, aprenderá cómo construir un clasificador con PySpark ejemplos.

Cómo instalar PySpark con AWS

El Jupyter El equipo crea una imagen de Docker para ejecutar. Spark eficientemente. A continuación se detallan los pasos que puede seguir para instalar PySpark instancia en AWS.

Consulte nuestro tutorial sobre AWS y TensorFlow

Paso 1: crear una instancia

En primer lugar, necesitas crear una instancia. Vaya a su cuenta de AWS e inicie la instancia. Puede aumentar el almacenamiento hasta 15 gy utilizar el mismo grupo de seguridad que en el tutorial de TensorFlow.

Paso 2: abre la conexión

Abra la conexión e instale el contenedor Docker. Para obtener más detalles, consulte el tutorial con TensorFlow con Docker. Tenga en cuenta que debe estar en el directorio de trabajo correcto.

Simplemente ejecute estos códigos para instalar Docker:

sudo yum update -y
sudo yum install -y docker
sudo service docker start
sudo user-mod -a -G docker ec2-user
exit

Paso 3: Vuelva a abrir la conexión e instale Spark

Después de volver a abrir la conexión, puede instalar la imagen que contiene PySpark.

## Spark
docker run -v ~/work:/home/jovyan/work -d -p 8888:8888 jupyter/pyspark-notebook

## Allow preserving Jupyter notebook
sudo chown 1000 ~/work

## Install tree to see our working directory next
sudo yum install -y tree

Paso 4: abierto Jupyter

Consulta el contenedor y su nombre.

docker ps

Inicie la ventana acoplable con los registros de la ventana acoplable seguidos del nombre de la ventana acoplable. Por ejemplo, Docker registra zealous_goldwasser

Vaya a su navegador y ejecute Jupyter. La dirección es http://localhost:8888/. Pega la contraseña proporcionada por el terminal.

Nota: Si desea cargar/descargar un archivo en su máquina AWS, puede utilizar el software. Cyberduck.

Cómo instalar PySpark on Windows/Mac con Conda

A continuación se muestra un proceso detallado sobre cómo instalar PySpark on Windows/Mac usando Anaconda:

Para instalar Spark en su máquina local, una práctica recomendada es crear un nuevo entorno conda. Este nuevo entorno se instalará Python 3.6, Spark y todas las dependencias.

Usuario de Mac

cd anaconda3
touch hello-spark.yml
vi hello-spark.yml

Windows El sistema de reservas de escritorios, interactivo y fácil de usar, ayuda a gestores y empresas a adaptarse a la nueva rutina laboral. El sistema inteligente optimiza espacios y horarios según necesidades reales.

cd C:\Users\Admin\Anaconda3
echo.>hello-spark.yml
notepad hello-spark.yml

Puede editar el archivo .yml. Tenga cuidado con la sangría. Se requieren dos espacios antes –

name: hello-spark 
    dependencies:
    
    - python=3.6
    - jupyter
    - ipython
    - numpy
    - numpy-base
    - pandas
    - py4j
    - pyspark
    - pytz

Guárdalo y crea el entorno. lleva algo de tiempo

conda env create -f hello-spark.yml

Para obtener más detalles sobre la ubicación, consulte el tutorial Instalar TensorFlow

Puede comprobar todo el entorno instalado en su máquina.

conda env list
Activate hello-spark

Usuario de Mac

source activate hello-spark

Windows El sistema de reservas de escritorios, interactivo y fácil de usar, ayuda a gestores y empresas a adaptarse a la nueva rutina laboral. El sistema inteligente optimiza espacios y horarios según necesidades reales.

activate hello-spark

Nota: Ya ha creado un entorno de TensorFlow específico para ejecutar los tutoriales en TensorFlow. Es más conveniente crear un nuevo entorno diferente a hello-tf. No tiene sentido sobrecargar hello-tf con Spark o cualquier otra biblioteca de aprendizaje automático.

Imagine que la mayor parte de su proyecto involucra TensorFlow, pero necesita usar Spark para un proyecto en particular. Puede configurar un entorno TensorFlow para todo su proyecto y crear un entorno separado para Spark. Puede agregar tantas bibliotecas en Spark entorno como desee sin interferir con el entorno de TensorFlow. Una vez que haya terminado con el Sparkdel proyecto, puedes borrarlo sin afectar el entorno de TensorFlow.

Jupyter

Abra Jupyter Cuaderno y prueba si PySpark Funciona. En un nuevo cuaderno pegue el siguiente PySpark Código de muestra:

import pyspark
from pyspark import SparkContext
sc =SparkContext()

Una ejecución exitosa no imprime ningún resultado, como se muestra en la captura de pantalla del cuaderno a continuación.

Jupyter Celda de cuaderno que importa pyspark y crea una SparkObjeto Contexto

Si se muestra un error, es probable que Java No está instalado en su máquina. En Mac, abra la terminal y escriba java -version. Si hay una versión de Java, asegúrese de que sea la 1.8. Windows, vaya a Aplicación y verifique si hay una Java carpeta. Si hay un Java carpeta, verifique que Java 1.8 está instalado. Al momento de escribir esto, PySpark no es compatible con Java 9 y superiores.

Nota de versión: que Java 8 restricciones se aplican a la Spark Línea 2.x utilizada a lo largo de este tutorial. Actual Spark Las versiones 3.x y 4.x se ejecutan en Java 8, 11 y 17, por lo que un JDK más reciente está bien si instalas un Py compatible.Spark versión.

Si necesita instalar Java, tu a pensar este enlace y descargar jdk-8u181-windows-x64.exe

Para usuarios de Mac, se recomienda utilizar "brew".

brew tap caskroom/versions
brew cask install java8

Consulte este tutorial paso a paso sobre cómo instalar Java

Nota: Utilice remover para borrar un entorno por completo.

 conda env remove -n hello-spark -y

Spark Contexto

SparkEl contexto es el motor interno que permite las conexiones con los clústeres. Si desea ejecutar una operación, necesita un SparkContexto.

Créar un SparkContexto

En primer lugar, es necesario iniciar un SparkContexto.

import pyspark
from pyspark import SparkContext
sc =SparkContext()

Ahora que la SparkEl contexto está listo, puedes crear una colección de datos llamada RDD, Resilient Distributed Dataset. El cálculo en un RDD se paraleliza automáticamente en todo el clúster.

nums= sc.parallelize([1,2,3,4])

Puedes acceder a la primera fila con tomar

nums.take(1)
[1]

Puede aplicar una transformación a los datos con una función lambda. en el pySpark En el siguiente ejemplo, se devuelve el cuadrado de números. Es una transformación del mapa.

squared = nums.map(lambda x: x*x).collect()
for num in squared:
    print('%i ' % (num))
1 
4 
9 
16

Contexto SQL

Una forma más conveniente es utilizar DataFrame. SparkEl contexto ya está configurado, puedes usarlo para crear el DataFrame. También necesitas declarar el SQLContext.

SQLContext permite conectar el motor con diferentes fuentes de datos. Se utiliza para iniciar las funcionalidades de Spark SQL

Nota de versión: SQLContext fue reemplazado por SparkSesión en Spark 2.0 y formalmente obsoleto en Spark 3.0. Los ejemplos a continuación mantienen SQLContext porque es en lo que se ejecuta el tutorial original; en un clúster moderno, el punto de entrada equivalente es SparkSession.builder.getOrCreate(), que expone los mismos métodos read y createDataFrame.

from pyspark.sql import Row
from pyspark.sql import SQLContext

sqlContext = SQLContext(sc)

Ahora en esto Spark tutoriales Python, creemos una lista de tuplas. Cada tupla contendrá el nombre de las personas y su edad. Se requieren cuatro pasos:

Paso 1) Crea la lista de tuplas con la información.

[('John',19),('Smith',29),('Adam',35),('Henry',50)]

Paso 2) Construir un RDD

rdd = sc.parallelize(list_p)

Paso 3) Convertir las tuplas

rdd.map(lambda x: Row(name=x[0], age=int(x[1])))

Paso 4) Crear un contexto de marco de datos

sqlContext.createDataFrame(ppl)
list_p = [('John',19),('Smith',29),('Adam',35),('Henry',50)]
rdd = sc.parallelize(list_p)
ppl = rdd.map(lambda x: Row(name=x[0], age=int(x[1])))
DF_ppl = sqlContext.createDataFrame(ppl)

Si desea acceder al tipo de cada característica, puede usar printSchema()

DF_ppl.printSchema()
root
 |-- age: long (nullable = true)
 |-- name: string (nullable = true)

Ejemplo de aprendizaje automático con PySpark

Ahora que tienes una breve idea de Spark y SQLContext, está listo para crear su primer programa de aprendizaje automático.

A continuación se muestran los pasos para crear un programa de aprendizaje automático con PySpark:

  • Paso 1) Operación básica con PySpark
  • Paso 2) Preprocesamiento de datos
  • Paso 3) Construya un canal de procesamiento de datos
  • Paso 4) Construir el clasificador: logístico
  • Paso 5) Entrenar y evaluar el modelo.
  • Paso 6) Ajusta el hiperparámetro

En este PySpark Tutorial de aprendizaje automático: utilizaremos el conjunto de datos de adultos. El objetivo de este tutorial es aprender a usar Python.SparkPara obtener más información sobre el conjunto de datos, consulte este tutorial.

Tenga en cuenta que el conjunto de datos no es significativo y puede pensar que el cálculo lleva mucho tiempo. Spark está diseñado para procesar una cantidad considerable de datos. SparkSu rendimiento aumenta en relación con otras bibliotecas de aprendizaje automático a medida que aumenta el tamaño del conjunto de datos procesado.

Paso 1) Operación básica con PySpark

En primer lugar, debe inicializar el SQLContext que aún no se ha iniciado.

#from pyspark.sql import SQLContext
url = "https://raw.githubusercontent.com/guru99-edu/R-Programming/master/adult_data.csv"
from pyspark import SparkFiles
sc.addFile(url)
sqlContext = SQLContext(sc)

luego, puede leer el archivo cvs con sqlContext.read.csv. Usas inferSchema configurado en True para saber Spark para adivinar automáticamente el tipo de datos. De forma predeterminada, cambia a Falso.

df = sqlContext.read.csv(SparkFiles.get("adult_data.csv"), header=True, inferSchema= True)

Echemos un vistazo al tipo de datos.

df.printSchema()
root
 |-- age: integer (nullable = true)
 |-- workclass: string (nullable = true)
 |-- fnlwgt: integer (nullable = true)
 |-- education: string (nullable = true)
 |-- education_num: integer (nullable = true)
 |-- marital: string (nullable = true)
 |-- occupation: string (nullable = true)
 |-- relationship: string (nullable = true)
 |-- race: string (nullable = true)
 |-- sex: string (nullable = true)
 |-- capital_gain: integer (nullable = true)
 |-- capital_loss: integer (nullable = true)
 |-- hours_week: integer (nullable = true)
 |-- native_country: string (nullable = true)
 |-- label: string (nullable = true)

Puedes ver los datos con show.

df.show(5, truncate = False)
+---+----------------+------+---------+-------------+------------------+-----------------+-------------+-----+------+------------+------------+----------+--------------+-----+
|age|workclass       |fnlwgt|education|education_num|marital           |occupation       |relationship |race |sex   |capital_gain|capital_loss|hours_week|native_country|label|
+---+----------------+------+---------+-------------+------------------+-----------------+-------------+-----+------+------------+------------+----------+--------------+-----+
|39 |State-gov       |77516 |Bachelors|13           |Never-married     |Adm-clerical     |Not-in-family|White|Male  |2174        |0           |40        |United-States |<=50K|
|50 |Self-emp-not-inc|83311 |Bachelors|13           |Married-civ-spouse|Exec-managerial  |Husband      |White|Male  |0           |0           |13        |United-States |<=50K|
|38 |Private         |215646|HS-grad  |9            |Divorced          |Handlers-cleaners|Not-in-family|White|Male  |0           |0           |40        |United-States |<=50K|
|53 |Private         |234721|11th     |7            |Married-civ-spouse|Handlers-cleaners|Husband      |Black|Male  |0           |0           |40        |United-States |<=50K|
|28 |Private         |338409|Bachelors|13           |Married-civ-spouse|Prof-specialty   |Wife         |Black|Female|0           |0           |40        |Cuba          |<=50K|
+---+----------------+------+---------+-------------+------------------+-----------------+-------------+-----+------+------------+------------+----------+--------------+-----+
only showing top 5 rows

Si no configuraste inferSchema en True, esto es lo que está sucediendo con el tipo. Todos están en cadena.

df_string = sqlContext.read.csv(SparkFiles.get("adult.csv"), header=True, inferSchema=  False)
df_string.printSchema()
root
 |-- age: string (nullable = true)
 |-- workclass: string (nullable = true)
 |-- fnlwgt: string (nullable = true)
 |-- education: string (nullable = true)
 |-- education_num: string (nullable = true)
 |-- marital: string (nullable = true)
 |-- occupation: string (nullable = true)
 |-- relationship: string (nullable = true)
 |-- race: string (nullable = true)
 |-- sex: string (nullable = true)
 |-- capital_gain: string (nullable = true)
 |-- capital_loss: string (nullable = true)
 |-- hours_week: string (nullable = true)
 |-- native_country: string (nullable = true)
 |-- label: string (nullable = true)

Para convertir la variable continua al formato correcto, puede utilizar la refundición de las columnas. Puedes usar withColumn para saber Spark En qué columna operar la transformación.

# Import all from `sql.types`
from pyspark.sql.types import *

# Write a custom function to convert the data type of DataFrame columns
def convertColumn(df, names, newType):
    for name in names: 
        df = df.withColumn(name, df[name].cast(newType))
    return df 
# List of continuous features
CONTI_FEATURES  = ['age', 'fnlwgt','capital_gain', 'education_num', 'capital_loss', 'hours_week']
# Convert the type
df_string = convertColumn(df_string, CONTI_FEATURES, FloatType())
# Check the dataset
df_string.printSchema()
root
 |-- age: float (nullable = true)
 |-- workclass: string (nullable = true)
 |-- fnlwgt: float (nullable = true)
 |-- education: string (nullable = true)
 |-- education_num: float (nullable = true)
 |-- marital: string (nullable = true)
 |-- occupation: string (nullable = true)
 |-- relationship: string (nullable = true)
 |-- race: string (nullable = true)
 |-- sex: string (nullable = true)
 |-- capital_gain: float (nullable = true)
 |-- capital_loss: float (nullable = true)
 |-- hours_week: float (nullable = true)
 |-- native_country: string (nullable = true)
 |-- label: string (nullable = true)

from pyspark.ml.feature import StringIndexer
#stringIndexer = StringIndexer(inputCol="label", outputCol="newlabel")
#model = stringIndexer.fit(df)
#df = model.transform(df)
df.printSchema()

Seleccionar columnas

Puede seleccionar y mostrar las filas con select y los nombres de las funciones. A continuación, se seleccionan edad y fnlwgt.

df.select('age','fnlwgt').show(5)
+---+------+
|age|fnlwgt|
+---+------+
| 39| 77516|
| 50| 83311|
| 38|215646|
| 53|234721|
| 28|338409|
+---+------+
only showing top 5 rows

Contar por grupo

Si desea contar el número de ocurrencias por grupo, puede encadenar:

  • agrupar por()
  • contar()

juntos. en el pySpark En el siguiente ejemplo, se cuenta el número de filas según el nivel educativo.

df.groupBy("education").count().sort("count",ascending=True).show()
+------------+-----+
|   education|count|
+------------+-----+
|   Preschool|   51|
|     1st-4th|  168|
|     5th-6th|  333|
|   Doctorate|  413|
|        12th|  433|
|         9th|  514|
| Prof-school|  576|
|     7th-8th|  646|
|        10th|  933|
|  Assoc-acdm| 1067|
|        11th| 1175|
|   Assoc-voc| 1382|
|     Masters| 1723|
|   Bachelors| 5355|
|Some-college| 7291|
|     HS-grad|10501|
+------------+-----+

Describe los datos

Para obtener un resumen estadístico de los datos, puede utilizar describe(). Calculará:

  • contar
  • mean
  • desviación estándar
  • min
  • max
df.describe().show()
+-------+------------------+-----------+------------------+------------+-----------------+--------+----------------+------------+------------------+------+------------------+----------------+------------------+--------------+-----+
|summary|               age|  workclass|            fnlwgt|   education|    education_num| marital|      occupation|relationship|              race|   sex|      capital_gain|    capital_loss|        hours_week|native_country|label|
+-------+------------------+-----------+------------------+------------+-----------------+--------+----------------+------------+------------------+------+------------------+----------------+------------------+--------------+-----+
|  count|             32561|      32561|             32561|       32561|            32561|   32561|           32561|       32561|             32561| 32561|             32561|           32561|             32561|         32561|32561|
|   mean| 38.58164675532078|       null|189778.36651208502|        null| 10.0806793403151|    null|            null|        null|              null|  null|1077.6488437087312| 87.303829734959|40.437455852092995|          null| null|
| stddev|13.640432553581356|       null|105549.97769702227|        null|2.572720332067397|    null|            null|        null|              null|  null| 7385.292084840354|402.960218649002|12.347428681731838|          null| null|
|    min|                17|          ?|             12285|        10th|                1|Divorced|               ?|     Husband|Amer-Indian-Eskimo|Female|                 0|               0|                 1|             ?|<=50K|
|    max|                90|Without-pay|           1484705|Some-college|               16| Widowed|Transport-moving|        Wife|             White|  Male|             99999|            4356|                99|    Yugoslavia| >50K|
+-------+------------------+-----------+------------------+------------+-----------------+--------+----------------+------------+------------------+------+------------------+----------------+------------------+--------------+-----+

Si desea el resumen estadístico de una sola columna, agregue el nombre de la columna dentro de describe()

df.describe('capital_gain').show()
+-------+------------------+
|summary|      capital_gain|
+-------+------------------+
|  count|             32561|
|   mean|1077.6488437087312|
| stddev| 7385.292084840354|
|    min|                 0|
|    max|             99999|
+-------+------------------+

Cálculo de tablas cruzadas

En algunas ocasiones, puede resultar interesante ver las estadísticas descriptivas entre dos columnas por pares. Por ejemplo, se puede contar la cantidad de personas con ingresos inferiores o superiores a 50 XNUMX dólares por nivel de educación. Esta operación se denomina tabla de referencias cruzadas.

df.crosstab('age', 'label').sort("age_label").show()
+---------+-----+----+
|age_label|<=50K|>50K|
+---------+-----+----+
|       17|  395|   0|
|       18|  550|   0|
|       19|  710|   2|
|       20|  753|   0|
|       21|  717|   3|
|       22|  752|  13|
|       23|  865|  12|
|       24|  767|  31|
|       25|  788|  53|
|       26|  722|  63|
|       27|  754|  81|
|       28|  748| 119|
|       29|  679| 134|
|       30|  690| 171|
|       31|  705| 183|
|       32|  639| 189|
|       33|  684| 191|
|       34|  643| 243|
|       35|  659| 217|
|       36|  635| 263|
+---------+-----+----+
only showing top 20 rows

Se puede ver que ninguna persona tiene ingresos superiores a 50 cuando son jóvenes.

Columna de caída

Hay dos API intuitivas para eliminar columnas:

  • soltar(): soltar una columna
  • dropna(): Elimina NA

Debajo sueltas la columna num_educación

df.drop('education_num').columns

['age',
 'workclass',
 'fnlwgt',
 'education',
 'marital',
 'occupation',
 'relationship',
 'race',
 'sex',
 'capital_gain',
 'capital_loss',
 'hours_week',
 'native_country',
 'label']

Filtrar datos

Puede utilizar filter() para aplicar estadísticas descriptivas en un subconjunto de datos. Por ejemplo, puedes contar el número de personas mayores de 40 años.

df.filter(df.age > 40).count()

13443

DescriptCinco estadísticas por grupo.

Finalmente, puedes agrupar datos por grupo y calcular operaciones estadísticas como la media.

df.groupby('marital').agg({'capital_gain': 'mean'}).show()
+--------------------+------------------+
|             marital| avg(capital_gain)|
+--------------------+------------------+
|           Separated| 535.5687804878049|
|       Never-married|376.58831788823363|
|Married-spouse-ab...| 653.9832535885167|
|            Divorced| 728.4148098131893|
|             Widowed| 571.0715005035247|
|   Married-AF-spouse| 432.6521739130435|
|  Married-civ-spouse|1764.8595085470085|
+--------------------+------------------+

Paso 2) Preprocesamiento de datos

El procesamiento de datos es un paso crítico en el aprendizaje automático. Después de eliminar los datos basura, obtendrá información importante.

Por ejemplo, sabes que la edad no es una función lineal con los ingresos. Cuando las personas son jóvenes, sus ingresos suelen ser inferiores a los de la mediana edad. Después de la jubilación, un hogar utiliza sus ahorros, lo que significa una disminución de sus ingresos. Para capturar este patrón, puede agregar un cuadrado a la función de edad.

Añadir cuadro de edad

Para agregar una nueva función, debe:

  1. Seleccione la columna
  2. Aplicar la transformación y agregarla al DataFrame.
from pyspark.sql.functions import *

# 1 Select the column
age_square = df.select(col("age")**2)

# 2 Apply the transformation and add it to the DataFrame
df = df.withColumn("age_square", col("age")**2)

df.printSchema()
root
 |-- age: integer (nullable = true)
 |-- workclass: string (nullable = true)
 |-- fnlwgt: integer (nullable = true)
 |-- education: string (nullable = true)
 |-- education_num: integer (nullable = true)
 |-- marital: string (nullable = true)
 |-- occupation: string (nullable = true)
 |-- relationship: string (nullable = true)
 |-- race: string (nullable = true)
 |-- sex: string (nullable = true)
 |-- capital_gain: integer (nullable = true)
 |-- capital_loss: integer (nullable = true)
 |-- hours_week: integer (nullable = true)
 |-- native_country: string (nullable = true)
 |-- label: string (nullable = true)
 |-- age_square: double (nullable = true)

Puede ver que age_square se agregó correctamente al marco de datos. Puede cambiar el orden de las variables con select. A continuación, traes age_square justo después de edad.

COLUMNS = ['age', 'age_square', 'workclass', 'fnlwgt', 'education', 'education_num', 'marital',
           'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss',
           'hours_week', 'native_country', 'label']
df = df.select(COLUMNS)
df.first()
Row(age=39, age_square=1521.0, workclass='State-gov', fnlwgt=77516, education='Bachelors', education_num=13, marital='Never-married', occupation='Adm-clerical', relationship='Not-in-family', race='White', sex='Male', capital_gain=2174, capital_loss=0, hours_week=40, native_country='United-States', label='<=50K')

Excluir Holanda-Países Bajos

Cuando un grupo dentro de una característica tiene solo una observación, no aporta información al modelo. Por el contrario, puede dar lugar a un error durante la validación cruzada.

Comprobemos el origen del hogar.

df.filter(df.native_country == 'Holand-Netherlands').count()
df.groupby('native_country').agg({'native_country': 'count'}).sort(asc("count(native_country)")).show()
+--------------------+---------------------+
|      native_country|count(native_country)|
+--------------------+---------------------+
|  Holand-Netherlands|                    1|
|            Scotland|                   12|
|             Hungary|                   13|
|            Honduras|                   13|
|Outlying-US(Guam-...|                   14|
|          Yugoslavia|                   16|
|            Thailand|                   18|
|                Laos|                   18|
|            Cambodia|                   19|
|     Trinadad&Tobago|                   19|
|                Hong|                   20|
|             Ireland|                   24|
|             Ecuador|                   28|
|              Greece|                   29|
|              France|                   29|
|                Peru|                   31|
|           Nicaragua|                   34|
|            Portugal|                   37|
|                Iran|                   43|
|               Haiti|                   44|
+--------------------+---------------------+
only showing top 20 rows

La característica país_nativo tiene solo un hogar procedente de Holanda. Lo excluyes.

df_remove = df.filter(df.native_country !=	'Holand-Netherlands')

Paso 3) Construya un canal de procesamiento de datos

Similar a scikit-learn, PySpark tiene una API de canalización.

Una canalización es muy conveniente para mantener la estructura de los datos. Insertas los datos en la tubería. Dentro de la canalización, se realizan varias operaciones y la salida se utiliza para alimentar el algoritmo.

Por ejemplo, una transformación universal en el aprendizaje automático consiste en convertir una cadena en un codificador activo, es decir, una columna por grupo. Un codificador activo suele ser una matriz llena de ceros.

Los pasos para transformar los datos son muy similares a los de scikit-learn. Necesitas:

  • Indexar la cadena a numérico
  • Crea el codificador activo
  • Transforma los datos

Dos API hacen el trabajo: StringIndexer, OneHotEncoder

  1. En primer lugar, selecciona la columna de cadena a indexar. inputCol es el nombre de la columna en el conjunto de datos. OutputCol es el nuevo nombre dado a la columna transformada.
StringIndexer(inputCol="workclass", outputCol="workclass_encoded")
  1. Ajustar los datos y transformarlos
model = stringIndexer.fit(df)		
`indexed = model.transform(df)``
  1. Crea las columnas de noticias según el grupo. Por ejemplo, si hay 10 grupos en la función, la nueva matriz tendrá 10 columnas, una para cada grupo.
OneHotEncoder(dropLast=False, inputCol="workclassencoded", outputCol="workclassvec")
### Example encoder
from pyspark.ml.feature import StringIndexer, OneHotEncoder, VectorAssembler

stringIndexer = StringIndexer(inputCol="workclass", outputCol="workclass_encoded")
model = stringIndexer.fit(df)
indexed = model.transform(df)
encoder = OneHotEncoder(dropLast=False, inputCol="workclass_encoded", outputCol="workclass_vec")
encoded = encoder.transform(indexed)
encoded.show(2)
+---+----------+----------------+------+---------+-------------+------------------+---------------+-------------+-----+----+------------+------------+----------+--------------+-----+-----------------+-------------+
|age|age_square|       workclass|fnlwgt|education|education_num|           marital|     occupation| relationship| race| sex|capital_gain|capital_loss|hours_week|native_country|label|workclass_encoded|workclass_vec|
+---+----------+----------------+------+---------+-------------+------------------+---------------+-------------+-----+----+------------+------------+----------+--------------+-----+-----------------+-------------+
| 39|    1521.0|       State-gov| 77516|Bachelors|           13|     Never-married|   Adm-clerical|Not-in-family|White|Male|        2174|           0|        40| United-States|<=50K|              4.0|(9,[4],[1.0])|
| 50|    2500.0|Self-emp-not-inc| 83311|Bachelors|           13|Married-civ-spouse|Exec-managerial|      Husband|White|Male|           0|           0|        13| United-States|<=50K|              1.0|(9,[1],[1.0])|
+---+----------+----------------+------+---------+-------------+------------------+---------------+-------------+-----+----+------------+------------+----------+--------------+-----+-----------------+-------------+
only showing top 2 rows

construir el oleoducto

Construirá una canalización para convertir todas las características precisas y agregarlas al conjunto de datos final. La canalización tendrá cuatro operaciones, pero siéntase libre de agregar tantas operaciones como desee.

  1. Codificar los datos categóricos.
  2. Indexar la característica de la etiqueta
  3. Agregar variable continua
  4. Montar los escalones.

Cada paso se almacena en una lista denominada etapas. Esta lista le indicará a VectorAssembler qué operación realizar dentro de la tubería.

1. Codifique los datos categóricos.

Este paso es exactamente igual que el ejemplo anterior, excepto que se itera sobre todas las características categóricas.

from pyspark.ml import Pipeline
from pyspark.ml.feature import OneHotEncoderEstimator
CATE_FEATURES = ['workclass', 'education', 'marital', 'occupation', 'relationship', 'race', 'sex', 'native_country']
stages = [] # stages in our Pipeline
for categoricalCol in CATE_FEATURES:
    stringIndexer = StringIndexer(inputCol=categoricalCol, outputCol=categoricalCol + "Index")
    encoder = OneHotEncoderEstimator(inputCols=[stringIndexer.getOutputCol()],
                                     outputCols=[categoricalCol + "classVec"])
    stages += [stringIndexer, encoder]

Nota sobre la API: OneHotEncoderEstimator se fusionó de nuevo con OneHotEncoder en Spark 3.0. En Spark En la versión 3.x o posterior, importe OneHotEncoder y pase los mismos argumentos inputCols y outputCols; el resto del bucle permanece sin cambios.

2. Indexar la característica de la etiqueta

Spark, como muchas otras bibliotecas, no acepta valores de cadena para la etiqueta. Convierte la función de etiqueta con StringIndexer y la agrega a las etapas de la lista

# Convert label into label indices using the StringIndexer
label_stringIdx =  StringIndexer(inputCol="label", outputCol="newlabel")
stages += [label_stringIdx]

3. Agregar variable continua

La columna `inputCols` del `VectorAssembler` es una lista de columnas. Puedes crear una nueva lista que contenga todas las columnas nuevas. El código que aparece a continuación rellena la lista con características categóricas codificadas y características continuas.

assemblerInputs = [c + "classVec" for c in CATE_FEATURES] + CONTI_FEATURES

4. Ensamble los escalones.

Finalmente, pasas todos los pasos en el VectorAssembler.

assembler = VectorAssembler(inputCols=assemblerInputs, outputCol="features")stages += [assembler]

Ahora que todos los pasos están listos, envía los datos a la canalización.

# Create a Pipeline.
pipeline = Pipeline(stages=stages)
pipelineModel = pipeline.fit(df_remove)
model = pipelineModel.transform(df_remove)

Si revisa el nuevo conjunto de datos, puede ver que contiene todas las características, transformadas y no transformadas. Solo le interesa la nueva etiqueta y las características. Las características incluyen todas las características transformadas y las variables continuas.

model.take(1)

[Row(age=39, age_square=1521.0, workclass='State-gov', fnlwgt=77516, education='Bachelors', education_num=13, marital='Never-married', occupation='Adm-clerical', relationship='Not-in-family', race='White', sex='Male', capital_gain=2174, capital_loss=0, hours_week=40, native_country='United-States', label='<=50K', workclassIndex=4.0, workclassclassVec=SparseVector(8, {4: 1.0}), educationIndex=2.0, educationclassVec=SparseVector(15, {2: 1.0}), maritalIndex=1.0, maritalclassVec=SparseVector(6, {1: 1.0}), occupationIndex=3.0, occupationclassVec=SparseVector(14, {3: 1.0}), relationshipIndex=1.0, relationshipclassVec=SparseVector(5, {1: 1.0}), raceIndex=0.0, raceclassVec=SparseVector(4, {0: 1.0}), sexIndex=0.0, sexclassVec=SparseVector(1, {0: 1.0}), native_countryIndex=0.0, native_countryclassVec=SparseVector(40, {0: 1.0}), newlabel=0.0, features=SparseVector(99, {4: 1.0, 10: 1.0, 24: 1.0, 32: 1.0, 44: 1.0, 48: 1.0, 52: 1.0, 53: 1.0, 93: 39.0, 94: 77516.0, 95: 2174.0, 96: 13.0, 98: 40.0}))]

Paso 4) Construir el clasificador: logístico

Para agilizar el cálculo, convierta el modelo en un DataFrame.

Debe seleccionar una nueva etiqueta y características del modelo usando el mapa.

from pyspark.ml.linalg import DenseVector
input_data = model.rdd.map(lambda x: (x["newlabel"], DenseVector(x["features"])))

Está listo para crear los datos del tren como un DataFrame. Usas el sqlContext

df_train = sqlContext.createDataFrame(input_data, ["label", "features"])

Revisa la segunda fila

df_train.show(2)
+-----+--------------------+
|label|            features|
+-----+--------------------+
|  0.0|[0.0,0.0,0.0,0.0,...|
|  0.0|[0.0,1.0,0.0,0.0,...|
+-----+--------------------+
only showing top 2 rows

Crear un conjunto de tren/prueba

Divide el conjunto de datos 80/20 con randomSplit.

# Split the data into train and test sets
train_data, test_data = df_train.randomSplit([.8,.2],seed=1234)

Contemos cuántas personas con ingresos inferiores o superiores a 50 XNUMX tanto en el conjunto de entrenamiento como en el de prueba

train_data.groupby('label').agg({'label': 'count'}).show()
+-----+------------+
|label|count(label)|
+-----+------------+
|  0.0|       19698|
|  1.0|        6263|
+-----+------------+
test_data.groupby('label').agg({'label': 'count'}).show()
+-----+------------+
|label|count(label)|
+-----+------------+
|  0.0|        5021|
|  1.0|        1578|
+-----+------------+

Construir el regresor logístico

Por último, pero no menos importante, puedes construir el clasificador. PySpark Dispone de una API llamada LogisticRegression para realizar regresiones logísticas.

Inicializa lr indicando la columna de etiqueta y las columnas de características. Establece un máximo de 10 iteraciones y agrega un parámetro de regularización con un valor de 0.3. Tenga en cuenta que en la siguiente sección utilizará la validación cruzada con una cuadrícula de parámetros para ajustar el modelo.

# Import `LinearRegression`
from pyspark.ml.classification import LogisticRegression

# Initialize `lr`
lr = LogisticRegression(labelCol="label",
                        featuresCol="features",
                        maxIter=10,
                        regParam=0.3)

# Fit the data to the model
linearModel = lr.fit(train_data)

#Puedes ver los coeficientes de la regresión.

# Print the coefficients and intercept for logistic regression
print("Coefficients: " + str(linearModel.coefficients))
print("Intercept: " + str(linearModel.intercept))
Coefficients: [-0.0678914665262,-0.153425526813,-0.0706009536407,-0.164057586562,-0.120655298528,0.162922330862,0.149176870438,-0.626836362611,-0.193483661541,-0.0782269980838,0.222667203836,0.399571096381,-0.0222024341804,-0.311925857859,-0.0434497788688,-0.306007744328,-0.41318209688,0.547937504247,-0.395837350854,-0.23166535958,0.618743906733,-0.344088614546,-0.385266881369,0.317324463006,-0.350518889186,-0.201335923138,-0.232878560088,-0.13349278865,-0.119760542498,0.17500602491,-0.0480968101118,0.288484253943,-0.116314616745,0.0524163478063,-0.300952624551,-0.22046421474,-0.16557996579,-0.114676231939,-0.311966431453,-0.344226119233,0.105530129507,0.152243047814,-0.292774545497,0.263628334433,-0.199951374076,-0.30329422583,-0.231087515178,0.418918551,-0.0565930184279,-0.177818073048,-0.0733236680663,-0.267972912252,0.168491215697,-0.12181255723,-0.385648075442,-0.202101794517,0.0469791640782,-0.00842850210625,-0.00373211448629,-0.259296141281,-0.309896554133,-0.168434409756,-0.11048086026,0.0280647963877,-0.204187030092,-0.414392623536,-0.252806580669,0.143366465705,-0.516359222663,-0.435627370849,-0.301949286524,0.0878249035894,-0.210951740965,-0.621417928742,-0.099445190784,-0.232671473401,-0.1077745606,-0.360429419703,-0.420362959052,-0.379729467809,-0.395186242741,0.0826401853838,-0.280251589972,0.187313505214,-0.20295228799,-0.431177064626,0.149759018379,-0.107114299614,-0.319314858424,0.0028450133235,-0.651220387649,-0.327918792207,-0.143659581445,0.00691075160413,8.38517628783e-08,2.18856717378e-05,0.0266701216268,0.000231075966823,0.00893832698698]
Intercept: -1.9884177974805692

Paso 5) Entrenar y evaluar el modelo.

Para generar predicción para su conjunto de prueba,

Puedes usar linearModel con transform() en test_data

# Make predictions on test data using the transform() method.
predictions = linearModel.transform(test_data)

Puedes imprimir los elementos en las predicciones.

predictions.printSchema()
root
 |-- label: double (nullable = true)
 |-- features: vector (nullable = true)
 |-- rawPrediction: vector (nullable = true)
 |-- probability: vector (nullable = true)
 |-- prediction: double (nullable = false)

Te interesa la etiqueta, la predicción y la probabilidad.

selected = predictions.select("label", "prediction", "probability")
selected.show(20)
+-----+----------+--------------------+
|label|prediction|         probability|
+-----+----------+--------------------+
|  0.0|       0.0|[0.91560704124179...|
|  0.0|       0.0|[0.92812140213994...|
|  0.0|       0.0|[0.92161406774159...|
|  0.0|       0.0|[0.96222760777142...|
|  0.0|       0.0|[0.66363283056957...|
|  0.0|       0.0|[0.65571324475477...|
|  0.0|       0.0|[0.73053376932829...|
|  0.0|       1.0|[0.31265053873570...|
|  0.0|       0.0|[0.80005907577390...|
|  0.0|       0.0|[0.76482251301640...|
|  0.0|       0.0|[0.84447301189069...|
|  0.0|       0.0|[0.75691912026619...|
|  0.0|       0.0|[0.60902504096722...|
|  0.0|       0.0|[0.80799228385509...|
|  0.0|       0.0|[0.87704364852567...|
|  0.0|       0.0|[0.83817652582377...|
|  0.0|       0.0|[0.79655423248500...|
|  0.0|       0.0|[0.82712311232246...|
|  0.0|       0.0|[0.81372823882016...|
|  0.0|       0.0|[0.59687710752201...|
+-----+----------+--------------------+
only showing top 20 rows

Evaluar el modelo

Es necesario observar la métrica de precisión para ver qué tan bien (o mal) se desempeña el modelo. Actualmente, no existe una API para calcular la medida de precisión en Spark. El valor predeterminado es la curva característica operativa del receptor, ROC. Es una métrica diferente que tiene en cuenta la tasa de falsos positivos.

Antes de mirar la República de China, construyamos la medida de precisión. Estás más familiarizado con esta métrica. La medida de precisión es la suma de la predicción correcta sobre el número total de observaciones.

Creas un DataFrame con la etiqueta y la `predicción.

cm = predictions.select("label", "prediction")

Puedes consultar el número de clase en la etiqueta y la predicción.

cm.groupby('label').agg({'label': 'count'}).show()
+-----+------------+
|label|count(label)|
+-----+------------+
|  0.0|        5021|
|  1.0|        1578|
+-----+------------+
cm.groupby('prediction').agg({'prediction': 'count'}).show()
+----------+-----------------+
|prediction|count(prediction)|
+----------+-----------------+
|       0.0|             5982|
|       1.0|              617|
+----------+-----------------+

Por ejemplo, en el conjunto de prueba, hay 1578 hogares con ingresos superiores a 50 y 5021 por debajo. El clasificador, sin embargo, predijo 617 hogares con ingresos superiores a 50.

Puede calcular la precisión calculando el recuento cuando las etiquetas están clasificadas correctamente sobre el número total de filas.

cm.filter(cm.label == cm.prediction).count() / cm.count()

0.8237611759357478

Puede unir todo y escribir una función para calcular la precisión.

def accuracy_m(model): 
    predictions = model.transform(test_data)
    cm = predictions.select("label", "prediction")
    acc = cm.filter(cm.label == cm.prediction).count() / cm.count()
    print("Model accuracy: %.3f%%" % (acc * 100)) 
accuracy_m(model = linearModel)
Model accuracy: 82.376%

Métricas de la República de China

El módulo BinaryClassificationEvaluator incluye las medidas ROC. El receptor OperaLa curva característica es otra herramienta común utilizada con la clasificación binaria. Es muy similar a la curva de precisión/recuperación, pero en lugar de representar gráficamente la precisión versus la recuperación, la curva ROC muestra la tasa de verdaderos positivos (es decir, recuperación) frente a la tasa de falsos positivos. La tasa de falsos positivos es la proporción de casos negativos que se clasifican incorrectamente como positivos. Es igual a uno menos la tasa negativa verdadera. La tasa de verdaderos negativos también se llama especificidad. Por lo tanto, la curva ROC representa la sensibilidad (recuerdo) versus 1 – especificidad.

### Use ROC 
from pyspark.ml.evaluation import BinaryClassificationEvaluator

# Evaluate model
evaluator = BinaryClassificationEvaluator(rawPredictionCol="rawPrediction")
print(evaluator.evaluate(predictions))
print(evaluator.getMetricName())

0.8940481662695192áreaBajoROC

print(evaluator.evaluate(predictions))

0.8940481662695192

Paso 6) Ajusta el hiperparámetro

Por último, pero no menos importante, puedes ajustar los hiperparámetros. De forma similar a scikit-learn, creas una cuadrícula de parámetros y añades los que deseas ajustar.

Para reducir el tiempo de cálculo, solo ajusta el parámetro de regularización con solo dos valores.

from pyspark.ml.tuning import ParamGridBuilder, CrossValidator

# Create ParamGrid for Cross Validation
paramGrid = (ParamGridBuilder()
             .addGrid(lr.regParam, [0.01, 0.5])
             .build())

Finalmente, se evalúa el modelo mediante el método de validación cruzada con 5 pliegues. El entrenamiento tarda aproximadamente 16 minutos.

from time import *
start_time = time()

# Create 5-fold CrossValidator
cv = CrossValidator(estimator=lr,
                    estimatorParamMaps=paramGrid,
                    evaluator=evaluator, numFolds=5)

# Run cross validations
cvModel = cv.fit(train_data)
# likely take a fair amount of time
end_time = time()
elapsed_time = end_time - start_time
print("Time to train model: %.3f seconds" % elapsed_time)

Tiempo para entrenar el modelo: 978.807 segundos.

El mejor hiperparámetro de regularización es 0.01, con una precisión del 85.316 por ciento.

accuracy_m(model = cvModel)
Model accuracy: 85.316%

Puedes extract el parámetro recomendado encadenando cvModel.bestModel con extractParamMap()

bestModel = cvModel.bestModel
bestModel.extractParamMap()
{Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='aggregationDepth', doc='suggested depth for treeAggregate (>= 2)'): 2,
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='elasticNetParam', doc='the ElasticNet mixing parameter, in range [0, 1]. For alpha = 0, the penalty is an L2 penalty. For alpha = 1, it is an L1 penalty'): 0.0,
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='family', doc='The name of family which is a description of the label distribution to be used in the model. Supported options: auto, binomial, multinomial.'): 'auto',
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='featuresCol', doc='features column name'): 'features',
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='fitIntercept', doc='whether to fit an intercept term'): True,
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='labelCol', doc='label column name'): 'label',
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='maxIter', doc='maximum number of iterations (>= 0)'): 10,
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='predictionCol', doc='prediction column name'): 'prediction',
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='probabilityCol', doc='Column name for predicted class conditional probabilities. Note: Not all models output well-calibrated probability estimates! These probabilities should be treated as confidences, not precise probabilities'): 'probability',
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='rawPredictionCol', doc='raw prediction (a.k.a. confidence) column name'): 'rawPrediction',
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='regParam', doc='regularization parameter (>= 0)'): 0.01,
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='standardization', doc='whether to standardize the training features before fitting the model'): True,
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='threshold', doc='threshold in binary classification prediction, in range [0, 1]'): 0.5,
 Param(parent='LogisticRegression_4d8f8ce4d6a02d8c29a0', name='tol', doc='the convergence tolerance for iterative algorithms (>= 0)'): 1e-06}

Preguntas Frecuentes

Un RDD es una colección distribuida sin tipo que se transforma con map y filter. Un DataFrame añade un esquema con nombre y se procesa mediante el optimizador Catalyst, por lo que suele ser más rápido y sencillo consultar datos estructurados.

Spark Se requiere 2.x Java 8 solamente. Spark 3.x y 4.x se ejecutan en Java 8, 11 y 17, y apoyo Python 3.8 en adelante. Siempre haga coincidir el JDK con el Spark lanzamiento, porque una versión más reciente de JDK rompe las versiones anteriores.

Los asistentes de IA leen Spark Las métricas de la interfaz de usuario y los planes de ejecución permiten detectar particiones desequilibradas, redistribuciones excesivas y derrames de memoria, y luego sugieren la redistribución de particiones o las uniones por difusión. Esto reduce el trabajo de optimización que antes requería la inspección manual de cada etapa de ejecución.

Copilot redacta bien el código estándar: conversiones con `withColumn`, agregaciones `groupBy` y etapas de canalización. Los nombres de las columnas y las claves de unión aún necesitan verificarse con respecto al esquema real, ya que el código generado compila sin problemas, pero selecciona silenciosamente el campo incorrecto.

Elija pandas mientras los datos quepan cómodamente en la memoria de una máquina. Pase a Py.Spark cuando los archivos superan la RAM disponible, cuando el trabajo debe ejecutarse en un clúster o cuando el mismo trabajo alimenta una canalización de producción en lugar de un cuaderno exploratorio.

Py4JJavaEl error muestra una excepción de JVM a través de la Python puente. Los desencadenantes comunes son un JDK faltante o incompatible, un JAVA_HOME no configurado o un PySpark versión construida contra una diferente Spark liberación que la del camino.

Guarda el script como un archivo .py y ejecútalo con spark-submit, agregando –master para seleccionar el modo local o de clúster. El mismo código que se ejecuta dentro Jupyter funciona sin cambios una vez que SparkLa sesión se crea explícitamente.

Las transformaciones como map, filter y withColumn solo crean un plan. Nada se ejecuta hasta que se ejecuta una acción como count, collect o show. Spark Luego, optimiza toda la cadena a la vez, lo que evita escribir resultados intermedios innecesarios.

Resumir este post con: