Estudo de Regressão Linear 1
Um exercício sobe o consumo de cerveja
Momento Zero do Artigo
Como podem ter visto, o tempo de leitura estimado pelo Medium para esse artigo é grande. Contudo, não tenham medo. O artigo ficou grande, pois tentei descrever um estudo feito da forma mais clara possível e explicar cada passo de maneira mais didática possível. Procurei fazer uma análise tanto computacional quanto matemática do estudo.
Não se faz necessário ler este artigo em uma única tacada. Em se tratando de um estudo, você pode ir acompanhando parte por parte. Um tijolo de cada vez. Um dia de cada vez.
Caso alguma parte não tenha ficado clara, por favor, peço-lhe que me informe nos comentários ao final dele. Estou aberto a correções e sugestões para que o conteúdo seja o mais coerente, claro e exato possível.
Adicionalmente, não estou sendo pago e nem patrocinado pela Alura Cursos. Quis escrever esse artigo, pois estou curtindo bastante os cursos da Formação em Cientista de Dados e também porque me apaixonei pela área.
Então, é isso! Bons estudos!
Antes de tudo
Esse estudo foi feito como um projeto do curso de Regressão Linear: Testando Relações e Prevendo Resultados oferecido pela Alura.
O objetivo desse artigo é mostrar um pouco do que é ensinado nos cursos de Ciência de Dados da Alura e também como alguns conceitos de estatística são aplicados à disciplina para análise e exploração de dados.
Além disso, por meio desse artigo, espero que eu consiga passar para você o que aprendi com esse curso. Afinal, quem ensina, aprende duas vezes.
Por último e não menos importante, somando-se ao conteúdo do curso, adicionei minhas próprias notas sobre o que entendi de cada passo do estudo.
Objetivos do estudo
- Aprender a explorar e analisar dados de forma estatística.
- Aprender a utilizar as bibliotecas (pandas, matplotlib, seaborn, numpy) para explorar, analisar e manipular dados.
- Aprender a utilizar a biblioteca scikit-learn para estimar modelos de regressão linear.
Introdução
Para que você possa reproduzir o mesmo estudo que fiz, deixarei aqui as informações necessárias sobre o dataset utilizado, ambiente e máquina. Contudo, não é necessário que você utilize exatamente o mesmo ambiente e máquina, mas recomendo que o dataset seja o mesmo.
Do Dataset 🗄
O conjunto de dados utilizado nesse estudo foi obtido na plataforma Kaggle e você pode encontrar em:
Segundo o autor do dataset, a coleta dos dados foi feita em São Paulo, no período de Janeiro/2015 a Dezembro/2015 em uma área na qual ocorrem festas universitárias e a faixa etária dos participantes foi de 18 a 28 anos de idade.
Uma observação sobre as variáveis: a nomenclatura das variáveis da base do Kaggle (nome das colunas) está diferente da utilizada no estudo, pois a Alura renomeou as variáveis a título de ser mais fácil trabalhar com elas.
Do ambiente de estudo 🛠
Para esse estudo, utilizei o Jupyter Notebook por meio da plataforma Anaconda. Caso você não tenha Anaconda instalado em sua máquina, você pode ou instalar ou utilizar o Google Colab que fornece o mesmo tipo de ambiente que o Jupyter só que na nuvem da Google e integrado com o seu Google Drive.
Uma observação: a versão Anaconda3–2019.01 para ambiente Windows não estava funcionando corretamente no meu PC Windows. Recentemente, atualizaram para Anaconda3–2020.02, mas não verifiquei se corrigiram o problema.
Da máquina 💻
Para esse estudo, utilizei um MacBook Pro 15", 2017, 2.8 GHz Quad-Core Intel Core i7, 16 GB 2133 MHz.
Das convenções do artigo
O Medium nos permite inserir blocos de código (Cmd + Opt + 6). Dessa forma, para aproveitar a formatação, vamos combinar uma convenção.
[IN]
print('Hello World!')[OUT]
Hello World!
O "[IN]" sempre vai se referir ao bloco de código que será executado e o "[OUT]" o resultado do código executado. OK?
Posto isso, vamos começar a nossa exploração e análise!
Importando as biblioteca necessárias
As bibliotecas facilitam o nosso estudo, pois foram criadas para explorar, analisar e manipular dados. Fazemos:
[IN]
# importando o matplotlib.pyplot
import matplotlib.pyplot as plt# usando função mágica para que os gráficos sejam gerados logo após a
# célula de código do notebook
# isso também permite que os gráficos sejam armazenados no notebook
%matplotlib inline# importando o pandas
import pandas as pd# importando o numpy
import numpy as np# importando o seaborn
import seaborn as sns
Lendo o arquivo de dados
O nosso arquivo de dados Consumo_cerveja.csv
é um arquivo CSV (Comma Separated Values) cujo separador utilizado nele é o ;
(ponto e vírgula).
[IN]
# lendo o arquivo de dados e atribuindo a uma variável
# cujo nome é "dados"
dados = pd.read_csv('Consumo_cerveja.csv', sep = ',')
Conhecendo o dataset
Antes de já querermos partir para a exploração, análise, investigação e estimativa, é muito importante que comecemos conhecendo o nosso conjunto de dados, pois todas as etapas posteriores serão impactadas negativamente caso não façamos esse reconhecimento preliminar do dataset.
Como assim "conhecer o dataset"?
Conhecer o dataset implica em:
a) Saber o tamanho dele (número de registros e colunas)
Saber o tamanho do dataset nos permite verificar o tamanho da amostra que vamos analisar e inferir modelos sobre ela.
"Qual é o tamanho do bicho que estamos lidando?"
Para isso podemos fazer:
[IN]
dados.shape[OUT]
(365, 7)
Isso implica que temos um total de 365 registros e 7 colunas.
b) Ter uma visão geral sobre as colunas
Até aqui, tudo bem, mas quais são as colunas do nosso dataset?
"Do que é feito o bicho que estamos lidando?"
Para isso, fazemos:
[IN]
# observando as informações do nosso dataset
dados.info()[OUT]
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 365 entries, 0 to 364
Data columns (total 7 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 data 365 non-null object
1 temp_media 365 non-null float64
2 temp_min 365 non-null float64
3 temp_max 365 non-null float64
4 chuva 365 non-null float64
5 fds 365 non-null int64
6 consumo 365 non-null int64
dtypes: float64(4), int64(2), object(1)
memory usage: 20.1+ KB
Descrevendo as colunas.
data
: é o dia que foram coletados os dados.temp_media
: temperatura média para o respectivo dia.temp_min
: temperatura mínima para o respectivo dia.temp_max
: temperatura máxima para o respectivo dia.chuva
: quantidade em mililitros de chuva para o respectivo dia.fds
: se o respectivo dia era final de semana (1 = sim, 0 = não).consumo
: consumo de cerveja em litros para o respectivo dia.
Observando o resultado acima, além de verificarmos a quantidade total de registros (365 entries
) e colunas (total 7 columns
), também podemos comparar o total de registros com o total de Non-Null Count
que nos informa quantos valores não são null (null implica valores faltantes) para cada coluna.
Dessa forma, verificamos que não há valores faltantes em nosso dataset, pois de um total de 365 registros, todos possuem 365 valores non-null.
c) Dar uma olhada nos primeiros registros
Agora vamos dar uma espiada nos primeiros cinco registros. Só por curiosidade.
"Deixa eu dar uma espiada nesse bicho."
[IN]
dados.head()[OUT]
O resultado mostra alguns registros e como os valores estão formatados em nosso dataset.
d) Verificar a existência ou não de valores faltantes (missing values)
É adequado que o dataset apresente a menor quantidade de valores faltantes, pois a falta de um valor em um registro pode prejudicar a nossa análise. É como se tivéssemos um queijo (🧀), se ele não for suíço, quanto mais buracos, pior é.
"Meu bicho tá completinho ou tá com defeitos?"
No item (b) já verificamos que não há valores faltantes, mas por desencargo de consciência e também como uma alternativa, podemos fazer:
[IN]
# verificando se há dados faltantes
dados.isna().any()[OUT]
data False
temp_media False
temp_min False
temp_max False
chuva False
fds False
consumo False
dtype: bool
Essa linha de código executada faz a seguinte pergunta: "Do meu dataset, tem algum dado de alguma coluna que seja null?". Se para uma ou mais colunas o valor retornado for True
, isso significa que há sim valores faltantes para as respectivas colunas. No caso, todas retornaram False
, isso implica que não há valores faltantes para nenhuma coluna do dataset.
Poderíamos verificar de outra forma também, fazendo:
[IN]
# verificando se há dados faltantes
dados.isna().sum()[OUT]
data 0
temp_media 0
temp_min 0
temp_max 0
chuva 0
fds 0
consumo 0
dtype: int64
Essa linha de código executada instrui o seguinte: "Do meu dataset, conte quantos valores null existem para cada uma das colunas ". Observando o resultado obtido, verificamos que não há valores null, pois obtivemos o total de 0
para cada coluna.
Análises Estatísticas Preliminares
Estatísticas Descritivas
O intuito de se fazer uma análise preliminar utilizando as estatística descritivas é verificar se há dados discrepantes — que pode decorrer de uma digitação errada, esquecimento de registrar, falha no sistema ou qualquer outra coisa.
Então, fazemos:
[IN]
# chamando o método que nos fornece as informações
# das estatísticas descritivas sobre o nosso dataset
dados.describe().round(2)[OUT]
Com essa análise, se víssemos, por exemplo, que o valor da temperatura máxima fosse 100.00 ou da mínima -50.00, observaríamos que há algo de errado, pois sabemos que em São Paulo normalmente não temos esse tipo de tempo. Além disso, precisamos ver se faz sentido a gradação de cada dado — os steps entre os quartis— e se não há salto absurdos neles, o que caracterizaria a existência de outliers. Quando ocorre a existência de outliers, precisamos tratar nosso dataset para que esses dados não impactem a nossa análise e a possibilidade de errarmos no nosso modelo estimado.
Matriz de Correlação
Essa matriz no permite identificar a correlação das variáveis que compõe o dataset. Nela, temos os valores que correspondem ao coeficiente de correlação.
O coeficiente de correlação é uma medida de associação linear entre duas variáveis e situa-se entre -1 e +1 sendo que -1 indica associação negativa perfeita e +1 indica associação positiva perfeita. — Alura Cursos
- Associação negativa: enquanto uma variável "sobe" a outra "desce".
- Associação positiva: quando uma variável "sobe" a outra também "sobe".
Para obtermos a matriz de correlação, fazemos:
[IN]
# olhando a matriz de correlação
dados.corr().round(4)[OUT]
Observando a matriz de correlação, verificamos as correlações da variável consumo
com as demais. Verificamos uma correlação negativa de ‘consumo’ com ‘chuva’ e podemos tirar uma hipótese de que quando chove o consumo de cerveja diminui (chuva
subindo e consumo
descendo).
Ao escolher as variáveis que vamos trabalhar, precisamos tomar cuidado para escolher as que fazem mais sentido, pois nem sempre uma correlação alta de uma variável com a outra significa que vamos conseguir tirar algum modelo adequado para o que queremos analisar.
Por exemplo, temos a variável temp_max
que tem 0.9225 de correlação com a variável temp_media
, é uma alta correlação, mas sendo as duas variáveis explicativas e que fazem parte do mesmo fenômeno (temperatura), não faz sentido escolher as duas, pois estaríamos adicionando mais do mesmo no nosso modelo.
Dessa forma, vamos escolher as variáveis:
- variável dependente (Y):
consumo
- variáveis auxiliares (X) que explicarão a dependente (Y):
chuva ; temp_max ; fds
Em resumo, em modelos de regressão linear é importante:
- Verificarmos se as variáveis explicativas (X’s) têm forte correlação com a variável dependente (Y).
- Que as variáveis explicativas (X’s) não tenham forte correlação entre si.
Análises Gráficas
Nessa seção, vamos começar a analisar graficamente o comportamento da nossa variável dependente consumo
.
Plotando a variável dependente y
Vamos observar o comportamento da variável consumo
no tempo. Para isso, fazemos:
[IN]
# chamando a função subplots; cria uma figura e permite que você
# insira gráficos dentro dessa figura
fig, ax = plt.subplots(figsize=(20,6))# adicionando um título ao nosso gráfico
ax.set_title('Consumo de Cerveja ao longo de 365 dias', fontsize=20)# identificando os eixos
ax.set_ylabel('Consumo (litros)', fontsize=14)
ax.set_xlabel('Tempo (dias)', fontsize=14)# plotando o nosso gráfico; o parâmetro fontsize vai definir o tamanho
# da fonte da gradação dos eixos
ax = dados['consumo'].plot(fontsize=14)[OUT]
O gráfico mostra como foi o consumo ao longo do ano (365 dias). Observamos que o comportamento da variável não possui anomalias. Por anomalias queremos dizer que poderia haver períodos onde há um extremo consumo e outros onde há um consumo quase inexistente.
O Boxplot
O objetivo desse artigo não é explicar o que é o boxplot, para isso, pode-se fazer uma rápida pesquisa no Google. O importante aqui, no nosso estudo, é utilizar essa ferramenta para analisarmos os nosso dados, mais especificamente, o comportamento da variável consumo
.
Duas das principais características de um boxplot é a possibilidade de identificar a simetria ou assimetria (figura abaixo) do conjunto de dados e a presença de outliers.
Assim, fazemos:
[IN]
# plotando o boxplot para a variável 'consumo'
# ao atribuir o gráfico a uma variável,
# podemos fazer algumas formatações
ax = sns.boxplot(data=dados['consumo'], orient='v', width=0.2)# fazendo formatações
ax.figure.set_size_inches(12,6)# adicionando um título ao nosso gráfico
ax.set_title('Consumo de Cerveja para 365 dias', fontsize=20)# identificando os eixos
ax.set_ylabel('Consumo (litros)', fontsize=14)ax[OUT]
Observando o gráfico de boxplot, verificamos que não há a presença de outliers ou dados discrepantes. A distribuição parece OK. Aparentemente, não há nada fora do comum.
Boxplot para mais de uma variável
Já que observamos que a variável dependente consumo
por si só não apresenta anomalias, vamos fazer uma outra análise.
Vamos investigar se há mesmo uma diferença de comportamento da variável consumo
se for final de semana ou não. Queremos ver se as estatísticas de consumo são diferentes por conta da variável fds
. Dessa forma, fazemos:
[IN]
# plotando o boxplot para as variáveis 'consumo' e 'fds'
# ao atribuir o gráfico a uma variável,
# podemos fazer algumas formatações
ax = sns.boxplot(data=dados, y='consumo', x='fds', orient='v', width=0.5)# fazendo formatações
ax.figure.set_size_inches(12,6)# adicionando um título ao nosso gráfico
ax.set_title('Consumo de Cerveja em relação ao Final de Semana', fontsize=20)# identificando os eixos
ax.set_ylabel('Consumo (litros)', fontsize=14)
ax.set_xlabel('Final de semana (0 = Não ; 1 = Sim)', fontsize=14)ax[OUT]
Observando o gráfico, podemos verificar que realmente há uma diferença de estatísticas de consumo entre ser ou não final de semana. O consumo médio é maior quando é final de semana e menor quando não é, vide os patamares distintos da mediana em cada boxplot.
Em dias que não é final de semana, temos alguns outliers que, por hipótese, pode ser decorrência de algum feriado que tivemos no meio da semana (ex: Carnaval).
Distribuição de Frequências
Vamos verificar se a nossa variável dependente consumo
segue uma distribuição normal. Uma das formas de fazermos isso é plotar um histograma da variável e observar se o formato da curva se assemelha a uma curva de distribuição normal (imagem acima).
Para entender melhor qual a utilidade dessa curva em termos estatísticos, recomendo este vídeo: The Normal Distribution and the 68–95–99.7 Rule (5.2).
O importante aqui, no nosso estudo, é fazer essa verificação, pois a assertividade do modelo que vamos estimar e das ferramentas utilizadas dependem de termos uma distribuição normal de nossos dados. Dessa forma, fazemos:
[IN]
# plotando um histograma para a variável 'consumo'
ax = sns.distplot(dados['consumo'])# fazendo formatações
ax.figure.set_size_inches(12,6)# adicionando um título ao nosso gráfico
ax.set_title('Distribuição de Frequências de Consumo de Cerveja', fontsize=20)# identificando os eixos
ax.set_xlabel('Consumo de Cerveja (litros)', fontsize=14)
ax.set_ylabel('Frequência', fontsize=14)ax[OUT]
Observando o gráfico gerado, verificamos que a distribuição de frequências da nossa variável dependente não é 100% normal. Isso pode decorrer da quantidade de observações que temos (365 registros) ou realmente o consumo não segue uma distribuição normal.
O que podemos fazer nesse caso é aplicar técnicas de transformação de dados para nos ajudar em nossa análise. Contudo, nesse momento, o objetivo aqui é entendermos as ferramentas disponíveis e aplicá-las em nosso estudo. Então, seguiremos com a distribuição de frequências da variável consumo
da maneira como está.
Entendo que em uma situação real, o mais adequado seria coletar maior quantidade de dados, observar e aplicar as técnicas necessárias.
Análise de gráficos de dispersão (Variável Dependente x Variáveis Explicativas)
Nessa seção, vamos analisar a correlação entre a variável dependente (consumo
) e as variáveis explicativas (chuva ; temp_max ; fds
).
Utilizando o pairplot
Queremos analisar a variável consumo
para vermos as correlações dela com as variáveis explicativas. Além disso, o gráfico de dispersão nos permite identificar se duas variáveis apresentam uma relação linear entre elas e a direção dessa relação. Então fazemos:
[IN]
# podemos definir uma lista de variáveis para que
# seja feita a correlação
ax = sns.pairplot(dados, y_vars='consumo', x_vars=['temp_min', 'temp_media', 'temp_max', 'chuva', 'fds'])# incluindo o título
ax.fig.suptitle('Dispersão entre as variáveis', fontsize=20, y=1.1)ax[OUT]
Observando os gráficos, verificamos:
- consumo x temp_min: quanto maior temperatura mínima, maior consumo.
- consumo x temp_media: a mesma relação com a temp_min, só que estão mais concentrados.
- consumo x temp_max: a mesma relação que as anteriores, só que estão ainda mais concentrados.
- consumo x chuva: uma correlação negativa, ou seja, quando mais chuva, menos consumo e vice-versa.
- consumo x fds: como vimos no boxplot, há consumo nos dois casos, mas estão em patamares diferentes.
Reta de Regressão Linear
Vamos observar a reta de regressão linear para vermos a direção da relação entre as variáveis. Fazemos:
[IN]
# podemos definir uma lista de variáveis para que
# seja feito o gráfico de dispersão;
# com o parâmetro 'kind=reg', há a tentativa de
# traçar uma reta de regressão linear
# parâmetro 'plot_kws' nos permite fazer outras configurações
ax = sns.pairplot(dados, y_vars='consumo', x_vars=['temp_min', 'temp_media', 'temp_max', 'chuva', 'fds'],
kind='reg', plot_kws={'line_kws':{'color':'purple'}})# incluindo o título
ax.fig.suptitle('Dispersão entre as variáveis', fontsize=20, y=1.1)ax[OUT]
As retas traçadas reforçam as observações que fizemos anteriormente sobre a correlação das variáveis que estamos estudando.
O curso a Alura também cobre o uso do seaborn.lmplot da biblioteca seaborn utilizando duas e três variáveis. Contudo, optei por não cobrir no artigo, pois não agregaria alguma conclusão a mais aqui. Caso queira saber mais sobre esse tipo de plot, acesse:
Estimando um modelo de Regressão Linear para o consumo
A análise de regressão diz respeito ao estudo da dependência de uma variável (a variável dependente) em relação a uma ou mais variáveis, as variáveis explanatórias, visando estimar e/ou prever o valor médio da primeira em termos dos valores conhecidos ou fixados das segundas. — Alura Cursos
No caso do nosso estudo, temos uma variável dependente, consumo
(Y), e três variáveis explicativas, chuva ; temp_max ; fds
(X2, X3 e X4, respectivamente). Assim, podemos montar a equação da nossa reta de regressão estimada.
Para fazermos isso, é importante que tenhamos separado os nosso dados em dois datasets: um de treino e um de teste. Vamos treinar o nosso modelo em um dataset de treino e depois vamos criar as estimativas no dataset de teste para medirmos quão bom está o nosso modelo.
Fazendo as importações necessárias
Para realizarmos os treinos e os testes, se faz necessário importar a função train_test_split da biblioteca scikit-learn. Então, fazemos:
[IN]
# importando a função que nos ajudará a separar os dados
from sklearn.model_selection import train_test_split
Separando as variáveis necessárias
Antes de começarmos os testes, precisamos pegar o nosso dataset e separar as variáveis. Vamos utilizar a nomenclatura que a própria documentação da função utiliza. Dessa forma, fazemos:
[IN]
# criando uma Series (pandas) para armazenar
# o consumo de cerveja (y)
y = dados['consumo']y[OUT]
0 25461
1 28972
2 30814
3 29799
4 28900
...
360 32307
361 26095
362 22309
363 20467
364 22446
Name: consumo, Length: 365, dtype: int64
E então.
[IN]
# criando um DataFrame (pandas) para armazenar
# as variáveis explicativas (X)
X = dados[['temp_max', 'chuva', 'fds']]X[OUT]
Criando os datasets de treino e de teste
Olhando a documentação da função train_test_split, observamos que ela retorna uma lista de 4 elementos:
X_train
eX_test
são Data Frames.y_train
ey_test
são Series.
Vemos que X_train
está relacionado a y_train
; X_test
está relacionado com y_test
. Aí fazemos:
[IN]
# test_size é o tamanho que se quer utilizar do dataset ;
# pega registros de forma aleatória
# random_state é a semente do nosso aleatório
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=2811)
Agora, vamos observar o que a função train_test_split fez com o nosso dataset X
. Lembrando que a quantidade total de registros nele é 365.
Para X_train
, temos:
[IN]
# observando quanto registros foram alocados para treino
X_train.shape[OUT]
(255, 3)
Para X_test
, temos:
[IN]
# observando quanto registros foram alocados para teste
X_test.shape[OUT]
(110, 3)
De fato, a função dividiu em dois datasets (X_train
e X_test
) contendo, respectivamente 255 e 110 registros (255 + 110 = 365).
Estimando a reta de regressão linear
Para estimarmos a reta, precisamos importar a biblioteca LinearRegression da biblioteca scikit-learn. Além disso, para que possamos avaliar o nosso modelo, importaremos a biblioteca metrics.
[IN]
# importando LinearRegression da biblioteca scikit-learn
from sklearn.linear_model import LinearRegression# importando as métricas que vai estimar
# o quanto o nosso modelo tá bom ou não
from sklearn import metrics
Agora, vamos instanciar a classe LinearRegression por meio de um objeto.
[IN]
# vamos chamar de 'modelo', pois é o modelo que estamos estimando
modelo = LinearRegression()
Utilizaremos os dados de treino (y_train
e X_train
) para estimar o modelo, aí fazemos:
[IN]
# utilizamos o método fit() para estimar o modelo
modelo.fit(X_train, y_train)[OUT]
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)
Tá bom ou tá ruim?
Agora que estimamos o modelo, vamos verificar o quão bom ou ruim é o nosso modelo em estimar um valor da variável dependente (Y) dados os valores das variáveis explicativas (Xni). Para isso, podemos calcular o coeficiente de determinação (R²) que é uma medida resumida que diz quanto a reta de regressão ajusta-se aos dados.
Onde: 0 ≤ R² ≤ 1
Assim, fazemos:
[IN]
# queremos o score (R²) do modelo que estimamos
# anteriormente com a função fit
print('R² = {}'.format(modelo.score(X_train, y_train).round(2)))[OUT]
R² = 0.73
Observando o resultado obtido, verificamos que o valor 0.73 nos diz que nosso modelo estimado é capaz de ter uma assertividade de 73% ao queremos calcular o quanto será o consumo de cerveja (em litros) dados os valores de chuva (em mililitros), temperatura máxima (em Celsius) e se é final de semana ou não.
Quanto mais próximo do valor 1.0, melhor. Então, nosso objetivo é maximizar esse valor.
Além disso, o R² somente poderia cair se fossem substituídas as variáveis explicativas. Com o acréscimo de variáveis, esta métrica não cai.
Agora, vamos obter dados de previsão utilizando os dados de teste (X_test
), ou seja, com base nos dados de teste (dados de coletados em campo — chuva ; temp_max ; fds
(variáveis explicativas X2, X3 e X4, respectivamente)), vamos calcular os valores para consumo
(variável dependente Y).
Fazemos:
[IN]
# vamos prever os valores baseados nos valores de X_test
y_previsto = modelo.predict(X_test)y_previsto[OUT]
array([26094.90177526, 25056.13191497, 23852.14792684, 29361.63643926,
25603.92132216, 28890.65776528, 20484.03383301, 28965.58342859,
21023.87627737, 29575.39452427, 28342.86835809, 28548.28938579,
25321.09612517, 22225.89320436, 20544.69824707, 30719.97303089,
23275.81634161, 26634.25245434, 29430.11011516, 19920.60622259,
23274.57708862, 23070.39531392, 17226.09529035, 20676.55088589,
25595.58426485, 25530.98239956, 21285.12272857, 25809.34234985,
21894.18633654, 27863.55262681, 22600.85923454, 23823.97949265,
23960.5531006 , 20057.55357439, 29361.63643926, 23823.6057488 ,
31347.37304031, 22909.13498792, 25809.34234985, 31172.22520894,
31895.1624475 , 22842.27430887, 25193.07926677, 25457.31566882,
27110.34219192, 30699.85323034, 25261.55294267, 30920.65673884,
28274.3946822 , 20536.86930568, 31895.1624475 , 26220.18440524,
34154.79375215, 19843.20205329, 26151.71072935, 27932.0263027 ,
19989.07989849, 22010.30243027, 24850.71088728, 29989.93798801,
17798.66975745, 21016.18503696, 24721.71049831, 25869.47896844,
27623.00306161, 28884.57952173, 21292.06648126, 29977.89952234,
25925.79615724, 34771.05683523, 18723.31026472, 32442.95185469,
25809.34234985, 26220.18440524, 24298.45623339, 24371.39515599,
24500.00545047, 24576.81618368, 21290.07974056, 22728.02693442,
18483.03277258, 18107.0668612 , 28753.71041349, 31552.79406801,
24713.76353548, 27416.24111012, 26288.65808114, 25330.02661856,
31826.6887716 , 24234.44780419, 17840.84371844, 24165.97412829,
24615.64612954, 25732.53161664, 30694.14873064, 19920.60622259,
30123.18393145, 27681.7987564 , 26014.76337755, 20810.76400927,
30507.45419888, 23892.0794247 , 22043.29017544, 26083.23705345,
21001.55004387, 23265.52857379, 24097.50045239, 29194.17984828,
24713.76353548, 20057.55357439])
Agora, vamos obter novamente o R², só que agora comparando os dados reais observados para consumo
(y_test
) com os estimados (y_previsto
).
[IN]
# agora vamos comparar o previsto com o de teste (real)
print('R² = %s' % metrics.r2_score(y_test, y_previsto).round(2))[OUT]
R² = 0.69
Observando o resultado obtido, verificamos que o valor 0.69 nos diz que nosso modelo estimado é capaz de ter uma assertividade de 69% ao queremos calcular o quanto será o consumo de cerveja (em litros) dados os valores de chuva (em mililitros), temperatura máxima (em Celsius) e se é final de semana ou não.
Muito bem, mas como ficou a equação da nossa reta de regressão linear estimada? E aqueles coeficientes angulares? E o erro?
Agora, vamos observar um pouco melhor o que é o quê na equação da reta de regressão linear estimada. Resgatando a equação genérica da reta, temos:
Primeiro, vamos observar o valor de 𝛽1 (intercepto, nome dado, pois é o valor obtido para Xn = 0, quando a reta de regressão linear corta o eixo y) e de cada um dos coeficientes angulares (𝛽2, 𝛽3 e 𝛽4). De forma ilustrativa, temos:
Então, para o intercepto, fazemos:
[IN]
# para vermos o valor do intercepto, fazemos
modelo.intercept_[OUT]
5951.9763393124485
Para os coeficientes angulares, fazemos:
[IN]
# observando os valores do coeficientes angulares
# [coeficiente de temp_max, coeficiente de chuva, coeficiente de fds],
# respectivamente
modelo.coef_[OUT]
array([ 684.73675898, -60.7824355 , 5401.08333866])
Dessa forma, temos:
E a nossa equação da reta de regressão linear estimada fica:
Mas o que significam esses valores?
Aqui, deixo a explicação que o curso da Alura descreve e que acredito que está bem clara.
Dessa forma, a partir da análise dos coeficientes, podemos formular que:
Independentemente da temperatura máxima, de quanto chove ou se é final de semana ou não, haverá um consumo médio de 5951,98 litros de cerveja. Além disso, chover realmente contribui para um menor consumo de cerveja e o fato de ser final de semana ou não, impacta consideravelmente o consumo de cerveja (uma diferença de 5401,08 entre ser ou não final de semana).
O que tem daqui para frente?
Muito bem, acredito que até aqui já temos um ótimo conteúdo para debruçarmos em cima e começarmos a aplicar os conceitos e ferramentas aprendidas em outros datasets e contextos.
O curso Regressão Linear: Testando Relações e Prevendo Resultados oferecido pela Alura ainda aborda os seguintes tópicos:
- Análise gráfica das previsões do modelo, onde exploramos o termo de erro (ui) e fazemos uma análise de dispersão e distribuição dele para classificarmos se o nosso modelo está bom ou ruim.
- Comparação de modelos, onde estimamos outro modelo considerando outro conjuntos de variáveis explicativas e avaliamos qual consegue estimar melhor o valor da variável dependente.
- Criação de um simulador simples que importa o nosso modelo que foi exportado para um arquivo.
Caso você se interesse em se aprofundar mais no assunto e explorar esses tópicos acima, recomendo que você se inscreva nos cursos da Alura e inicie seus estudos na Formação Cientista de Dados! 😄
É isso aí! Muito obrigado e até a próxima!