Olá! Eu sou o Igor do Nascimento Alves e vou ser seu instrutor nesse curso de Classificação com PySpark.
Igor é um homem branco, com barba e cabelos pretos e curtos, e olhos também pretos. Ele está vestindo uma camisa preta e usando fones de ouvido internos sem fio. Ao fundo, sob uma iluminação verde, há uma parede com algumas prateleiras e nichos com itens de decoração e livros.
Para acompanhar essas aulas, é importante que você conheça a criação de modelos de Machine Learning para problemas de classificação, além da otimização de hiperparâmetros desses modelos. Assim, você conseguirá entender como aplicar esses conceitos no contexto do Spark.
Recebemos a demanda de ajudar o time de marketing a prever se um cliente vai cancelar o serviço ou não, pois eles estão notando um problema com o churn.
Nossa proposta para esse problema é criar um modelo de machine learning capaz de fazer a classificação entre clientes que vão cancelar o serviço e os que não vão.
Para isso, vamos utilizar uma base de dados fornecida pelo time de marketing contendo informações sobre esse cliente, como o tipo de serviço que ele contratou, há quanto tempo seu contrato está vigente, etc. Com essas informações, criaremos o modelo.
Utilizaremos o PySpark para fazer isso, principalmente o modo Spark DataFrame SQL e o MLlib. Com essa ferramenta faremos todo o pipeline do machine learning, passando pela etapa de tratamento dos dados, ajuste dos modelos por meio de algoritmos, otimização desses modelos encontrando os melhores hiperparâmetros e, por fim, a validação dos modelos.
Ao final do pipeline, entregaremos um modelo capaz de realizar a classificação de novos clientes entre provável cancelamento do serviço ou não, oferecendo essa previsão. Ou seja, teremos um modelo com tuning, otimizado para o nosso problema.
Com certeza ajudaremos o time de marketing com essa solução. Então, vamos lá?!
Vamos recapitular o nosso problema.
Nós, do time de ciência de dados do Alura Voz, recebemos uma demanda do Marketing. Existe um problema, atualmente, com o alto número de churn: basicamente, muitos clientes cancelando o serviço.
Para resolver esse problema, a ideia do time de marketing é oferecer promoções para os clientes que provavelmente cancelarão o serviço, procurando evitar esse cancelamento.
Na reunião entre nosso time e o time de marketing, surgiu a ideia de criarmos um modelo de Machine Learning capaz de classificar nossos clientes entre possíveis cancelamentos ou não.
Basearemos esse modelo nos dados históricos da empresa, relacionando as características dos clientes em relação ao contrato estabelecido e as ocorrências de cancelamento.
Nossa liderança técnica estabelece que o recomendado para esse problema é a utilização do PySpark, uma vez que o time de marketing conta com um grande volume de dados acerca de clientes. O PySpark é a única ferramenta capaz de processar todos esses dados e tornar a nossa pesquisa possível.
Vamos utilizar o ambiente do Google Colab nesse projeto, muito bem configurado, preparado, e conta com diversas bibliotecas pré-instaladas - exceto o PySpark.
Portanto, vamos instalar o PySpark no nosso notebook do Colab, disponível neste link. Esse notebook que vamos fornecer para você possui algumas informações muito interessantes.
Na primeira célula, há uma breve explicação sobre o PySpark e suas ferramentas, como o Spark SQL DataFrame e o MLlib, nos quais focaremos nesse projeto, além do Streaming. Tudo isso é construído em cima do Spark Core. Além disso, oferecemos também alguns links para leitura.
No canto superior direito da página do nosso notebook do Colab, vamos clicar no botão "Conectar". Com isso, o Google Colab disponibiliza uma máquina para trabalharmos. Sabemos que a conexão foi bem sucedida quando, nesse mesmo lugar na tela, temos um ícone de "check" verde.
Em seguida, na primeira célula de código, digitaremos:
[1]
!pip install pyspark
Então apertamos o atalho "Shift + Enter" para executar essa célula. Esse processo pode demorar um pouco, visto que são realizados o download da biblioteca, a instalação de pré-requisitos e uma série de configurações prévias.
Terminada a instalação, faremos um teste para verificar se tudo funciona como esperado.
Para esse teste, usaremos a parte de criação de sessão Spark, ou SparkSession, da biblioteca. Basicamente, a sessão Spark é o modo como fazemos a interação com o Spark.
O Spark é responsável por processar grandes bases de dados, e para nos comunicarmos com ele pelo Python, realizamos a conexão através de uma API. Ou seja, precisamos criar essa sessão Spark, que ficará responsável pelos dados, para interagir com ele.
Então precisamos, primeiramente, importar essa etapa da ferramenta, inserindo o seguinte código na célula de SparkSession:
[2]
from pyspark.sql import SparkSession
Apertando "Shift + Enter" novamente, fazemos a importação da ferramenta SparkSession.
Agora vamos criar a sessão. A salvaremos em uma variável chamada spark
, em uma terceira célula de código, chamando um construtor SparkSession.builder
que criará a estrutura necessária. Em seguida, temos que passar alguns parâmetros importantes para esse construtor.
Precisamos do comando .master()
para indicar para esse construtor onde o Spark está rodando. No caso, vamos utilizar o ambiente local, então passaremos 'local[*]'
como parâmetro desse comando. Outro comando importante é o appName()
, com o qual nomearemos a nossa sessão para identificá-la mais facilmente. Passaremos o nome como parâmetro desse comando, que indicará o problema a resolver: "Classificação com Spark"
. Por último, podemos criar a sessão, de fato. Para isso, usamos o método .getOrCreate()
.
Por fim, teremos a seguinte linha de código para a criação da SparkSession:
[3]
spark = SparkSession.builder.master('local[*]').appName("Classificação com Spark").getOrCreate()
Em seguida, executamos novamente esse código com "Shift + Enter". Assim, a conexão e a criação do ambiente com que vamos interagir serão realizadas.
Por fim, em uma quarta célula de código, vamos digitar apenas spark
, nossa variável, para analisar os resultados. O retorno é o seguinte:
[4]
SparkSession - in-memory
SparkContext
Spark UI
Version
v3.2.1
Master
local[*]
AppName
Classificação com Spark
Temos a versão utilizada do Spark, o ambiente e o nome que definimos. Ou seja, tudo funciona conforme o esperado e estamos preparados para trabalhar!
Agora, então, vamos analisar a nossa base de dados.
Observação: vamos trabalhar com uma base de dados pequena, porque estamos no ambiente do Colab e não vamos realizar tantas configurações no Spark. Além disso, como nosso objetivo é entender a ferramenta e criar esse modelo de classificação, uma base pequena é o suficiente para esse propósito.
Os dados com que iremos trabalhar foram fornecidos para nós em um arquivo CSV. Tendo feito seu download, o carregaremos no Colab.
Para isso clicamos no ícone de pasta, chamado "Arquivos", no menu lateral esquerdo do Colab. Assim, uma aba será aberta contendo diferentes opções para o carregamento de arquivos. Clicaremos na primeira opção, "Fazer upload para o armazenamento da sessão", representada pelo ícone de um arquivo com uma seta dentro, apontando para cima.
Feito isso, a janela dos nossos arquivos locais será aberta. Selecionamos o arquivo dados_clientes.csv
e clicamos em "Abrir" no canto inferior direito da janela. Nesse momento, o seguinte aviso será exibido:
"Observação: os arquivos enviados serão excluídos quando o ambiente de execução for reciclado."
Isso significa que nosso arquivo funciona apenas na sessão, portanto, temos de recarregá-lo a cada vez que reiniciarmos o Colab. Clicamos em "Ok" no canto inferior direito do pop-up.
Assim, nossos dados serão carregados. Verificamos isso pela aba lateral esquerda, que agora exibe dados_clientes.csv
. Clicamos no ícone de pasta novamente para essa aba se fechar e ganharmos espaço de tela.
Agora, na sessão "Carregamento dos Dados" do nosso notebook, carregaremos esses dados na variável dados
, na primeira célula de código. Essa variável receberá o contexto Spark, ou seja, a nossa variável spark
. Em seguida, usaremos o comando .read.csv()
para que o nosso arquivo de dados seja lido pelo Spark.
[5]
dados = spark.read.csv()
Agora, precisamos passar alguns parâmetros essenciais para esse comando de leitura. O primeiro deles é a indicação de onde está o nosso arquivo. Como ele está na raiz do nosso projeto, basta digitarmos o seu nome entre aspas simples: 'dados_clientes.csv'
.
Outro parâmetro importante é o separador, sep=
, que indica qual caractere o nosso arquivo usa para separar os dados. No nosso caso é a vírgula, então a colocamos entre aspas simples ','
.
Precisamos, também, indicar se o nosso CSV conta com um cabeçalho (header=
) que informa o que cada coluna representa. No nosso caso, sim. Então esse parâmetro terá o valor True
.
Por fim, o último parâmetro interessante é o inferSchema
, que interpretará o esquema dos nossos dados a partir do arquivo CSV, assumindo o tipo de cada variável. O valor desse parâmetro também será True
.
Com tudo isso, teremos a seguinte linha de código:
dados = spark.read.csv('dados_clientes.csv', sep=',', reahder=True, inferSchema=True)
Então, apertamos "Shift + Enter" e nossa base de dados será carregada, criando a representação de DataFrame do SQL do Spark.
Na próxima célula de código, podemos executar apenas a variável dados
para verificar essa leitura. No entanto, quando digitamos dados
, apenas a estrutura do nosso DataFrame é exibida:
DataFrame[id: int, Churn: string, Mais65anos: int, Conjuge: string, Dependentes: string, MesesDeContrato:int, ... //retorno omitido
Ou seja, o DataFrame é composto de um primeiro campo chamado "id" do tipo inteiro, um segundo campo chamado "Churn" do tipo string, e assim por diante.
Para exibir o DataFrame propriamente, vamos executar o comando .show
, ou seja, "mostrar":
[7]
dados.show()
Agora, sim, visualizamos os dados na forma de DataFrame (que você pode conferir com detalhes na seção 1.3 do nosso notebook, disponível neste link). Na primeira linha temos os nomes das colunas, separadas por vários caracteres, como "id", "Churn", "Mais65anos", "Conjuge", "Dependentes", "MesesDeContrato", etc.
Abaixo dos nomes das colunas, temos os dados em si. Por exemplo, o primeiro cliente está registrado como id "0", valor de Churn como "Não" (ou seja, ele não cancelou o serviço), valor "0" para Mais65Anos (significando "falso", ao contrário de "1" que significaria "verdadeiro"), etc.
Vemos que nas colunas "Churn", "Cônjuge", "Dependentes" e "TelefoneFixo" foram usadas variáveis de sim e não, diferente de "Mais65Anos", que usa a variável binária de 0 e 1. Inclusive, as variáveis "MaisDeUmaLinhaTelefonica" e "Internet", têm 3 valores possíveis, e não apenas 2. Ou seja, os dados estão registrados sem um padrão, provavelmente porque são informações que vieram de um questionário e não foram tratadas. Devemos nos atentar a isso porque pode ser um problema no futuro.
Agora, vamos explorar outras informações dos nossos dados.
Por exemplo, vamos extrair o número de registros que temos nessa base de dados. Para isso, executamos o comando .count()
na variável dados
, na próxima célula de código. Teremos o seguinte código e retorno, respectivamente:
[8]
dados.count()
10348
Ou seja, temos dez mil, trezentos e quarenta e oito registros. É com esse volume de dados com que trabalharemos nesse projeto.
Outra informação interessante que podemos colher é acerca do balanceamento dessa base. Ou seja, temos a mesma quantidade de assinaturas ativas e de cancelamentos?
Para descobrir isso, precisamos agrupar as informações de churn por meio do comando .groupBy()
na variável dados
. Passaremos o nome da coluna que queremos agrupar como parâmetro desse comando: 'Churn'
.
Mas, se queremos contar quantos registros temos em cada valor dessa variável ("Sim" ou "Não"), usaremos o comando count()
novamente.
Por último, queremos visualizar esse DataFrame que será criado exibindo essas informações. Para isso, usamos show()
novamente. Enfim, teremos:
[9]
dados.groupBy('Churn').count().show()
Executando essa linha de código, teremos o seguinte DataFrame como retorno:
[9] (retorno
Churn | count |
---|---|
Sim | 5174 |
Nao | 5174 |
Ou seja, temos um DataFrame bem pequeno com o mesmo layout do DataFrame anterior: nome das colunas na linha superior e, abaixo, o valor dessas categorias.
Com esses dados assim dispostos, vemos que nossa base de dados está balanceada: temos o mesmo número de cancelamentos e assinaturas ativas. Essa é uma informação importante para decidirmos que tipo de modelo de Machine Learning nós utilizaremos, a quais métricas podemos recorrer e como podemos fazer a leitura dessas métricas.
Mas a nossa preocupação atual é em relação ao tipo dos nossos dados, pois observamos anteriormente que temos algumas strings no meio deles.
Para analisar isso mais detalhadamente, podemos usar o comando printSchema()
, que terá o seguinte retorno:
[10]
dados.printSchema()
root
|-- id: integer (nullable = true)
|-- Churn: string (nullable = true)
|-- Mais65anos: integer (nullable = true)
|-- Conjuge: string (nullable = true)
|-- Dependentes: string (nullable = true)
|-- MesesDeContrato: integer (nullable = true)
|-- TelefoneFixo: string (nullable = true)
|-- MaisDeUmaLinhaTelefonica: string (nullable = true)
|-- Internet: string (nullable = true)
|-- SegurancaOnline: string (nullable = true)
|-- BackupOnline: string (nullable = true)
|-- SeguroDispositivo: string (nullable = true)
|-- SuporteTecnico: string (nullable = true)
|-- TVaCabo: string (nullable = true)
|-- StreamingFilmes: string (nullable = true)
|-- TipoContrato: string (nullable = true)
|-- ContaCorreio: string (nullable = true)
|-- MetodoPagamento: string (nullable = true)
|-- MesesCobrados: double (nullable = true)
Estamos diante do esquema dos nossos dados, que é bastante simples: temos apenas um primeiro nível de colunas, todas alinhadas. Nesse esquema, vemos o nome da coluna e o tipo de informação que o Spark reconhece nela.
O "id" é um inteiro, pois conforme vimos antes, os valores apresentados nessa coluna são numéricos. Já o "Churn" é uma string, pois seus valores são representados por "Sim" e "Nao", e assim por diante.
A maioria das nossas colunas tem os valores representados por string, o que é um problema para os modelos de Machine Learning, que não sabem lidar com dados em texto.
Dessa forma, precisamos encontrar uma maneira de transformar todos esses dados em números. É o que faremos a seguir.
O curso Spark: criando modelos de classificação possui 154 minutos de vídeos, em um total de 49 atividades. Gostou? Conheça nossos outros cursos de Engenharia de Dados em Data Science, ou leia nossos artigos de Data Science.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.
Acesso completo
durante 1 ano
Estude 24h/dia
onde e quando quiser
Novos cursos
todas as semanas