Analisar dados com Apache Spark

Neste tutorial, você aprenderá a executar a análise de dados exploratória usando o Azure Open Datasets e o Apache Spark. Em seguida, você pode visualizar os resultados em um notebook do Synapse Studio no Azure Synapse Analytics.

Em particular, analisaremos o conjunto de dados de táxi de Nova York (NYC ). Os dados estão disponíveis por meio dos Conjuntos de Dados em Aberto no Azure. Esse subconjunto do conjunto de dados contém informações sobre as corridas de táxi amarelo: informações sobre cada corrida, a hora de início e de término e os locais, o custo e outros atributos interessantes.

Antes de começar

Crie um Pool do Apache Spark seguindo o tutorial Criar um pool do Apache Spark.

Baixar e preparar os dados

  1. Crie um notebook usando o kernel PySpark. Para obter instruções, consulte Criar um bloco de anotações.

    Observação

    Devido ao kernel do PySpark, você não precisa criar nenhum contexto explicitamente. O contexto do Spark é criado automaticamente para você quando você executa a primeira célula de código.

  2. Neste tutorial, usaremos várias bibliotecas diferentes para nos ajudar a visualizar o conjunto de dados. Para fazer essa análise, importe as seguintes bibliotecas:

    import matplotlib.pyplot as plt
    import seaborn as sns
    import pandas as pd
    
  3. Como os dados brutos estão no formato Parquet, você pode usar o contexto do Spark para extrair o arquivo diretamente na memória como um DataFrame. Crie um DataFrame do Spark recuperando os dados por meio da API open datasets. Aqui, usamos as propriedades de schema on read do Spark DataFrame para inferir os tipos de dados e o esquema.

    from azureml.opendatasets import NycTlcYellow
    
    from datetime import datetime
    from dateutil import parser
    
    end_date = parser.parse('2018-05-08 00:00:00')
    start_date = parser.parse('2018-05-01 00:00:00')
    
    nyc_tlc = NycTlcYellow(start_date=start_date, end_date=end_date)
    df = spark.createDataFrame(nyc_tlc.to_pandas_dataframe())
    
    
  4. Depois que os dados forem lidos, vamos querer fazer alguma filtragem inicial para limpar o conjunto de dados. Podemos remover colunas desnecessárias e adicionar colunas que extraem informações importantes. Além disso, filtraremos anomalias dentro do conjunto de dados.

    # Filter the dataset 
    from pyspark.sql.functions import *
    
    filtered_df = df.select('vendorID', 'passengerCount', 'tripDistance','paymentType', 'fareAmount', 'tipAmount'\
                                    , date_format('tpepPickupDateTime', 'hh').alias('hour_of_day')\
                                    , dayofweek('tpepPickupDateTime').alias('day_of_week')\
                                    , dayofmonth(col('tpepPickupDateTime')).alias('day_of_month'))\
                                .filter((df.passengerCount > 0)\
                                    & (df.tipAmount >= 0)\
                                    & (df.fareAmount >= 1) & (df.fareAmount <= 250)\
                                    & (df.tripDistance > 0) & (df.tripDistance <= 200))
    
    filtered_df.createOrReplaceTempView("taxi_dataset")
    

Analisar dados

Como analista de dados, você tem uma ampla variedade de ferramentas disponíveis para ajudá-lo a extrair informações dos dados. Nesta parte do tutorial, percorreremos algumas ferramentas úteis disponíveis nos notebooks do Azure Synapse Analytics. Nesta análise, queremos entender os fatores que geram dicas de táxi mais altas para nosso período selecionado.

Comando magic do SQL do Apache Spark

Primeiro, executaremos a análise exploratória de dados usando Apache Spark SQL e comandos mágicos com o notebook do Azure Synapse. Depois que tivermos nossa consulta, veremos os resultados usando o recurso interno chart options.

  1. No bloco de anotações, crie uma nova célula e copie o código a seguir. Ao usar essa consulta, queremos entender como os valores médios de gorjeta foram alterados ao longo do período selecionado. Essa consulta também nos ajudará a identificar outros insights úteis, incluindo o valor mínimo/máximo da gorjeta por dia e o valor médio da tarifa.

    %%sql
    SELECT 
        day_of_month
        , MIN(tipAmount) AS minTipAmount
        , MAX(tipAmount) AS maxTipAmount
        , AVG(tipAmount) AS avgTipAmount
        , AVG(fareAmount) as fareAmount
    FROM taxi_dataset 
    GROUP BY day_of_month
    ORDER BY day_of_month ASC
    
  2. Depois que nossa consulta terminar de ser executada, podemos visualizar os resultados alternando para o modo de exibição do gráfico. Este exemplo cria um gráfico de linhas especificando o campo day_of_month como a chave e avgTipAmount como o valor. Depois de fazer as seleções, selecione Aplicar para atualizar seu gráfico.

