Olá, tudo bem? Me chamo João Miranda, sou instrutor aqui na Alura e irei te acompanhar ao longo deste curso.
Audiodescrição: João se delcara um homem branco, com cabelo e barba curtos. Veste uma camisa azul lisa. Ao fundo, há uma parede com uma iluminação que vai do verde ao azul.
Você já teve contato com dados que variam ao longo do tempo e não soube como analisá-los?
Neste curso, construiremos um projeto prático de séries temporais utilizando dados da quantidade de clientes em uma rede de restaurantes ao longo do tempo.
A partir desses dados, extrair insights para aprimorar o planejamento dessa rede de restaurantes, detectando pontos de anomalia e fazendo previsões para períodos posteriores, para otimizar a alocação de pessoas atendentes.
Não realizaremos comparações nem avaliações de desempenho de modelos. O foco será na exploração de dados e na análise de séries temporais.
Para acompanhar o conteúdo, é recomendado que você tenha conhecimento na linguagem de programação Python e na biblioteca Pandas.
Vamos começar?
A rede de restaurantes está enfrentando dificuldades no planejamento do negócio. Em alguns dias, a quantidade de clientes é muito baixa, resultando em pessoas atendentes ociosas. Em outros dias, a quantidade de clientes é muito alta, tornando insuficiente a quantidade de pessoas atendentes para atender toda a demanda.
Como cientistas de dados, podemos ajudar essa rede de restaurantes a planejar melhor o negócio e alocar a quantidade ideal de pessoas atendentes para a quantidade de clientes ao longo dos dias.
Essa rede de restaurantes coleta informações sobre a quantidade de clientes que visitam os restaurantes ao longo dos dias e armazena essas informações em um arquivo CSV. Esse arquivo estará disponível na atividade "Preparando Ambiente".
É importante fazer o download dessa base de dados na atividade "Preparando Ambiente" antes de continuar com este vídeo.
Vamos utilizar o Google Colab e a linguagem Python para analisar esses dados e extrair insights para ajudar essa rede de restaurantes a planejar melhor o negócio.
O primeiro passo será fazer o upload do arquivo CSV para o ambiente do Google Colab.
Para fazer isso, abrimos o menu lateral esquerdo "Arquivos", clicamos no primeiro botão na parte superior denominado "Fazer Upload para Armazenamento da Sessão" e selecionamos o arquivo disponível na atividade "Preparando Ambiente", que é o clientes_restaurantes.csv
.
Clicamos duas vezes neste arquivo dentro do nosso computador. Após fazer o upload do arquivo, selecionamos a opção dos três pontos ao lado do nome do arquivo e escolhemos a opção "Copiar Caminho". Feito isso, podemos fechar o menu lateral de arquivos no botão "X" e começar a leitura desse arquivo.
Para ler o arquivo, vamos utilizar a biblioteca pandas
.
Importamos essa biblioteca na primeira célula, utilizando o código import pandas as pd
.
import pandas as pd
Executamos o código com o atalho "Ctrl + Enter".
Agora, para ler o arquivo, vamos utilizar a função read.csv()
da biblioteca pandas
e armazenar isso em uma variável chamada dados
.
Digitamos dados = pd.read_csv('')
, e colamos o caminho do arquivo que copiamos no menu de arquivos. Pressionamos "Ctrl + V" e colamos o caminho '/content/clientes_restaurantes.csv'
.
dados = pd.read_csv('/content/clientes_restaurantes.csv')
Executamos essa célula com "Ctrl + Enter". Agora, já fizemos a leitura da base de dados e armazenamos na variável dados
.
Para visualizar esses dados, vamos para a próxima célula, escrevemos dados
e executamos com "Ctrl + Enter".
dados
Obtemos uma visualização do DataFrame contendo todos os dados da quantidade de clientes que visitam os restaurantes.
# | data | Chimi & Churri | Assa Frão |
---|---|---|---|
0 | 1/1/2016 | 65.0 | 139.0 |
1 | 1/2/2016 | 24.0 | 85.0 |
2 | 1/3/2016 | 24.0 | 81.0 |
3 | 1/4/2016 | 23.0 | 32.0 |
4 | 1/5/2016 | 2.0 | 43.0 |
... | ... | ... | ... |
473 | 4/18/2017 | 30.0 | 18.0 |
474 | 4/19/2017 | 20.0 | 18.0 |
475 | 4/20/2017 | 22.0 | 46.0 |
476 | 4/21/2017 | 38.0 | 38.0 |
477 | 4/22/2017 | 97.0 | 59.0 |
A primeira informação é o índice do DataFrame que varia de 0 até 477, ou seja, temos 478 linhas na base de dados.
Na primeira coluna do DataFrame, temos informações de data que variam de 1/1/2016 até 4/22/2017. A data está no formato americano, onde o primeiro número é o mês, o segundo é o dia e o último é o ano. Nas próximas colunas, temos "Chimi & Churri" e "Assa Frão", que provavelmente são os nomes de cada um dos restaurantes da rede.
As informações nestas colunas são valores numéricos que mostram a quantidade de clientes que visitam esses restaurantes em cada um dos dias.
Esse tipo de informação é conhecido como uma série temporal, uma informação numérica que varia ao longo do tempo.
Já conseguimos fazer a leitura da base de dados e agora podemos começar a explorar as informações desse DataFrame.
Para começar a explorar esses dados, vamos identificar o formato, o tipo de dado de cada uma das colunas e também vamos identificar se existem dados nulos no DataFrame.
Para fazer essa análise, utilizamos o método info()
da biblioteca pandas
. Digitamos na próxima célula, dados.info()
.
dados.info()
Pressionamos "Ctrl + Enter" para executar essa célula.
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 478 entries, 0 to 477
Data columns (total 3 columns):
Column Non-Null Count Dtype
0 data 478 non-null object
1 Chimi & Churri 476 non-null float64
2 Assa Frão 477 non-null float64
dtypes: float64(2), object(1)
memory usage: 11.3+ KB
Obtemos várias informações interessantes sobre a base de dados. Temos 478 registros e um total de 3 colunas. Abaixo do info()
, temos para cada uma das colunas a quantidade de dados não nulos e também o Dtype
, que é o tipo de dado daquelas colunas.
A coluna "data" tem 478 dados não nulos e, como sabemos que tem 478 registros na base de dados, essa coluna não tem nenhum dado nulo. No entanto, o Dtype
, o tipo daquela coluna, está marcado como object
, o que significa que essa coluna está identificada como um texto.
A biblioteca pandas
não sabe que isso é uma data. Vamos precisar fazer uma transformação para alocar essa coluna de data, como o formato DateTime
. A partir disso, a biblioteca pandas
vai identificar que isso é uma data e vamos conseguir trabalhar melhor com esse tipo de informação.
Continuaremos analisando os dados.
As colunas da quantidade de clientes nos restaurantes, "Chimi & Churri" e "Assa Frão", têm 476 e 477 dados não nulos, respectivamente. Como a quantidade de linhas é 478, existem dados nulos que precisaremos tratar (1 no Assa Frão e 2 no Chimi & Churri).
É importante fazer esse tratamento de dados nulos porque estamos trabalhando com séries temporais e, caso tenha alguma data que não tenha uma informação, que é um dado nulo, perdemos a sensação de continuidade. Teremos clientes em um dia e no outro não temos nenhuma informação.
O Dtype
de ambas as colunas está marcado como float64
, ou seja, já está identificado como uma informação numérica.
data
em datetime
O primeiro passo será fazer o tratamento, a modificação da coluna "data" para o formato datetime
, para conseguirmos trabalhar melhor com esse tipo de informação.
Para fazer isso, utilizamos uma função, que é o to_datetime)_
, que vai fazer a transformação daquela coluna, que está como texto, para esse formato de data. Digitamos na próxima célula: dados['data'] = pd.to_datetime(dados['data'])
.
Selecionamos a coluna em dados['data']
e armazenamos o conteúdo dessa transformação na mesma coluna, usando uma substituição com pd.to_datetime()
, passando os mesmos dados.
dados['data'] = pd.to_datetime(dados['data'])
Dessa maneira, conseguimos transformar esses dados, que estão em formato de texto, para o formato de data. Além disso, modificamos essa informação para colocá-la no índice do dataframe. Isso vai facilitar, em momentos futuros, a utilização desse formato de data.
Na mesma célula, digitamos dados.set_index('data', inplace = True)
. Com dados.set_index()
transformamos o índice do dataframe na informação de data. Dentro passamos o nome da coluna (data
) e inplace = True
para fazer a substituição no próprio conjunto de dados.
dados['data'] = pd.to_datetime(dados['data'])
dados.set_index('data', inplace = True)
Executamos essa célula.
Para visualizar a nova informação, na próxima célula, digitamos dados
e executamos o código com "Ctrl + Enter".
data | Chimi & Churri | Assa Frão |
---|---|---|
2016-01-01 | 65.0 | 139.0 |
2016-01-02 | 24.0 | 85.0 |
2016-01-03 | 24.0 | 81.0 |
2016-01-04 | 23.0 | 32.0 |
2016-01-05 | 2.0 | 43.0 |
... | ... | ... |
2017-04-18 | 30.0 | 18.0 |
2017-04-19 | 20.0 | 18.0 |
2017-04-20 | 22.0 | 46.0 |
2017-04-21 | 38.0 | 38.0 |
2017-04-22 | 97.0 | 59.0 |
Agora, a data
está sendo entendida, de fato, como uma data, no formato dateTime
. Observe que a ordem das informações foram alteradas: 2016-01-01
, começa com o ano, mês e depois dia. E também está no índice do dataframe.
Já conseguimos fazer a leitura da base de dados e identificar a quantidade de dados nulos em cada uma das colunas. Vamos precisar fazer um tratamento desses dados, mas isso ficará para o próximo vídeo!
Conseguimos ler a nossa base de dados, que contém a quantidade de clientes que frequentam a rede de restaurantes. Na exploração inicial, percebemos a presença de dados nulos no DataFrame. Esses dados nulos podem prejudicar as análises futuras. Eles interferem na extração de estatísticas, como média e mediana, e também fazem com que percamos o senso de continuidade da série temporal.
O que podemos fazer para detectar quais são esses dados nulos e não ter nenhum problema em análises posteriores? Uma filtragem na base de dados utilizando o método isna()
para detectar quais são esses dados nulos.
Na primeira célula, começamos com o restaurante Chimi & Churri. Digitamos: dados['Chimi & Churri']
. E depois que filtrarmos a coluna, vamos fazer a filtragem das linhas. Abrimos colchetes novamente, [dados['Chimi & Churri'].isna()]
.
dados['Chimi & Churri'][dados['Chimi & Churri'].isna()]
Executamos essa célula com "Ctrl + Enter".
data
2016-04-05 NaN
2016-09-17 NaN
Name: Chimi & Churri, dtype: float64
Obteremos dois valores nulos representados por NaN
e estão na data 2016-04-05 e 2016-09-17.
Seria interessante se conseguíssemos visualizar isso a partir de um gráfico. Vamos construir um gráfico da série temporal mostrando a quantidade de clientes ao longo do tempo do Chimi & Churri e vamos colocar retas verticais em vermelho para dar esse destaque nas datas onde ocorreram dados nulos.
Para construir essas retas verticais, importamos a biblioteca matplotlib e utilizar a função axvline()
.
Na próxima célula, importamos a primeira biblioteca com import matplotlib.pyplot as plt
, executando o código com "Ctrl + Enter".
import matplotlib.pyplot as plt
Na próxima célula, vamos construir primeiro o gráfico de linhas da série temporal. Digitamos: dados['Chimi & Churri'].plot(figsize = (20,3))
, sendo (20,3)
o tamanho da figura. Na mesma célula, inserimos as retas verticais. Vai ser uma reta vertical para cada uma das datas. Então, construiremos dois gráficos de reta vertical.
O primeiro deles vai ser plt.axvline(x=, color='red')
. Precisamos passar x=
para identificar em qual data ocorreu o dado nulo. Vamos fazer toda essa filtragem, passando toda a filtragem que fizemos anteriormente para esse x=
e, ao final, passamos qual é a data. Digitamos .index[0]
para passar a primeira data. Também teremos uma cor para essa reta vertical com color = 'red'
.
Nessa mesma célula, inserimos a próxima data. Copiamos todo esse código, colamos na próxima linha e substituímos index[0]
por index[1]
. Inserimos um ponto e vírgula ao final do código, pois, se não o fizermos, a biblioteca matplotlib mostra uma informação textual no nosso gráfico. Como não desejamos essa informação, adicionamos o ponto e vírgula.
dados['Chimi & Churri'].plot(figsize = (20,3))
plt.axvline(x = dados['Chimi & Churri'][dados['Chimi & Churri'].isna()].index[0], color = 'red')
plt.axvline(x = dados['Chimi & Churri'][dados['Chimi & Churri'].isna()].index[1], color = 'red');
Executamos o código com "Ctrl + Enter".
Conseguimos obter qual é a quantidade de clientes ao longo do tempo para o restaurante Chimi & Churri. No mês de abril e no mês de setembro, temos duas retas verticais mostrando onde estão os dados nulos dessa série temporal.
Faremos o mesmo para o restaurante Assa Frão.
Copiamos o código da filtragem dos dados nulos, colamos na próxima célula vazia e substituímos as informações de Chimi & Churri
para Assa Frão
.
dados['Assa Frão'][dados['Assa Frão'].isna()]
Executamos o código com "Ctrl + Enter".
data
2016-11-24 NaN
Name: Assa Frão, dtype: float64
Conseguimos obter apenas um dado nulo que está na data 2016-11-24
.
Vamos fazer a mesma coisa e visualizar isso em um gráfico. Copiamos todo o código que construímos para o gráfico do Chimi & Churri. Vamos colar na próxima célula vazia e substituir as informações de Chimi & Churri
para Assa Frão
.
Então, digitamos Assa Frão
dentro dos colchetes, e no axvline()
. Posteriormente ajustamos em x = dados['Assa Frão'][dados['Assa Frão'].isna()]
. No index colocamos index[0]
, porque**** só temos apenas uma data de dado nulo. No final, inserimos o ponto e vírgula.
dados['Assa Frão'].plot(figsize = (20,3))
plt.axvline(x = dados['Assa Frão'][dados['Assa Frão'].isna()].index[0], color = 'red');
Executamos o código com "Ctrl + Enter".
Obtemos outro gráfico da série temporal para o Assa Frão e conseguimos perceber que, em novembro de 2016, temos uma reta vertical mostrando qual é o dado nulo nessa série temporal.
Identificamos quais são os dados nulos e em quais datas eles ocorrem, mas agora precisamos tratá-los para que não prejudiquem nossas análises futuras. Quais tipos de tratamento podemos realizar?
A abordagem mais indicada seria substituir esses valores pelos dados originais daquela data. Para isso, a rede de restaurantes precisa recuperar a fonte de informação original em alguma base de dados que possuem. No entanto, no caso, não temos mais essa fonte de informação. Portanto, embora essa seja a melhor opção, utilizaremos outras estratégias para preencher os dados nulos.
Uma das estratégias possíveis é substituir o valor nulo pela média da coluna. Esse tratamento é mais adequado quando o DataFrame não depende da data. No entanto, como estamos trabalhando com séries temporais, existem tratamentos mais indicados, pois o padrão dos dados muda ao longo do tempo.
Vamos substituir os valores nulos por valores que correspondem ao padrão de um período. Por exemplo, podemos substituir o valor nulo pelo valor do dia anterior ou pelo valor do dia posterior. Isso faz sentido porque, nestes dias próximos, a série temporal tende a apresentar um padrão semelhante.
No entanto, utilizaremos uma estratégia ainda mais indicada: a interpolação entre o dia anterior e o dia posterior.
Essa interpolação calcula um ponto médio entre o valor da data anterior e o valor da data posterior.
Para realizar essa interpolação, usaremos o método interpolate()
. Na próxima célula, digitamos dados = dados.interpolate()
.
dados = dados.interpolate()
Essa função detecta automaticamente os dados nulos e realiza a substituição com base na lógica de calcular o ponto médio entre a data anterior e a data posterior. Ela preencherá apenas os valores nulos na base de dados. Ao executar essa célula, toda a base será atualizada, mas apenas os dados nulos serão preenchidos.
Para verificar se o tratamento foi realizado corretamente, filtraremos os dados para as datas nulas. Identificamos que as datas com dados nulos são 5 de abril (04-05
), 17 de setembro (09-17
) e 24 de novembro (11-24
). Vamos analisar o dia anterior e o dia posterior a cada uma dessas datas. Na próxima célula, digitamos dados.loc['2016-04-04':'2016-04-06']
.
dados.loc['2016-04-04':'2016-04-06']
Estamos selecionando um intervalo de dias que inclui a data anterior ao dia 5 de abril e a data posterior.
data | Chimi & Churri | Assa Frão |
---|---|---|
2016-04-04 | 32.0 | 12.0 |
2016-04-05 | 17.0 | 34.0 |
2016-04-06 | 2.0 | 40.0 |
Ao executar esse código, visualizamos que o restaurante Chimi & Churri agora tem um valor para o dia 5 de abril, que estava nulo. Esse valor é o ponto médio entre 32 e 2. Portanto, a soma de 32 mais 2 é 34, e dividida por 2 resulta em 17.
Vamos aplicar a mesma filtragem para detectar os outros dados nulos. Copiamos e colamos o código nas duas células seguintes, e para a próxima data, que é 17 de setembro (09-17
), usamos dados.loc['2016-09-16':'2016-09-18']
.
dados.loc['2016-09-16':'2016-09-18']
Obtemos:
data | Chimi & Churri | Assa Frão |
---|---|---|
2016-09-16 | 23.0 | 51.0 |
2016-09-17 | 37.5 | 60.0 |
2016-09-18 | 52.0 | 57.0 |
Ao executar essa linha, visualizamos que o valor para 17 de setembro foi preenchido com a média entre 23 e 52, que são os valores dos dias 16 e 18 de setembro. O valor resultante é 37,5.
Como trabalhamos com a quantidade de clientes que frequentam o restaurante, o valor decimal não faz sentido, e precisaremos ajustar esse valor para um número inteiro.
Por fim, filtramos a última data nula, que é 24 de novembro. Usamos dados.loc['2016-11-23':'2016-11-25']
.
dados.loc['2016-11-23':'2016-11-25']
Executamos com "Ctrl + Enter".
data | Chimi & Churri | Assa Frão |
---|---|---|
2016-11-23 | 5.0 | 38.0 |
2016-11-24 | 17.0 | 70.0 |
2016-11-25 | 72.0 | 102.0 |
Verificamos que, no restaurante Assa Frão, o valor para 24 de novembro é 70, que corresponde à média entre 102 e 38.
Com o tratamento dos dados nulos concluído, podemos agora prosseguir com as análises. Continuaremos essas análises no próximo vídeo!
O curso Séries temporais: detectando anomalias e realizando previsões possui 147 minutos de vídeos, em um total de 50 atividades. Gostou? Conheça nossos outros cursos de Machine Learning 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:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
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.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
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.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
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.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.