Análise Estatística com Statsmodels¶

Problema de Negócio:

Existe alguma relação entre a área de imóveis (em metros quadrados) e o valor do aluguel em uma determinada cidade? Caso exista relação, como podemos mensurá-la?

In [ ]:
# Imports
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import statsmodels.api as sm

Carregando os Dados¶

In [ ]:
url = "https://raw.githubusercontent.com/jeferson-paz/Analise-Estatistica-com-Statsmodels/main/dataset.csv"
In [ ]:
# Carrega o dataset
df_JP = pd.read_csv(url)
In [ ]:
df_JP.shape
Out[ ]:
(3000, 7)
In [ ]:
df_JP.columns
Out[ ]:
Index(['valor_aluguel', 'area_m2', 'ano_construcao', 'codigo_localidade',
       'numero_banheiros', 'numero_cozinhas', 'codigo_bairro'],
      dtype='object')
In [ ]:
df_JP.head()
Out[ ]:
valor_aluguel area_m2 ano_construcao codigo_localidade numero_banheiros numero_cozinhas codigo_bairro
0 120.97436 35 1939 1 0 0 1112
1 436.97433 104 1939 1 1 0 1112
2 355.74360 29 1971 2 0 0 2114
3 282.92310 39 1972 2 0 0 2148
4 807.23080 97 1985 1 0 0 2222
In [ ]:
df_JP.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3000 entries, 0 to 2999
Data columns (total 7 columns):
 #   Column             Non-Null Count  Dtype  
---  ------             --------------  -----  
 0   valor_aluguel      3000 non-null   float64
 1   area_m2            3000 non-null   int64  
 2   ano_construcao     3000 non-null   int64  
 3   codigo_localidade  3000 non-null   int64  
 4   numero_banheiros   3000 non-null   int64  
 5   numero_cozinhas    3000 non-null   int64  
 6   codigo_bairro      3000 non-null   int64  
dtypes: float64(1), int64(6)
memory usage: 164.2 KB

Análise Exploratória - Resumo Estatístico¶

In [ ]:
# Verifica se há valores ausentes
df_JP.isnull().sum()
Out[ ]:
valor_aluguel        0
area_m2              0
ano_construcao       0
codigo_localidade    0
numero_banheiros     0
numero_cozinhas      0
codigo_bairro        0
dtype: int64
In [ ]:
# Resumo estatístico do dataset - ATENÇÃO
df_JP.describe()
Out[ ]:
valor_aluguel area_m2 ano_construcao codigo_localidade numero_banheiros numero_cozinhas codigo_bairro
count 3000.000000 3000.000000 3000.000000 3000.000000 3000.000000 3000.000000 3000.000000
mean 459.643146 67.363333 1956.321333 1.441000 0.061333 0.042000 1173.798667
std 195.865692 23.675758 22.288136 0.545238 0.239981 0.200623 678.187690
min 40.512820 20.000000 1918.000000 1.000000 0.000000 0.000000 113.000000
25% 320.961530 51.000000 1939.000000 1.000000 0.000000 0.000000 561.750000
50% 426.897435 65.000000 1959.000000 1.000000 0.000000 0.000000 1025.000000
75% 560.282055 81.000000 1972.000000 2.000000 0.000000 0.000000 1714.000000
max 1843.384600 160.000000 1997.000000 3.000000 1.000000 1.000000 2529.000000
In [ ]:
# Resumo estatístico da variável alvo
df_JP["valor_aluguel"].describe()
Out[ ]:
count    3000.000000
mean      459.643146
std       195.865692
min        40.512820
25%       320.961530
50%       426.897435
75%       560.282055
max      1843.384600
Name: valor_aluguel, dtype: float64
In [ ]:
# Histograma da variável alvo
sns.histplot(data = df_JP, x = "valor_aluguel", kde = True)
C:\Users\pazj8\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\seaborn\_oldcore.py:1119: FutureWarning: use_inf_as_na option is deprecated and will be removed in a future version. Convert inf values to NaN before operating instead.
  with pd.option_context('mode.use_inf_as_na', True):
