Boas-vindas ao curso de Otimização: Programação por restrições! Me chamo João Miranda e serei o seu instrutor neste curso.
Audiodescrição: João é um homem branco com cabelo médio preso em um coque, com as laterais raspadas. Usa bigode e cavanhaque. Veste uma camiseta preta lisa. Ao fundo, uma parede branca com uma iluminação verde e azul.
Já se perguntou como são escolhidos os tipos de propagandas que passam durante os intervalos dos programas de TV? Neste curso, vamos desenvolver um projeto de programação por restrições para entender melhor como alocar propagandas nos horários disponíveis para publicidade em um canal de televisão.
Vamos considerar fatores como horário e público-alvo para garantir que as propagandas sejam direcionadas da melhor forma possível através de otimização. No curso, não vamos utilizar a biblioteca Pyomo; em vez disso, vamos nos concentrar no uso da ferramenta OR Tools do Google.
Para acompanhar esse conteúdo, é necessário ter conhecimento em Python e também em programação linear.
Vamos começar?
Pense em uma emissora de TV comum que tem vários anunciantes interessados em colocar seus comerciais nos intervalos comerciais.
Com a popularidade das Smart TVs, agora podemos obter informações sobre o perfil de cada TV, incluindo quantas pessoas de cada segmento demográfico estão assistindo aos anúncios.
Se tivermos acesso a esses dados de visibilidade, como podemos garantir que as propagandas sejam colocados nos intervalos certos para alcançar o público-alvo e maximizar sua visibilidade?
Vamos usar Python e técnicas de otimização para alocar esses comerciais da melhor forma possível nos intervalos disponíveis. Para começar, vamos usar um conjunto de dados que inclui a visibilidade de cada anunciante nessa rede de TV.
Para começar dentro do Google Colab, vamos fazer o upload do arquivo contendo esses dados de visibilidade. No menu lateral esquerdo, selecionamos o ícone de pasta que representa os arquivos e clicamos no primeiro ícone de fazer o upload do arquivo.Na nossa máquina, selecionamos o arquivo visibilidade.csv
.
Esse arquivo estará disponível na atividade "Preparando Ambiente" antes desta aula. Antes de começar a assistir esse conteúdo, é importante que você faça o download desse arquivo para ser utilizado no projeto.
Vamos clicar duas vezes no arquivo visibilidade.csv
e, a partir de agora, podemos copiar o caminho desse arquivo para fazer a leitura dessa base de dados. Para isso, clicamos nos três pontos ao lado do arquivo, selecionamos a opção "Copiar caminho" e, agora, podemos fechar o menu lateral esquerdo dos arquivos clicando no ícone de xis ("X").
Na primeira célula de código, importamos a biblioteca Pandas. Ela será fundamental para a leitura e manipulação dos dados. Portanto, na primeira célula, importamos o pandas as pd
.
import pandas as pd
Executamos a célula pressionando "Ctrl + Enter".
Na próxima célula, faremos a leitura da base de dados. Para isso, digitamos dados = pd.read_csv()
e inserimos o caminho do arquivo entre as aspas, utilizando "Ctrl + V" para colar o caminho.
dados = pd.read_csv('/content/visibilidade.csv')
Em seguida, na mesma célula, para visualizar os dados, digitamos dados e executamos com "Ctrl + Enter".
dados = pd.read_csv('/content/visibilidade.csv')
dados
Como retorno, obtemos:
# | EsportivaMax | TechInova | EnergiaViva | SuperTech | BebaBem |
---|---|---|---|---|---|
0 | 7 | 2 | 6 | 5 | 5 |
1 | 4 | 1 | 1 | 8 | 1 |
2 | 8 | 7 | 9 | 1 | 7 |
3 | 5 | 7 | 6 | 5 | 5 |
4 | 7 | 8 | 3 | 3 | 6 |
... | ... | ... | ... | ... | ... |
95 | 10 | 8 | 1 | 1 | 1 |
96 | 9 | 5 | 5 | 2 | 7 |
97 | 7 | 4 | 6 | 6 | 7 |
98 | 9 | 2 | 3 | 9 | 9 |
99 | 8 | 6 | 9 | 8 | 3 |
Temos um dataframe com 100 linhas e 5 colunas, representando 100 registros e os seguintes anunciantes da rede de televisão: Esportiva Max, TechInova, Energia Viva, SuperTech e BebaBem. Cada linha do dataframe corresponde a um slot de tempo onde as propagandas serão alocadas, com as colunas representando os diferentes anunciantes e as linhas representando os slots de tempo.
No índice 0, encontramos o primeiro período disponível; no índice 1, temos o segundo período, e assim por diante, totalizando 100 intervalos de tempo distintos. Quanto aos valores dentro do dataframe, representam a visibilidade do anunciante naquele intervalo de tempo específico.
Por exemplo, no primeiro intervalo de tempo (índice 0), o Esportiva Max possui uma visibilidade de 7, o TechInova de 2, o Energia Viva de 6, o SuperTech de 5 e o Beba Bem de 5. Estes números estão relacionados a dezenas de milhares de televisões. Esses valores indicam a intensidade e a quantidade de pessoas que poderão assistir e ser alcançadas pelo público-alvo durante aquele período.
A partir desses dados, vamos querer alocar o melhor anunciante para cada um dos slots de tempo para aumentar a visibilidade.Para fazer isso, vamos utilizar a otimização e vamos utilizar a biblioteca ORTools do Google.
ORTools
Para utilizar a biblioteca ORTools, vamos ter que instalá-la no ambiente do Colab. Na próxima célula, escrevemos !pip install ortools
.
!pip install ortools
Esse código será utilizado para instalar essa ferramenta OR Tools do Google. Vamos executar o código e ele vai começar a fazer a instalação dessa biblioteca.
Depois de fazer a instalação, vamos fazer uma transformação nesse DataFrame para ser mais fácil de utilizar com essa biblioteca. Vamos armazenar a informação dos slots de tempo em uma lista. Isto é, iremos colocar o valor do 0 até o 99 em uma lista.
Logo após, armazenamos todo o restante dos dados do DataFrame em um dicionário. Dessa maneira, vai ficar mais fácil utilizar nessa ferramenta do OR Tools.
Na próxima célula, vamos transformar aquelas informações em uma lista e um dicionário. Primeiro, armazenamos os slots de tempo. Para isso, escrevemos slots_tempo_disponiveis = dados.index.tolist()
.
Dessa maneira, vamos pegar o índice do DataFrame e transformar para uma lista com a função tolist()
. Na mesma célula, digitamos essa variável, slots_tempo_disponiveis
, e vamos executar para verificar se foi construída a lista com sucesso.
slots_tempo_disponiveis = dados.index.tolist()
slots_tempo_disponiveis
Obtemos a seguinte lista de valores do 0 até 99:
A lista abaixo foi parcialmente transcrita:
[0,
1
2
3
4
5
6
7
…
99]
Com isso, temos todos os slots de tempo nessa variável.
Agora, vamos armazenar o restante dos dados em um dicionário. Para isso, utilizamos o método to_dict()
: dados_visibilidade = dados.to_dict()
.
dados_visibilidade = dados.to_dict()
Assim, transformamos o nosso DataFrame em um dicionário. Cada uma das chaves do dicionário será um dos anunciantes e os valores serão os dados de visibilidade. Na mesma célula, vamos escrever dados_visibilidade
e executar esse código para verificar se foi feita a transformação com sucesso.
dados_visibilidade = dados.to_dict()
dados_visibilidade
Obtemos um dicionário:
O dicionário abaixo foi parcialmente transcrito:
42: 1,
43: 4,
44: 8,
45: 2,
46: 3,
47: 1,
48: 1,
…
'SuperTech': {0: 5,
1: 8,
2: 1,
3: 5,
4: 3,
…
Se descemos, obtemos um dicionário contendo o nome do anunciante na chave do dicionário e o valor daquela chave será o dado de visibilidade daquele anunciante em cada um dos slots de tempo.
Agora que já temos os nossos dados e fizemos as transformações necessárias e também fizemos a instalação da Biblioteca ORTools, podemos começar a modelar o nosso problema de otimização utilizando essa ferramenta para obter a solução da melhor alocação dos anunciantes nos slots de tempo.
Mas vamos fazer isso no próximo vídeo!
Conseguimos realizar a leitura da base de dados, que contém os dados de visibilidade de cada anunciante que deseja colocar suas propagandas na rede de televisão. Mas, a partir desses dados, como vamos escolher os melhores anunciantes para cada um dos slots de tempo disponíveis para a publicidade?
Vamos utilizar a otimização para traduzir o nosso problema, que já conhecemos, para um problema de programação linear inteira. A partir desse problema, vamos conseguir encontrar uma solução dos melhores anunciantes para cada slot de tempo.
Como faremos isso? Vamos criar variáveis de decisão nesse nosso modelo, e essa variável de decisão será justamente decidir se o anunciante será alocado ou não no slot de tempo.
Portanto, essa variável de decisão terá o valor de 0 ou 1. O valor 0 indicará que aquele anunciante não foi alocado naquele intervalo de tempo. E o valor 1 indicará que aquele anunciante foi alocado naquele intervalo de tempo.
Nosso problema tem o objetivo de atingir o maior número de pessoas com esses anúncios, e atingir também o público-alvo correto. Para fazer isso, no problema de programação linear inteira, vamos construir uma função objetivo que terá o objetivo de maximizar a visibilidade total dos anunciantes.
Vamos começar!
No Google Colab, vamos primeiro importar um solucionador desse tipo de problema de programação linear inteira, a partir da biblioteca ORTools
. Então, na primeira linha, escrevemos from ortools.linear_solver import pywraplp
.
from ortools.linear_solver import pywraplp
Na mesma célula, vamos inicializar o nosso modelo: modelo = pywraplp.Solver.CreateSolver('SCIP')
.
from ortools.linear_solver import pywraplp
modelo = pywraplp.Solver.CreateSolver('SCIP')
O tipo de solver
que vamos escolher será justamente um que consegue resolver esse problema de programação linear inteira com restrições.
Na mesma célula, vamos primeiro criar as nossas variáveis de decisão. Será o valor 0, se não quisermos alocar o anunciante no intervalo de tempo, e o valor 1, se quisermos alocar o anunciante no intervalo de tempo.
Para isso, como teremos uma variável de decisão para cada anunciante e para cada intervalo de tempo, vamos fazer um for
percorrendo cada um dos anunciantes e cada um dos intervalos de tempo. E vamos armazenar essas variáveis de decisão em um dicionário. Então, chamamos o dicionário de x
.
Para tal, digitamos x = {}
. E, a partir disso, começamos a alocar em cada chave desse dicionário as variáveis de decisão. Então, vamos percorrer primeiro os anunciantes: for anunciante in dados_visibilidade:
. Esse dado de visibilidade é justamente aquele dicionário contendo a informação do nome do anunciante, o intervalo de tempo e a quantidade de visibilidade daquele anunciante.
Logo após, dentro desse for
, percorremos os slots de tempo: for slot in slots_tempo_disponiveis:
. Esses slots de tempo disponíveis é aquela lista de slots de tempo do 0 até o 99.
from ortools.linear_solver import pywraplp
modelo = pywraplp.Solver.CreateSolver('SCIP')
x = {}
for anunciante in dados_visibilidade:
for slot in slots_tempo_disponiveis:
Agora que já percorremos os anunciantes dos slots de tempo, vamos criar a variável de decisão para esse anunciante e para aquele slot de tempo específico dentro do dicionário x
. Para isso, escrevemos x[anunciante, slot] = modelo.BoolVar(f"x[{anunciante, slot}]")
.
O tipo será BoolVar()
por ser valor 0 ou 1. Dentro dos parênteses, passamos o nome da variável de decisão. Portanto, informamos o nome do anunciante e o slot de tempo usando f
string: f"x[{anunciante, slot}]")
.
from ortools.linear_solver import pywraplp
modelo = pywraplp.Solver.CreateSolver('SCIP')
x = {}
for anunciante in dados_visibilidade:
for slot in slots_tempo_disponiveis:
x[anunciante, slot] = modelo.BoolVar(f"x[{anunciante, slot}]")
Dessa maneira, conseguimos construir todas as variáveis de decisão do nosso modelo para cada anunciante e para cada slot de tempo.
Agora, como o nosso objetivo é maximizar a visibilidade total dos anunciantes, vamos construir uma função objetivo maximize
, que tem o objetivo de maximizar um valor.
Escrevemos: modelo.Maximize(sum(dados_visibilidade[anunciante][slot] * x[anunciante, slot] for anunciante in dados_visibilidade for slot in slots_tempo_disponiveis))
.
Dentro do modelo.Maximize()
passamos uma função objetivo para aumentar o valor da visibilidade. Portanto, usamos sum()
para somar todos os valores de visibilidade dos anunciantes que foram selecionados.
Os anunciantes que foram selecionados possuem como variável de decisão (x
) o valor igual a um. Portanto, multiplicamos o valor do dado de visibilidade do anunciante somente pelo valor um do anunciante selecionado.
Em sum(dados_visibilidade[anunciante][slot])
estamos acessando o anunciante
e o slot
no dicionário dados_visibilidade
. Na sequência, multiplicamos pela variável de decisão do anunciante. Assim, somamos os dados de visibilidade somente dos anunciantes que estão selecionados. Isso porque o valor da variável de decisão será igual a um.
Logo após, percorremos os anunciantes e os slots. Para isso, usamos o for anunciante in dados_visibilidade for slot in slots_tempo_disponiveis
dentro do sum()
.
from ortools.linear_solver import pywraplp
modelo = pywraplp.Solver.CreateSolver('SCIP')
x = {}
for anunciante in dados_visibilidade:
for slot in slots_tempo_disponiveis:
x[anunciante, slot] = modelo.BoolVar(f"x[{anunciante, slot}]")
modelo.Maximize(sum(dados_visibilidade[anunciante][slot] * x[anunciante, slot] for anunciante in dados_visibilidade for slot in slots_tempo_disponiveis))
Agora que estabelecemos a função objetivo para o nosso modelo, podemos avançar para a definição das restrições do problema. Até este ponto, ainda não determinamos como será selecionado o valor dessa variável de decisão.
Só podemos alocar um anunciante para cada slot de tempo, não podemos colocar mais de um anunciante em cada slot de tempo. Temos que fazer uma restrição para o modelo entender que é necessário fazer isso. Caso contrário, ele vai colocar o valor 1 para todos os valores de anunciante e slot de tempo, porque dessa maneira ele vai maximizar o valor da visibilidade.
Vamos criar nossa restrição, que também vai depender do slot de tempo. Iremos percorrer o slot de tempo escrevendo for slot in slots_tempo_disponiveis
. Em seguida, adicionaremos uma restrição na ferramenta ORTools com a linha modelo.Add(sum(x[anunciante, slot] for anunciante in dados_visibilidade) == 1)
.
Dentro de Add()
estamos passando uma expressão matemática, em cada slot de tempo somamos as variáveis de decisão. E o valor dessa soma deve ser igual a um, isso significa que somamos as variáveis de cada slot de tempo dos anunciantes e para que seja igual a um, indica que somente um dos anunciantes será alocado naquele intervalo de tempo. Portanto, terá o valor um e o restante o valor zero.
from ortools.linear_solver import pywraplp
modelo = pywraplp.Solver.CreateSolver('SCIP')
x = {}
for anunciante in dados_visibilidade:
for slot in slots_tempo_disponiveis:
x[anunciante, slot] = modelo.BoolVar(f"x[{anunciante, slot}]")
modelo.Maximize(sum(dados_visibilidade[anunciante][slot] * x[anunciante, slot] for anunciante in dados_visibilidade for slot in slots_tempo_disponiveis))
for slot in slots_tempo_disponiveis:
modelo.Add(sum(x[anunciante, slot] for anunciante in dados_visibilidade) == 1)
Com isso, adicionamos a restrição indicando que a soma das variáveis de decisão em cada slot de tempo deve ser igual a um.
Agora, podemos resolver o nosso modelo de programação em linha inteira. Para isso, escrevemos status = modelo.Solve()
.
from ortools.linear_solver import pywraplp
modelo = pywraplp.Solver.CreateSolver('SCIP')
x = {}
for anunciante in dados_visibilidade:
for slot in slots_tempo_disponiveis:
x[anunciante, slot] = modelo.BoolVar(f"x[{anunciante, slot}]")
modelo.Maximize(sum(dados_visibilidade[anunciante][slot] * x[anunciante, slot] for anunciante in dados_visibilidade for slot in slots_tempo_disponiveis))
for slot in slots_tempo_disponiveis:
modelo.Add(sum(x[anunciante, slot] for anunciante in dados_visibilidade) == 1)
status = modelo.Solve()
Assim, estamos armazenando qual o status dessa solução dentro da variável status()
.
Agora, verificamos se o status indica que obtivemos uma solução ótima, ou seja, se encontramos a melhor solução possível. Para isso, vamos verificar if status == pywraplp.Solver.OPTIMAL:
.
from ortools.linear_solver import pywraplp
modelo = pywraplp.Solver.CreateSolver('SCIP')
x = {}
for anunciante in dados_visibilidade:
for slot in slots_tempo_disponiveis:
x[anunciante, slot] = modelo.BoolVar(f"x[{anunciante, slot}]")
modelo.Maximize(sum(dados_visibilidade[anunciante][slot] * x[anunciante, slot] for anunciante in dados_visibilidade for slot in slots_tempo_disponiveis))
for slot in slots_tempo_disponiveis:
modelo.Add(sum(x[anunciante, slot] for anunciante in dados_visibilidade) == 1)
status = modelo.Solve()
if status == pywraplp.Solver.OPTIMAL:
Isso permite checar se o status da solução é o melhor resultado possível dentro de todas as possibilidades.
Em seguida, vamos começar a inserir os anunciantes para cada slot de tempo, criando assim uma grade de anúncios. Dentro do bloco if
, vamos iniciar grade = []
.
from ortools.linear_solver import pywraplp
modelo = pywraplp.Solver.CreateSolver('SCIP')
x = {}
for anunciante in dados_visibilidade:
for slot in slots_tempo_disponiveis:
x[anunciante, slot] = modelo.BoolVar(f"x[{anunciante, slot}]")
modelo.Maximize(sum(dados_visibilidade[anunciante][slot] * x[anunciante, slot] for anunciante in dados_visibilidade for slot in slots_tempo_disponiveis))
for slot in slots_tempo_disponiveis:
modelo.Add(sum(x[anunciante, slot] for anunciante in dados_visibilidade) == 1)
status = modelo.Solve()
if status == pywraplp.Solver.OPTIMAL:
grade = []
Com isso, criamos uma lista contendo todos os anunciantes que serão alocados.
Na sequência, imprimimos qual foi a visibilidade máxima da nossa solução. A partir da função objetivo, que é o modelo.Maximize()
, conseguimos encontrar qual foi a visibilidade total dessa alocação. Escrevemos: print('Visibilidade total máxima:', modelo.Objective().Value())
.
from ortools.linear_solver import pywraplp
modelo = pywraplp.Solver.CreateSolver('SCIP')
x = {}
for anunciante in dados_visibilidade:
for slot in slots_tempo_disponiveis:
x[anunciante, slot] = modelo.BoolVar(f"x[{anunciante, slot}]")
modelo.Maximize(sum(dados_visibilidade[anunciante][slot] * x[anunciante, slot] for anunciante in dados_visibilidade for slot in slots_tempo_disponiveis))
for slot in slots_tempo_disponiveis:
modelo.Add(sum(x[anunciante, slot] for anunciante in dados_visibilidade) == 1)
status = modelo.Solve()
if status == pywraplp.Solver.OPTIMAL:
grade = []
Dessa forma, encontramos o valor da função objetivo encontrada no problema.
Logo após, imprimimos o resultado da grade, das alocações que foram feitas dos anunciantes. Então vamos escrever:
print('Alocações:')
for slot in slots_tempo_disponiveis:
for anunciante in dados_visibilidade:
if x[anunciante, slot].solution_value() == 1:
grade.append(anunciante)
print('Anunciante', anunciante, 'alocado para o slot de tempo', slot)
Em for slot in slots_tempo_disponiveis
indicamos "para cada slot de tempo"; e em for anunciante in dados_visibilidade
representamos "para cada anuciante". Usando o if x[anunciante, slot].solution_value() == 1:
, checamos se a variável de decisão daquele anunciante e intervalo de tempo possui valor igual a um.
Se o valor for igual a um, imprimimos o resultado do anunciante na tela. Podemos usar o ==1
ou deixar somente .solution_value():
. Isso porque se o valor for zero, não entra no if
. Ao entrar no if
, adicionamos o valor na lista que chamamos de grade usando grade.append(anunciante)
.
Na sequência, inserimos o print()
com o anunciante alocado em cada slot de tempo. Assim, temos a informação de cada anunciante alocado em cada intervalo de tempo.
Por enquanto, temos:
from ortools.linear_solver import pywraplp
modelo = pywraplp.Solver.CreateSolver('SCIP')
x = {}
for anunciante in dados_visibilidade:
for slot in slots_tempo_disponiveis:
x[anunciante, slot] = modelo.BoolVar(f"x[{anunciante, slot}]")
modelo.Maximize(sum(dados_visibilidade[anunciante][slot] * x[anunciante, slot] for anunciante in dados_visibilidade for slot in slots_tempo_disponiveis))
for slot in slots_tempo_disponiveis:
modelo.Add(sum(x[anunciante, slot] for anunciante in dados_visibilidade) == 1)
status = modelo.Solve()
grade = []
if status == pywraplp.Solver.OPTIMAL:
print('Visibilidade total máxima:', modelo.Objective().Value())
print('Alocações:')
for slot in slots_tempo_disponiveis:
for anunciante in dados_visibilidade:
if x[anunciante, slot].solution_value() == 1:
grade.append(anunciante)
print('Anunciante', anunciante, 'alocado para o slot de tempo', slot)
Após isso, verificamos também se o valor for igual a zero, o que significa que o anunciante não foi alocado no intervalo de tempo correspondente.
Depois de incluir essa informação para cada anunciante alocado em cada intervalo de tempo, adicionamos um bloco else
após o if
que verifica se a solução é ótima. Se a solução não for ótima, isso indica que o modelo não encontrou a melhor solução possível.
Então no final do nosso código, digitamos um else:
e passamos um print('O problema não possui solução ótima.')
.
Logo após podemos imprimir justamente aquela grade, que é aquela lista contendo somente o nome dos anunciantes. Então colocamos dentro da lista o nome de cada anunciante, então no final podemos colocar grade
e executar o nosso código para encontrar essa solução.
from ortools.linear_solver import pywraplp
modelo = pywraplp.Solver.CreateSolver('SCIP')
x = {}
for anunciante in dados_visibilidade:
for slot in slots_tempo_disponiveis:
x[anunciante, slot] = modelo.BoolVar(f"x[{anunciante, slot}]")
modelo.Maximize(sum(dados_visibilidade[anunciante][slot] * x[anunciante, slot] for anunciante in dados_visibilidade for slot in slots_tempo_disponiveis))
for slot in slots_tempo_disponiveis:
modelo.Add(sum(x[anunciante, slot] for anunciante in dados_visibilidade) == 1)
status = modelo.Solve()
grade = []
if status == pywraplp.Solver.OPTIMAL:
print('Visibilidade total máxima:', modelo.Objective().Value())
print('Alocações:')
for slot in slots_tempo_disponiveis:
for anunciante in dados_visibilidade:
if x[anunciante, slot].solution_value() == 1:
grade.append(anunciante)
print('Anunciante', anunciante, 'alocado para o slot de tempo', slot)
else:
print('O problema não possui solução ótima.')
grade
É possível que leve algum tempo, já que ele precisa fazer todos os cálculos para determinar as melhores variáveis de decisão. Ao executar com "Ctrl + Enter", notamos que ele concluiu rapidamente e nos mostrou a visibilidade máxima de 888, junto com as alocações.
O retorno abaixo foi parcialmente transcrito:
Visibilidade total máxima: 888.0
Alocações:
Anunciante EsportivaMax alocado para o slot de tempo 0
Anunciante SuperTech alocado para o slot de tempo 1
Anunciante EnergiaViva alocado para o slot de tempo 2
Anunciante TechInova alocado para o slot de tempo 3
Anunciante TechInova alocado para o slot de tempo 4
… Grade de propaganda:
['EsportivaMax',
'SuperTech',
'EnergiaViva',
'TechInova',
'TechInova',
'EsportivaMax',
… ]
No intervalo de tempo zero, o anunciante EsportivaMax foi alocado primeiro, seguido pelo Supertech e depois o Energia Viva, e assim por diante. Ao final do nosso output, teremos apenas a lista com os nomes dos anunciantes.
É interessante observar que conseguimos resolver o problema de alocação das propagandas utilizando a programação linear inteira. Se desejarmos adicionar restrições mais complexas, como a programação linear inteira lidaria com elas? Descobriremos no próximo vídeo!
O curso Otimização: aplicando a programação por restrições possui 157 minutos de vídeos, em um total de 50 atividades. Gostou? Conheça nossos outros cursos de Data Science 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