Use o Apache Spark MLlib para criar um aplicativo de aprendizado de máquina e analisar um conjunto de dadosUse Apache Spark MLlib to build a machine learning application and analyze a dataset

Aprenda como usar o Apache Spark MLlib para criar um aplicativo de aprendizado de máquina para fazer uma análise preditiva simples em um conjunto de dados aberto.Learn how to use Apache Spark MLlib to create a machine learning application to do simple predictive analysis on an open dataset. Das bibliotecas aprendizado de máquina internas do Spark, este exemplo usa classificação por meio de regressão logística.From Spark's built-in machine learning libraries, this example uses classification through logistic regression.

MLlib é uma biblioteca Spark principal que fornece vários utilitários úteis para tarefas de aprendizado de máquina, incluindo utilitários adequados para:MLlib is a core Spark library that provides many utilities useful for machine learning tasks, including utilities that are suitable for:

  • classificaçãoClassification
  • RegressãoRegression
  • ClusteringClustering
  • Modelagem de tópicoTopic modeling
  • Decomposição de valor singular (SVD) e análise de componente principal (PCA)Singular value decomposition (SVD) and principal component analysis (PCA)
  • Teste de hipótese e cálculo de estatísticas de exemploHypothesis testing and calculating sample statistics

Compreender a classificação e regressão logísticaUnderstand classification and logistic regression

Classificação, uma tarefa popular de aprendizado de máquina, é o processo de classificação de dados de entrada em categorias.Classification, a popular machine learning task, is the process of sorting input data into categories. É o trabalho de um algoritmo de classificação para descobrir como atribuir "rótulos" a dados de entrada que você fornece.It is the job of a classification algorithm to figure out how to assign "labels" to input data that you provide. Por exemplo, você pode pensar em um algoritmo de aprendizado de máquina que aceite informações sobre estoque como entrada e divida o estoque em duas categorias: estoque que você deve vender e estoque que deve ser mantido.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.

Regressão logística é o algoritmo usado para classificação.Logistic regression is the algorithm that you use for classification. A API de regressão logística do Spark é útil para classificação bináriaou para classificação de dados de entrada em um dos dois grupos.Spark's logistic regression API is useful for binary classification, or classifying input data into one of two groups. Para obter mais informações sobre a regressão logística, consulte Wikipédia.For more information about logistic regressions, see Wikipedia.

Em resumo, o processo de regressão logística produz uma função logística que pode ser usada para prever a probabilidade de um vetor de entrada pertencer a um grupo ou outro.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.

Exemplo de análise preditiva em dados de inspeção de alimentosPredictive analysis example on food inspection data

Neste exemplo, você usa o Spark para executar uma análise preditiva sobre os dados de inspeção de alimentos (Food_Inspections1.csv) que foi adquirido por meio do portal de dados da cidade 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. Esse conjunto de dados contém informações sobre inspeções de estabelecimentos de alimentos realizadas em Chicago, incluindo informações sobre cada estabelecimento de alimentos inspecionado, as violações encontradas (se houver) e os resultados da inspeção.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. O arquivo de dados CSV já está disponível na conta de armazenamento associada ao cluster em /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.

Nas etapas a seguir, você desenvolverá um modelo para ver o que é necessário para ser aprovado ou reprovado em uma inspeção de alimentos.In the steps below, you develop a model to see what it takes to pass or fail a food inspection.

Crie um aplicativo de aprendizado de máquina Apache Spark MLlibCreate an Apache Spark MLlib machine learning app

  1. Crie um bloco de notas do Jupyter usando o kernel PySpark.Create a Jupyter notebook using the PySpark kernel. Para obter instruções, consulte Criar um bloco de notas do Jupyter.For the instructions, see Create a Jupyter notebook.

  2. Importe os tipos obrigatórios necessários para este aplicativo.Import the types required for this application. Copie e cole o código a seguir em uma célula vazia e, em seguida, pressione SHIFT + ENTER.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 causa do kernel PySpark, não será necessário criar nenhum contexto explicitamente.Because of the PySpark kernel, you do not need to create any contexts explicitly. Os contextos do Spark e do Hive são criados automaticamente para você ao executar a primeira célula do código.The Spark and Hive contexts are automatically created for you when you run the first code cell.

Construir o dataframe de entradaConstruct the input dataframe

