Uso de Apache Spark MLlib para compilar una aplicación de aprendizaje automático y analizar un conjunto de datosUse Apache Spark MLlib to build a machine learning application and analyze a dataset

Aprenda a usar Apache Spark MLlib para crear una aplicación de aprendizaje automático para efectuar análisis predictivos simples en un conjunto de datos abierto.Learn how to use Apache Spark MLlib to create a machine learning application to do simple predictive analysis on an open dataset. De las bibliotecas de aprendizaje automático integradas de Spark, en este ejemplo se usa una clasificación mediante una regresión logística.From Spark's built-in machine learning libraries, this example uses classification through logistic regression.

MLlib es una biblioteca básica de Spark que proporciona numerosas utilidades que resultan prácticas para las tareas de aprendizaje automático, como utilidades adecuadas para:MLlib is a core Spark library that provides many utilities useful for machine learning tasks, including utilities that are suitable for:

  • clasificaciónClassification
  • RegresiónRegression
  • Agrupación en clústeresClustering
  • Modelado de temaTopic modeling
  • Descomposición en valores singulares (SVD) y Análisis de los componentes principales (PCA)Singular value decomposition (SVD) and principal component analysis (PCA)
  • Comprobación de hipótesis y cálculo de estadísticas de ejemploHypothesis testing and calculating sample statistics

Comprensión de la clasificación y la regresión logísticaUnderstand classification and logistic regression

Clasificación, una tarea habitual en el aprendizaje automático, es el proceso de ordenación de datos de entrada en categorías.Classification, a popular machine learning task, is the process of sorting input data into categories. El trabajo de averiguar cómo asignar "etiquetas" a las entradas de datos que se proporcionen lo realiza un algoritmo de clasificación.It is the job of a classification algorithm to figure out how to assign "labels" to input data that you provide. Por ejemplo, imagínese un algoritmo de aprendizaje automático que acepta información bursátil como entrada y divide las existencias en dos categorías: acciones que se deberían vender y acciones que se deberían conservar.For example, you could think of a machine learning algorithm that accepts stock information as input and divides the stock into two categories: stocks that you should sell and stocks that you should keep.

La regresión logística es el algoritmo que se usa para la clasificación.Logistic regression is the algorithm that you use for classification. La API de regresión logística de Spark es útil para la clasificación binaria, o para la clasificación de datos de entrada en uno de los dos grupos.Spark's logistic regression API is useful for binary classification, or classifying input data into one of two groups. Para obtener más información acerca de la regresión logística, consulte Wikipedia.For more information about logistic regressions, see Wikipedia.

En resumen, el proceso de regresión logística genera una función logística que se puede usar para predecir la probabilidad de que un vector de entrada pertenezca a un grupo o al otro.In summary, the process of logistic regression produces a logistic function that can be used to predict the probability that an input vector belongs in one group or the other.

Ejemplo de análisis predictivo en datos de inspección alimentariaPredictive analysis example on food inspection data

En este ejemplo usará Spark para llevar a cabo un análisis predictivo sobre unos datos de inspección alimentaria (Food_Inspections1.csv) que se han adquirido a través del portal de datos de la ciudad de Chicago.In this example, you use Spark to perform some predictive analysis on food inspection data (Food_Inspections1.csv) that was acquired through the City of Chicago data portal. Este conjunto de datos contiene información sobre las inspecciones alimentarias que se llevaron a cabo en establecimientos de Chicago (información sobre cada establecimiento, las infracciones que se detectaron (en caso de detectarse alguna) y los resultados de la inspección).This dataset contains information about food establishment inspections that were conducted in Chicago, including information about each establishment, the violations found (if any), and the results of the inspection. El archivo de datos CSV ya está disponible en la cuenta de almacenamiento asociada al clúster, en /HdiSamples/HdiSamples/FoodInspectionData/Food_Inspections1.csv.The CSV data file is already available in the storage account associated with the cluster at /HdiSamples/HdiSamples/FoodInspectionData/Food_Inspections1.csv.

En los pasos siguientes, va a desarrollar un modelo para ver lo que es necesario para superar o no una inspección de alimentos.In the steps below, you develop a model to see what it takes to pass or fail a food inspection.