Visualizar dados

Além das opções internas de criação de gráficos em notebooks, você pode usar bibliotecas de código aberto para criar suas próprias visualizações. Nos exemplos a seguir, usaremos Seaborn e Matplotlib. Essas bibliotecas do Python geralmente são usadas para visualização de dados.

Observação

Por padrão, cada pool do Apache Spark no Azure Synapse Analytics contém um conjunto de bibliotecas normalmente usadas e padrão. Você pode visualizar a lista completa de bibliotecas na documentação do runtime do Azure Synapse. Além disso, para tornar código de terceiros ou construído localmente disponível para seus aplicativos, você pode instalar uma biblioteca em um de seus pools do Spark.

  1. Para tornar o desenvolvimento mais fácil e menos caro, reduziremos o tamanho do conjunto de dados. Usaremos a funcionalidade de amostragem interna do Apache Spark. Além disso, tanto Seaborn quanto Matplotlib exigem um DataFrame do Pandas ou um array do NumPy. Para obter um DataFrame do Pandas, use o comando toPandas() para converter o DataFrame.

    # To make development easier, faster, and less expensive, downsample for now
    sampled_taxi_df = filtered_df.sample(True, 0.001, seed=1234)
    
    # The charting package needs a Pandas DataFrame or NumPy array to do the conversion
    sampled_taxi_pd_df = sampled_taxi_df.toPandas()
    
  2. Queremos entender a distribuição de dicas em nosso conjunto de dados. Usaremos Matplotlib para criar um histograma que mostra a distribuição da quantidade e da contagem de gorjetas. Com base na distribuição, podemos ver que as gorjetas tendem a valores menores ou iguais a US$ 10.

    # Look at a histogram of tips by count by using Matplotlib
    
    ax1 = sampled_taxi_pd_df['tipAmount'].plot(kind='hist', bins=25, facecolor='lightblue')
    ax1.set_title('Tip amount distribution')
    ax1.set_xlabel('Tip Amount ($)')
    ax1.set_ylabel('Counts')
    plt.suptitle('')
    plt.show()
    

    Histograma de dicas.

  3. Em seguida, queremos entender a relação entre as dicas para uma determinada viagem e o dia da semana. Use o Seaborn para criar um gráfico de caixa que resuma as tendências de cada dia da semana.

    # View the distribution of tips by day of week using Seaborn
    ax = sns.boxplot(x="day_of_week", y="tipAmount",data=sampled_taxi_pd_df, showfliers = False)
    ax.set_title('Tip amount distribution per day')
    ax.set_xlabel('Day of Week')
    ax.set_ylabel('Tip Amount ($)')
    plt.show()
    
    

    Gráfico que mostra a distribuição de dicas por dia.

  4. Outra hipótese nossa pode ser que haja uma relação positiva entre o número de passageiros e a quantidade total de gorjetas de táxi. Para verificar essa relação, execute o código a seguir para gerar um gráfico de caixa que ilustra a distribuição de gorjetas para cada contagem de passageiros.

    # How many passengers tipped by various amounts 
    ax2 = sampled_taxi_pd_df.boxplot(column=['tipAmount'], by=['passengerCount'])
    ax2.set_title('Tip amount by Passenger count')
    ax2.set_xlabel('Passenger count')
    ax2.set_ylabel('Tip Amount ($)')
    ax2.set_ylim(0,30)
    plt.suptitle('')
    plt.show()
    

    Gráfico que mostra um gráfico de caixa estreita.

  5. Por fim, queremos entender a relação entre o valor da tarifa e o valor da gorjeta. Com base nos resultados, podemos ver que há várias observações em que as pessoas não dão gorjetas. No entanto, também vemos uma relação positiva entre os valores gerais de tarifa e gorjeta.

    # Look at the relationship between fare and tip amounts
    
    ax = sampled_taxi_pd_df.plot(kind='scatter', x= 'fareAmount', y = 'tipAmount', c='blue', alpha = 0.10, s=2.5*(sampled_taxi_pd_df['passengerCount']))
    ax.set_title('Tip amount by Fare amount')
    ax.set_xlabel('Fare Amount ($)')
    ax.set_ylabel('Tip Amount ($)')
    plt.axis([-2, 80, -2, 20])
    plt.suptitle('')
    plt.show()
    

    Gráfico de dispersão do valor da gorjeta.

Desligar a instância do Spark

Depois de concluir a execução do aplicativo, desligue o bloco de anotações para liberar os recursos. Feche a guia ou selecione Encerrar Sessão no painel de status na parte inferior do bloco de anotações.

Consulte também

Próximas Etapas