Como os dados brutos estão em formato CSV, você pode usar o contexto do Spark para efetuar pull do arquivo na memória como texto não estruturado; em seguida, use a biblioteca CSV do Python para analisar cada linha dos dados.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. Execute as seguintes linhas para criar um RDD (Conjunto de Dados distribuídos resiliente), importando e analisando os dados 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. Execute o seguinte código para recuperar uma linha de RDD, portanto você pode dar uma olhada do esquema de dados:Run the following code to retrieve one row from the RDD, so you can take a look of the data schema:

    inspections.take(1)
    

    A saída é: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)']]
    

    A saída anterior lhe dá uma ideia do esquema do arquivo de entrada.The output gives you an idea of the schema of the input file. Ele inclui o nome de cada estabelecimento, o tipo de estabelecimento, o endereço, os dados da inspeção e a localização, entre outras informações.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. Execute o seguinte código para criar um dataframe (df) e uma tabela temporária (CountResults) com algumas colunas que são úteis para a análise de previsão.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 é usado para executar transformações de dados estruturados.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')
    

    As quatro colunas de interesse no dataframe são id, nome, resultados e violações.The four columns of interest in the dataframe are id, name, results, and violations.

  4. Execute o código a seguir para obter uma pequena amostra dos dados:Run the following code to get a small sample of the data:

    df.show(5)
    

    A saída é: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|                    |
    +------+--------------------+-------+--------------------+
    

Entender os dadosUnderstand the data

Vamos começar a ter uma ideia do que o nosso conjunto de dados contém.Let's start to get a sense of what the dataset contains.

  1. Execute o seguinte código para mostrar os valores distintos na coluna resultados:Run the following code to show the distinct values in the results column:

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

    A saída é:The output is:

    +--------------------+
    |             results|
    +--------------------+
    |                Fail|
    |Business Not Located|
    |                Pass|
    |  Pass w/ Conditions|
    |     Out of Business|
    +--------------------+
    
  2. Execute o seguinte código para visualizar a distribuição desses 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
    

    A mágica do %%sql seguido pelo -o countResultsdf assegura que a saída da consulta seja mantida localmente no servidor Jupyter (normalmente o nó principal do cluster).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). A saída é mantida como uma estrutura de dados Pandas com o nome especificado countResultsdf.The output is persisted as a Pandas dataframe with the specified name countResultsdf. Para obter mais informações sobre a mágica %%sql e outras magias disponíveis com o kernel do PySpark, consulte Kernels disponíveis em notebooks Jupyter com clusters do Apache Spark 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.

    A saída é:The output is:

    Saída da consulta SQLSQL query output

  3. Você também pode usar Matplotlib, uma biblioteca usada para construir a visualização de dados para criar um gráfico.You can also use Matplotlib, a library used to construct visualization of data, to create a plot. Como o gráfico deve ser criado a partir do dataframe countResultsdf mantido localmente, o snippet de código deve começar com a mágica %%local.Because the plot must be created from the locally persisted countResultsdf dataframe, the code snippet must begin with the %%local magic. Isso garante que o código seja executado localmente no servidor do 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')
    

    A saída é:The output is:

    Saída do aplicativo de aprendizado de máquina do Spark – gráfico de pizza com cinco conjuntos de resultados de inspeção distintosSpark machine learning application output - pie chart with five distinct inspection results

    Para prever um resultado de inspeção de alimentos, você precisa desenvolver um modelo com base nas violações.To predict a food inspection outcome, you need to develop a model based on the violations. Como a regressão logística é um método de classificação binária, é recomendável agrupar os dados do resultado em duas categorias: Reprovado e Aprovado:Because logistic regression is a binary classification method, it makes sense to group the result data into two categories: Fail and Pass:

    • AprovadoPass

      • AprovadoPass
      • Aprovado c/ condiçõesPass w/ conditions
    • ReprovadoFail

      • ReprovadoFail
    • DescartarDiscard

      • Negócios não localizadosBusiness not located
      • Fora de negócioOut of Business

      Dados com os outros resultados ("Negócios não localizados" ou "Cessação de atividades") não são úteis, e eles formam uma porcentagem muito pequena dos resultados de qualquer forma.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. Execute o código a seguir para converter nosso dataframe existente (df) em um novo dataframe em que cada inspeção é representada como um par de violações de rótulo.Run the following code to convert the existing dataframe(df) into a new dataframe where each inspection is represented as a label-violations pair. Nesse caso, um rótulo de 0.0 representa uma falha, um rótulo de 1.0 representa um sucesso e um rótulo de -1.0 representa alguns resultados diferentes desses dois.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. Execute o seguinte código para mostrar uma linha de dados rotulados:Run the following code to show one row of the labeled data:

    labeledData.take(1)
    

    A saída é: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.")]
    

Criar um modelo de regressão logística do dataframe de entradaCreate a logistic regression model from the input dataframe

A tarefa final é converter os dados rotulados para um formato que possa ser analisado pela regressão logística.The final task is to convert the labeled data into a format that can be analyzed by logistic regression. A entrada para um algoritmo de regressão logística precisa ser um conjunto de pares de vetor de recurso de rótulo, em que o “vetor de recurso” é um vetor de números que representa o ponto 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. Portanto, você precisa converter a coluna "violações", que é semiestruturada e contém muitos comentários em texto livre, para uma matriz de números reais que um computador facilmente entenderia.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.