Creación de una aplicación de aprendizaje automático de Apache Spark MLlibCreate an Apache Spark MLlib machine learning app

  1. Cree un cuaderno de Jupyter Notebook con el kernel de PySpark.Create a Jupyter notebook using the PySpark kernel. Para las instrucciones, consulte Creación de un cuaderno de Jupyter Notebook.For the instructions, see Create a Jupyter notebook.

  2. Importe los tipos necesarios para esta aplicación.Import the types required for this application. Copie y pegue el código siguiente en una celda vacía y, a continuación, presione MAYÚS + ENTRAR.Copy and paste the following code into an empty cell, and then press SHIFT + ENTER.

    from pyspark.ml import Pipeline
    from pyspark.ml.classification import LogisticRegression
    from pyspark.ml.feature import HashingTF, Tokenizer
    from pyspark.sql import Row
    from pyspark.sql.functions import UserDefinedFunction
    from pyspark.sql.types import *
    

    Por la existencia del kernel PySpark, no necesitará crear ningún contexto explícitamente.Because of the PySpark kernel, you do not need to create any contexts explicitly. Los contextos de Spark y Hive se crean automáticamente al ejecutar la primera celda de código.The Spark and Hive contexts are automatically created for you when you run the first code cell.

Construcción de una trama de datos de entradaConstruct the input dataframe