Out[ ]:
<Axes: xlabel='valor_aluguel', ylabel='Count'>
No description has been provided for this image
In [ ]:
# Correlação entre as variáveis
df_JP.corr()
Out[ ]:
valor_aluguel area_m2 ano_construcao codigo_localidade numero_banheiros numero_cozinhas codigo_bairro
valor_aluguel 1.000000 0.584878 0.139194 0.172368 0.250261 0.170707 -0.020846
area_m2 0.584878 1.000000 -0.226581 0.110046 0.226306 0.045716 -0.089050
ano_construcao 0.139194 -0.226581 1.000000 -0.152206 0.065824 0.109881 0.327983
codigo_localidade 0.172368 0.110046 -0.152206 1.000000 0.037858 -0.004774 -0.282528
numero_banheiros 0.250261 0.226306 0.065824 0.037858 1.000000 0.064216 0.043600
numero_cozinhas 0.170707 0.045716 0.109881 -0.004774 0.064216 1.000000 0.029495
codigo_bairro -0.020846 -0.089050 0.327983 -0.282528 0.043600 0.029495 1.000000
In [ ]:
# Vamos analisar a relação entre a variável de entrada area_m2 e a variável alvo valor_aluguel
sns.scatterplot(data = df_JP, x = "area_m2", y = "valor_aluguel")
Out[ ]:
<Axes: xlabel='area_m2', ylabel='valor_aluguel'>
No description has been provided for this image

Construção do Modelo OLS (Ordinary Least Squares) com Statsmodels em Python¶

In [ ]:
df_JP.head()
Out[ ]:
valor_aluguel area_m2 ano_construcao codigo_localidade numero_banheiros numero_cozinhas codigo_bairro
0 120.97436 35 1939 1 0 0 1112
1 436.97433 104 1939 1 1 0 1112
2 355.74360 29 1971 2 0 0 2114
3 282.92310 39 1972 2 0 0 2148
4 807.23080 97 1985 1 0 0 2222
In [ ]:
# Definimos a variável dependente
y = df_JP["valor_aluguel"]
In [ ]:
# Definimos a variável independente
X = df_JP["area_m2"]
In [ ]:
# O Statsmodels requer a adição de uma constante à variável independente
X = sm.add_constant(X)
In [ ]:
# Criamos o modelo
modelo = sm.OLS(y, X)
In [ ]:
# Treinamento do modelo
resultado = modelo.fit()
In [ ]:
print(resultado.summary())
                            OLS Regression Results                            
==============================================================================
Dep. Variable:          valor_aluguel   R-squared:                       0.342
Model:                            OLS   Adj. R-squared:                  0.342
Method:                 Least Squares   F-statistic:                     1559.
Date:                Fri, 09 Aug 2024   Prob (F-statistic):          6.84e-275
Time:                        14:09:40   Log-Likelihood:                -19461.
No. Observations:                3000   AIC:                         3.893e+04
Df Residuals:                    2998   BIC:                         3.894e+04
Df Model:                           1                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
const        133.6988      8.750     15.279      0.000     116.541     150.856
area_m2        4.8386      0.123     39.482      0.000       4.598       5.079
==============================================================================
Omnibus:                      206.173   Durbin-Watson:                   2.003
Prob(Omnibus):                  0.000   Jarque-Bera (JB):              441.379
Skew:                           0.448   Prob(JB):                     1.43e-96
Kurtosis:                       4.651   Cond. No.                         215.
==============================================================================

Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
In [ ]:
# Plot
plt.figure(figsize = (12, 8))
plt.xlabel("area_m2", size = 16)
plt.ylabel("valor_aluguel", size = 16)
plt.plot(X["area_m2"], y, "o", label = "Dados Reais")
plt.plot(X["area_m2"], resultado.fittedvalues, "r-", label = "Linha de Regressão (Previsões do Modelo)")
plt.legend(loc = "best")
plt.show()
No description has been provided for this image

Conclusão¶

Claramente existe uma forte relação entre a área (em m2) dos imóveis e o valor do aluguel. Entretanto, apenas a área dos imóveis não é suficiente para explicar a variação no valor do aluguel, pois nosso modelo obteve um coeficiente de determinação (R²) de apenas 0.34.

O ideal seria usar mais variáveis de entrada para construir o modelo a fim de compreender se outros fatores influenciam no valor do aluguel.

É sempre importante deixar claro que correlação não implica causalidade e que não podemos afirmar que o valor do aluguel muda apenas devido à área dos imóveis. Para estudar causalidade devemos aplicar Análise Causal.