Uma abordagem de aprendizado de máquina padrão para processamento de linguagem natural é atribuir a cada palavra distinta um “índice” e então passar um vetor para o algoritmo de aprendizado de máquina, de modo que o valor de cada índice contenha a frequência relativa da palavra na cadeia 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.

O MLlib oferece uma maneira fácil de executar essa operação.MLlib provides an easy way to perform this operation. Primeiro, crie tokens de cada cadeia de caracteres de violações para obter as palavras individuais em cada cadeia de caracteres.First, "tokenize" each violations string to get the individual words in each string. Em seguida, use um HashingTF para converter cada conjunto de tokens em um vetor de recurso que pode ser passado para o algoritmo de regressão logística para construir um 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. Você realiza todas essas etapas em sequência, usando um "pipeline".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)

Avaliar o modelo usando outro conjunto de dadosEvaluate the model using another dataset

Você pode usar o modelo criado anteriormente para prever quais serão os resultados das novas inspeções com base nas violações observadas.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. Você treinou esse modelo no conjunto de dados Food_Inspections1.csv.You trained this model on the dataset Food_Inspections1.csv. Você pode usar um segundo conjunto de dados, Food_Inspections2.csv, para avaliar a força deste modelo nos dados novos.You can use a second dataset, Food_Inspections2.csv, to evaluate the strength of this model on the new data. Esse segundo conjunto de dados (Food_Inspections2.csv) está no contêiner de armazenamento padrão associado ao cluster.This second data set (Food_Inspections2.csv) is in the default storage container associated with the cluster.

  1. Execute o código a seguir para criar um novo dataframe, predictionsDf que contém a previsão gerada pelo modelo.Run the following code to create a new dataframe, predictionsDf that contains the prediction generated by the model. O snippet de código também cria uma tabela temporária Previsões com base no dataframe.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
    

    Você verá algo semelhante ao mostrado a seguir:You should see an output like the following:

    ['id',
        'name',
        'results',
        'violations',
        'words',
        'features',
        'rawPrediction',
        'probability',
        'prediction']
    
  2. Examine uma das previsões.Look at one of the predictions. Execute este snippet de código:Run this snippet:

    predictionsDf.take(1)
    

    Há uma previsão para a primeira entrada no conjunto de dados de teste.There is a prediction for the first entry in the test data set.

  3. O método model.transform() aplica a mesma transformação para novos dados com o mesmo esquema e chega a uma previsão de como classificar os dados.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. Você pode fazer algumas estatísticas simples para ter uma ideia de quão precisas foram nossas previsões: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"
    

    A saída se parece com o seguinte:The output looks like the following:

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

    Usar regressão logística com o Spark fornece um modelo preciso da relação entre as descrições de violações em inglês e se um determinado negócio seria aprovado ou reprovado uma inspeção 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.

Criar uma representação visual da previsãoCreate a visual representation of the prediction

Agora você pode construir uma visualização final para ajudar a justificar os resultados deste teste.You can now construct a final visualization to help you reason about the results of this test.

  1. Você começa extraindo as diferentes previsões e os resultados da tabela temporária Predictions criada anteriormente.You start by extracting the different predictions and results from the Predictions temporary table created earlier. As consultas a seguir separam a saída como true_positive, false_positive, true_negative e false_negative.The following queries separate the output as true_positive, false_positive, true_negative, and false_negative. Nas consultas a seguir, você vai desligar as visualização usando -q e também salvar a saída (usando -o) como quadros de dados que podem ser usados com a 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 fim, use o snippet de código a seguir para gerar o gráfico usando o 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')
    

    Você deve ver o seguinte resultado:You should see the following output:

    Saída do aplicativo de aprendizado de máquina do Spark – percentuais de gráfico de pizza de inspeções em alimentos com falha.Spark machine learning application output - pie chart percentages of failed food inspections.

    Neste gráfico, um resultado "positivo" refere-se a uma reprovação na inspeção de alimentos, enquanto um resultado negativo refere-se a uma aprovação na inspeção.In this chart, a "positive" result refers to the failed food inspection, while a negative result refers to a passed inspection.

Fechar o notebookShut down the notebook

Depois de concluir a execução do aplicativo, você deve encerrar o bloco de anotações para liberar os recursos.After you have finished running the application, you should shut down the notebook to release the resources. Para fazer isso, no menu Arquivo do notebook, selecione Fechar e Interromper.To do so, from the File menu on the notebook, select Close and Halt. Isso desliga e fecha o bloco de anotações.This shuts down and closes the notebook.

Consulte tambémSee also

CenáriosScenarios

Criar e executar aplicativosCreate and run applications

Ferramentas e extensõesTools and extensions

Gerenciar recursosManage resources