Dado que los datos sin procesar están en formato CSV, puede usar el contexto de Spark para extraer el archivo en memoria como texto no estructurado y después usar la biblioteca CSV de Python para analizar cada línea de datos.Because the raw data is in a CSV format, you can use the Spark context to pull the file into memory as unstructured text, and then use Python's CSV library to parse each line of the data.

  1. Ejecute las líneas siguientes para crear un conjunto de datos distribuido resistente (RDD) mediante la importación y el análisis de los datos de entrada.Run the following lines to create a Resilient Distributed Dataset (RDD) by importing and parsing the input data.

    def csvParse(s):
        import csv
        from StringIO import StringIO
        sio = StringIO(s)
        value = csv.reader(sio).next()
        sio.close()
        return value
    
    inspections = sc.textFile('/HdiSamples/HdiSamples/FoodInspectionData/Food_Inspections1.csv')\
                    .map(csvParse)
    
  2. Ejecute el siguiente código para recuperar una fila del RDD, a fin de poder echar un vistazo al esquema de datos:Run the following code to retrieve one row from the RDD, so you can take a look of the data schema:

    inspections.take(1)
    

    La salida es la siguiente:The output is:

    [['413707',
        'LUNA PARK INC',
        'LUNA PARK  DAY CARE',
        '2049789',
        "Children's Services Facility",
        'Risk 1 (High)',
        '3250 W FOSTER AVE ',
        'CHICAGO',
        'IL',
        '60625',
        '09/21/2010',
        'License-Task Force',
        'Fail',
        '24. DISH WASHING FACILITIES: PROPERLY DESIGNED, CONSTRUCTED, MAINTAINED, INSTALLED, LOCATED AND OPERATED - Comments: All dishwashing machines must be of a type that complies with all requirements of the plumbing section of the Municipal Code of Chicago and Rules and Regulation of the Board of Health. OBSEVERD THE 3 COMPARTMENT SINK BACKING UP INTO THE 1ST AND 2ND COMPARTMENT WITH CLEAR WATER AND SLOWLY DRAINING OUT. INST NEED HAVE IT REPAIR. CITATION ISSUED, SERIOUS VIOLATION 7-38-030 H000062369-10 COURT DATE 10-28-10 TIME 1 P.M. ROOM 107 400 W. SURPERIOR. | 36. LIGHTING: REQUIRED MINIMUM FOOT-CANDLES OF LIGHT PROVIDED, FIXTURES SHIELDED - Comments: Shielding to protect against broken glass falling into food shall be provided for all artificial lighting sources in preparation, service, and display facilities. LIGHT SHIELD ARE MISSING UNDER HOOD OF  COOKING EQUIPMENT AND NEED TO REPLACE LIGHT UNDER UNIT. 4 LIGHTS ARE OUT IN THE REAR CHILDREN AREA,IN THE KINDERGARDEN CLASS ROOM. 2 LIGHT ARE OUT EAST REAR, LIGHT FRONT WEST ROOM. NEED TO REPLACE ALL LIGHT THAT ARE NOT WORKING. | 35. WALLS, CEILINGS, ATTACHED EQUIPMENT CONSTRUCTED PER CODE: GOOD REPAIR, SURFACES CLEAN AND DUST-LESS CLEANING METHODS - Comments: The walls and ceilings shall be in good repair and easily cleaned. MISSING CEILING TILES WITH STAINS IN WEST,EAST, IN FRONT AREA WEST, AND BY THE 15MOS AREA. NEED TO BE REPLACED. | 32. FOOD AND NON-FOOD CONTACT SURFACES PROPERLY DESIGNED, CONSTRUCTED AND MAINTAINED - Comments: All food and non-food contact equipment and utensils shall be smooth, easily cleanable, and durable, and shall be in good repair. SPLASH GUARDED ARE NEEDED BY THE EXPOSED HAND SINK IN THE KITCHEN AREA | 34. FLOORS: CONSTRUCTED PER CODE, CLEANED, GOOD REPAIR, COVING INSTALLED, DUST-LESS CLEANING METHODS USED - Comments: The floors shall be constructed per code, be smooth and easily cleaned, and be kept clean and in good repair. INST NEED TO ELEVATE ALL FOOD ITEMS 6INCH OFF THE FLOOR 6 INCH AWAY FORM WALL.  ',
        '41.97583445690982',
        '-87.7107455232781',
        '(41.97583445690982, -87.7107455232781)']]
    

    La salida nos da una idea del esquema del archivo de entrada.The output gives you an idea of the schema of the input file. Incluye el nombre de cada establecimiento, el tipo de establecimiento, la dirección, los datos de las inspecciones y la ubicación, entre otras cosas.It includes the name of every establishment, the type of establishment, the address, the data of the inspections, and the location, among other things.

  3. Ejecute el siguiente código para crear una trama de datos (df) y una tabla temporal (CountResults) con unas pocas columnas que son útiles para el análisis predictivo.Run the following code to create a dataframe (df) and a temporary table (CountResults) with a few columns that are useful for the predictive analysis. sqlContext se usa para realizar las transformaciones de datos estructurados.sqlContext is used to perform transformations on structured data.

    schema = StructType([
    StructField("id", IntegerType(), False),
    StructField("name", StringType(), False),
    StructField("results", StringType(), False),
    StructField("violations", StringType(), True)])
    
    df = spark.createDataFrame(inspections.map(lambda l: (int(l[0]), l[1], l[12], l[13])) , schema)
    df.registerTempTable('CountResults')
    

    Las cuatro columnas de interés de la trama de datos son id (identificador), name (nombre), results (resultados) y violations (infracciones).The four columns of interest in the dataframe are id, name, results, and violations.

  4. Ejecute el código siguiente para obtener una pequeña muestra de los datos:Run the following code to get a small sample of the data:

    df.show(5)
    

    La salida es la siguiente:The output is:

    +------+--------------------+-------+--------------------+
    |    id|                name|results|          violations|
    +------+--------------------+-------+--------------------+
    |413707|       LUNA PARK INC|   Fail|24. DISH WASHING ...|
    |391234|       CAFE SELMARIE|   Fail|2. FACILITIES TO ...|
    |413751|          MANCHU WOK|   Pass|33. FOOD AND NON-...|
    |413708|BENCHMARK HOSPITA...|   Pass|                    |
    |413722|           JJ BURGER|   Pass|                    |
    +------+--------------------+-------+--------------------+
    

Comprensión de los datosUnderstand the data

Vamos a empezar a hacernos una idea de lo que contiene el conjunto de datos.Let's start to get a sense of what the dataset contains.

  1. Ejecute el siguiente código para mostrar los valores distintos en la columna results (resultados):Run the following code to show the distinct values in the results column:

    df.select('results').distinct().show()
    

    La salida es la siguiente:The output is:

    +--------------------+
    |             results|
    +--------------------+
    |                Fail|
    |Business Not Located|
    |                Pass|
    |  Pass w/ Conditions|
    |     Out of Business|
    +--------------------+
    
  2. Ejecute el siguiente código para visualizar la distribución de estos resultados:Run the following code to visualize the distribution of these results:

    %%sql -o countResultsdf
    SELECT COUNT(results) AS cnt, results FROM CountResults GROUP BY results
    

    La instrucción mágica %%sql seguida de -o countResultsdf garantiza que el resultado de la consulta persista localmente en el servidor de Jupyter (normalmente, el nodo principal del clúster).The %%sql magic followed by -o countResultsdf ensures that the output of the query is persisted locally on the Jupyter server (typically the headnode of the cluster). El resultado se conserva como una trama de datos Pandas con el nombre especificado countResultsdf.The output is persisted as a Pandas dataframe with the specified name countResultsdf. Para más información sobre la instrucción mágica %%sql, así como otras instrucciones mágicas disponibles con el kernel de PySpark, consulte Kernels disponibles en Jupyter Notebook con clústeres de Apache Spark en HDInsight.For more information about the %%sql magic, and other magics available with the PySpark kernel, see Kernels available on Jupyter notebooks with Apache Spark HDInsight clusters.

    La salida es la siguiente:The output is:

    Salida de la consulta SQLSQL query output

  3. También puede utilizar Matplotlib, una biblioteca que se usa para construir la visualización de datos, para crear un trazado.You can also use Matplotlib, a library used to construct visualization of data, to create a plot. Dado que el gráfico debe crearse a partir de la trama de datos localmente persistente countResultsdf, el fragmento de código debe comenzar con la instrucción mágica %%local.Because the plot must be created from the locally persisted countResultsdf dataframe, the code snippet must begin with the %%local magic. Esto garantiza que el código se ejecuta localmente en el servidor de Jupyter.This ensures that the code is run locally on the Jupyter server.

    %%local
    %matplotlib inline
    import matplotlib.pyplot as plt
    
    labels = countResultsdf['results']
    sizes = countResultsdf['cnt']
    colors = ['turquoise', 'seagreen', 'mediumslateblue', 'palegreen', 'coral']
    plt.pie(sizes, labels=labels, autopct='%1.1f%%', colors=colors)
    plt.axis('equal')
    

    La salida es la siguiente:The output is:

    Salida de la aplicación de aprendizaje automático de Spark: gráfico circular con cinco resultados de inspección distintosSpark machine learning application output - pie chart with five distinct inspection results

    Para predecir un resultado de inspección de alimentos, debe desarrollar un modelo basado en las infracciones.To predict a food inspection outcome, you need to develop a model based on the violations. Puesto que la regresión logística es un método de clasificación binaria, tiene sentido agrupar los datos de los resultados en dos categorías: Fail y Pass:Because logistic regression is a binary classification method, it makes sense to group the result data into two categories: Fail and Pass:

    • Pass (pasado)Pass

      • Pass (pasado)Pass
      • Pass w/ conditions (superado con condiciones)Pass w/ conditions
    • Fail (no superado)Fail

      • Fail (no superado)Fail
    • Discard (Descartar)Discard

      • Business not located (no se encontró el negocio)Business not located
      • Out of Business (negocio cerrado)Out of Business

      Los datos con los demás resultados, como "Business Not Located" (No se encontró el negocio) o "Out of Business" (Negocio cerrado), no son útiles y constituyen un porcentaje muy bajo de los resultados.Data with the other results ("Business Not Located" or "Out of Business") are not useful, and they make up a very small percentage of the results anyway.

  4. Ejecute el siguiente código para convertir la trama de datos existente (df) en una trama de datos nueva, donde cada inspección se representa como un par de etiquetas de infracción.Run the following code to convert the existing dataframe(df) into a new dataframe where each inspection is represented as a label-violations pair. En este caso, una etiqueta de 0.0 representa un resultado de "no superado", una etiqueta de 1.0 representa un resultado de "pasado" y una etiqueta de -1.0 representa resultados que no sean los dos anteriores.In this case, a label of 0.0 represents a failure, a label of 1.0 represents a success, and a label of -1.0 represents some results besides those two.

    def labelForResults(s):
        if s == 'Fail':
            return 0.0
        elif s == 'Pass w/ Conditions' or s == 'Pass':
            return 1.0
        else:
            return -1.0
    label = UserDefinedFunction(labelForResults, DoubleType())
    labeledData = df.select(label(df.results).alias('label'), df.violations).where('label >= 0')
    
  5. Ejecute el siguiente código para mostrar una fila de los datos etiquetados:Run the following code to show one row of the labeled data:

    labeledData.take(1)
    

    La salida es la siguiente:The output is:

    [Row(label=0.0, violations=u"41. PREMISES MAINTAINED FREE OF LITTER, UNNECESSARY ARTICLES, CLEANING  EQUIPMENT PROPERLY STORED - Comments: All parts of the food establishment and all parts of the property used in connection with the operation of the establishment shall be kept neat and clean and should not produce any offensive odors.  REMOVE MATTRESS FROM SMALL DUMPSTER. | 35. WALLS, CEILINGS, ATTACHED EQUIPMENT CONSTRUCTED PER CODE: GOOD REPAIR, SURFACES CLEAN AND DUST-LESS CLEANING METHODS - Comments: The walls and ceilings shall be in good repair and easily cleaned.  REPAIR MISALIGNED DOORS AND DOOR NEAR ELEVATOR.  DETAIL CLEAN BLACK MOLD LIKE SUBSTANCE FROM WALLS BY BOTH DISH MACHINES.  REPAIR OR REMOVE BASEBOARD UNDER DISH MACHINE (LEFT REAR KITCHEN). SEAL ALL GAPS.  REPLACE MILK CRATES USED IN WALK IN COOLERS AND STORAGE AREAS WITH PROPER SHELVING AT LEAST 6' OFF THE FLOOR.  | 38. VENTILATION: ROOMS AND EQUIPMENT VENTED AS REQUIRED: PLUMBING: INSTALLED AND MAINTAINED - Comments: The flow of air discharged from kitchen fans shall always be through a duct to a point above the roofline.  REPAIR BROKEN VENTILATION IN MEN'S AND WOMEN'S WASHROOMS NEXT TO DINING AREA. | 32. FOOD AND NON-FOOD CONTACT SURFACES PROPERLY DESIGNED, CONSTRUCTED AND MAINTAINED - Comments: All food and non-food contact equipment and utensils shall be smooth, easily cleanable, and durable, and shall be in good repair.  REPAIR DAMAGED PLUG ON LEFT SIDE OF 2 COMPARTMENT SINK.  REPAIR SELF CLOSER ON BOTTOM LEFT DOOR OF 4 DOOR PREP UNIT NEXT TO OFFICE.")]
    

Creación de un modelo de regresión logística a partir de la trama de datos de entradaCreate a logistic regression model from the input dataframe

La última tarea consiste en convertir los datos etiquetados a un formato que se pueda analizar con la regresión logística.The final task is to convert the labeled data into a format that can be analyzed by logistic regression. La entrada a un algoritmo de regresión logística debe ser un conjunto de pares de vector de característica de etiqueta, donde el "vector de característica" es un vector de números que representa el punto de entrada.The input to a logistic regression algorithm needs be a set of label-feature vector pairs, where the "feature vector" is a vector of numbers representing the input point. Por lo tanto, debemos convertir la columna "violations", que está semiestructurada y contiene numerosos comentarios de texto sin formato, en una matriz de números reales que una máquina pueda comprender.So, you need to convert the "violations" column, which is semi-structured and contains many comments in free-text, to an array of real numbers that a machine could easily understand.

Un enfoque estándar en el aprendizaje automático para procesar el lenguaje natural consiste en asignar a cada palabra diferente un "índice" y, a continuación, pasar un vector al algoritmo de aprendizaje automático, de forma que el valor de cada índice contenga la frecuencia relativa de esa palabra en la cadena de texto.One standard machine learning approach for processing natural language is to assign each distinct word an "index", and then pass a vector to the machine learning algorithm such that each index's value contains the relative frequency of that word in the text string.

MLlib proporciona una forma sencilla de efectuar esta operación.MLlib provides an easy way to perform this operation. En primer lugar, vamos a tratar como tokens todas las cadenas de infracciones para obtener las palabras de cada cadena.First, "tokenize" each violations string to get the individual words in each string. Luego, use un HashingTF para convertir cada conjunto de tokens en un vector de característica que se pueda pasar al algoritmo de regresión logística para construir un modelo.Then, use a HashingTF to convert each set of tokens into a feature vector that can then be passed to the logistic regression algorithm to construct a model. Llevaremos a cabo todos estos pasos en secuencia mediante una canalización.You conduct all of these steps in sequence using a "pipeline".

tokenizer = Tokenizer(inputCol="violations", outputCol="words")
hashingTF = HashingTF(inputCol=tokenizer.getOutputCol(), outputCol="features")
lr = LogisticRegression(maxIter=10, regParam=0.01)
pipeline = Pipeline(stages=[tokenizer, hashingTF, lr])

model = pipeline.fit(labeledData)

Evaluación del modelo con otro conjunto de datosEvaluate the model using another dataset

Se puede usar el modelo creado anteriormente para predecir cuáles serán los resultados de las nuevas inspecciones, en función de las infracciones que se han observado.You can use the model you created earlier to predict what the results of new inspections will be, based on the violations that were observed. Este modelo se ha probado en el conjunto de datos Food_Inspections1.csv.You trained this model on the dataset Food_Inspections1.csv. Puede usar un segundo conjunto de datos, Food_Inspections2.csv, para evaluar la solidez de este modelo con nuevos datos.You can use a second dataset, Food_Inspections2.csv, to evaluate the strength of this model on the new data. Este segundo conjunto de datos (Food_Inspections2.csv) está en el contenedor de almacenamiento predeterminado asociado al clúster.This second data set (Food_Inspections2.csv) is in the default storage container associated with the cluster.

  1. Ejecute el siguiente fragmento de código para crear una trama de datos, predictionsDf, que contiene la predicción generada por el modelo.Run the following code to create a new dataframe, predictionsDf that contains the prediction generated by the model. El fragmento de código también crea una tabla temporal, llamada Predictions, basada en la trama de datos.The snippet also creates a temporary table called Predictions based on the dataframe.

    testData = sc.textFile('wasbs:///HdiSamples/HdiSamples/FoodInspectionData/Food_Inspections2.csv')\
                .map(csvParse) \
                .map(lambda l: (int(l[0]), l[1], l[12], l[13]))
    testDf = spark.createDataFrame(testData, schema).where("results = 'Fail' OR results = 'Pass' OR results = 'Pass w/ Conditions'")
    predictionsDf = model.transform(testDf)
    predictionsDf.registerTempTable('Predictions')
    predictionsDf.columns
    

    Debe ver algo parecido a lo siguiente:You should see an output like the following:

    ['id',
        'name',
        'results',
        'violations',
        'words',
        'features',
        'rawPrediction',
        'probability',
        'prediction']
    
  2. Examine una de las predicciones.Look at one of the predictions. Ejecute este fragmento de código:Run this snippet:

    predictionsDf.take(1)
    

    Hay una predicción para la primera entrada en el conjunto de datos de prueba.There is a prediction for the first entry in the test data set.

  3. El método model.transform() aplica la misma transformación a todos los datos nuevos que tengan el mismo esquema y llega a una predicción sobre cómo clasificar los datos.The model.transform() method applies the same transformation to any new data with the same schema, and arrive at a prediction of how to classify the data. Haremos algunas estadísticas muy sencillas para tener una idea del grado de precisión de las predicciones:You can do some simple statistics to get a sense of how accurate the predictions were:

    numSuccesses = predictionsDf.where("""(prediction = 0 AND results = 'Fail') OR
                                            (prediction = 1 AND (results = 'Pass' OR
                                                                results = 'Pass w/ Conditions'))""").count()
    numInspections = predictionsDf.count()
    
    print "There were", numInspections, "inspections and there were", numSuccesses, "successful predictions"
    print "This is a", str((float(numSuccesses) / float(numInspections)) * 100) + "%", "success rate"
    

    El resultado tendrá un aspecto similar al siguiente:The output looks like the following:

    There were 9315 inspections and there were 8087 successful predictions
    This is a 86.8169618894% success rate
    

    El uso de la regresión logística con Spark ofrece un modelo preciso de la relación entre las descripciones de las infracciones en inglés y el hecho de si un negocio determinado superará o no una inspección de alimentos.Using logistic regression with Spark gives you an accurate model of the relationship between violations descriptions in English and whether a given business would pass or fail a food inspection.

Creación de una representación visual de la predicciónCreate a visual representation of the prediction

Ahora se puede crear una visualización final para facilitar el análisis de los resultados de esta prueba.You can now construct a final visualization to help you reason about the results of this test.

  1. Primero se extraen los distintos resultados y predicciones de la tabla temporal Predictions que se creó anteriormente.You start by extracting the different predictions and results from the Predictions temporary table created earlier. Las siguientes consultas separan la salida en distintos grupos: true_positive, false_positive, true_negative y false_negative.The following queries separate the output as true_positive, false_positive, true_negative, and false_negative. En las consultas siguientes, se desactiva la visualización mediante -q y se guarda también la salida (con -o) como tramas de datos que se usen con la instrucción mágica %%local.In the queries below, you turn off visualization by using -q and also save the output (by using -o) as dataframes that can be then used with the %%local magic.

    %%sql -q -o true_positive
    SELECT count(*) AS cnt FROM Predictions WHERE prediction = 0 AND results = 'Fail'
    
    %%sql -q -o false_positive
    SELECT count(*) AS cnt FROM Predictions WHERE prediction = 0 AND (results = 'Pass' OR results = 'Pass w/ Conditions')
    
    %%sql -q -o true_negative
    SELECT count(*) AS cnt FROM Predictions WHERE prediction = 1 AND results = 'Fail'
    
    %%sql -q -o false_negative
    SELECT count(*) AS cnt FROM Predictions WHERE prediction = 1 AND (results = 'Pass' OR results = 'Pass w/ Conditions')
    
  2. Por último, utilice el siguiente fragmento de código para generar el gráfico mediante Matplotlib.Finally, use the following snippet to generate the plot using Matplotlib.

    %%local
    %matplotlib inline
    import matplotlib.pyplot as plt
    
    labels = ['True positive', 'False positive', 'True negative', 'False negative']
    sizes = [true_positive['cnt'], false_positive['cnt'], false_negative['cnt'], true_negative['cnt']]
    colors = ['turquoise', 'seagreen', 'mediumslateblue', 'palegreen', 'coral']
    plt.pie(sizes, labels=labels, autopct='%1.1f%%', colors=colors)
    plt.axis('equal')
    

    Debería ver la siguiente salida:You should see the following output:

    Salida de la aplicación de aprendizaje automático de Spark: gráfico circular con porcentajes de inspecciones alimentarias no superadasSpark machine learning application output - pie chart percentages of failed food inspections.

    En este gráfico, un resultado "positivo" hace referencia a la inspección de alimentos no superada, mientras que un resultado negativo hace referencia a una inspección pasada.In this chart, a "positive" result refers to the failed food inspection, while a negative result refers to a passed inspection.

Cierre del cuadernoShut down the notebook

Cuando haya terminado de ejecutar la aplicación, deberá cerrar el cuaderno para liberar los recursos.After you have finished running the application, you should shut down the notebook to release the resources. Para ello, en el menú File (Archivo) del cuaderno y seleccione Close and Halt (Cerrar y detener).To do so, from the File menu on the notebook, select Close and Halt. Con esta acción se cerrará el cuaderno.This shuts down and closes the notebook.

Consulte tambiénSee also

EscenariosScenarios

Creación y ejecución de aplicacionesCreate and run applications

Herramientas y extensionesTools and extensions

Administración de recursosManage resources