UNB logo

Programa de Pós-graduação em Computação Aplicada – PPCA (UnB)

Análise Estatística de Dados e Informações

Professor: João Gabriel de Moraes Souza
Aluno: Angelo Donizete Buso Júnior

Técnicas Estatisicas - ANOVA Aplicadas ao mercado Imobiliário

A estatística aplicada ao mercado imobiliário desempenha um papel fundamental na análise e compreensão dos fatores que influenciam os preços das propriedades. Por meio de técnicas como validação de pressupostos e testes de hipótese, é possível identificar relações significativas entre variáveis como localização, qualidade construtiva e características físicas das propriedades.

Uma dessas ferramentas é o uso da Análise de Variância (ANOVA), permite avaliar avaliar se há diferenças significativas nos preços médios entre grupos categorizados, como bairros ou níveis de qualidade. Contudo, a aplicação do ANOVA requer o cumprimento de pressupostos de normalidade e homogeneidade das variâncias, essenciais para garantir a validade dos resultados. Se tais pressupostos são violados, a análise é complementada por técnicas não paramétricas, permitindo insights robustos sobre a influência de diferentes características no mercado imobiliário.

Problemática a ser resolvida

O presente estudo tem como objetivo procurar responder, com base em evidencia estatística, à seguinte pergunta: "Selecionado algumas características, estas afetam significativamente o preço médio de venda das propriedades?".

E como pergunta alternativa responder ao marketing "É possível realizar uma estratégia de preços única, sem comprometer a percepção de valor no mercado?"

Para alcançar o objetivo, seguimos as etapas abaixo:

Metodologia

1. Exploração Inicial dos Dados

Foi realizada uma análise exploratória para compreender a distribuição de SalePrice e a relação com as três variáveis selecionadas. Identificamos que os dados de SalePrice apresentavam assimetria positiva, indicando a possibilidade de comportamento não linear.

2. Teste ANOVA Tradicional

A ANOVA é uma técnica estatística que avalia se há diferenças significativas entre as médias de grupos categóricos, como bairros ou níveis de qualidade. No entanto, para sua aplicação, é necessário que os dados atendam aos pressupostos de normalidade e homogeneidade de variâncias. Esses pressupostos são essenciais para a validade dos resultados.

3. Abordagem Não Paramétrica

Quando os pressupostos da ANOVA não são atendidos, utilizamos técnicas não paramétricas como o Teste de Kruskal-Wallis, que não requer normalidade nem homogeneidade das variâncias, sendo ideal para avaliar diferenças entre grupos categóricos em situações onde os dados não seguem distribuições normais.

4. Análise Post-Hoc

Após identificar diferenças significativas entre os grupos, foi aplicada a Análise Post-Hoc por meio do Teste de Dunn. Este teste avalia comparações par a par entre os grupos, ajustando os valores-p para múltiplas comparações, destacando quais grupos específicos possuem diferenças significativas.

5. Visualizações

Gráficos como violinos e mapas de calor foram utilizados para ilustrar as distribuições de SalePrice e evidenciar as comparações significativas entre os grupos. Essas visualizações complementam a análise ao destacar tendências e padrões nos dados.

Para Virgillito (2017), o teste ANOVA é uma ferramenta estatística fundamental para avaliar a significância estatística entre grupos. Ele permite verificar se duas ou mais populações apresentam médias significativamente diferentes, utilizando amostras extraídas dessas populações. Em sua explicação, o autor destaca que, "para se comparar o afastamento entre as médias, recorre-se ao conceito de desvio-padrão de cada amostra, o qual, elevado ao quadrado, resulta na variância" (VIRGILLITO, 2017, p. 627). Assim, a análise da variância avalia as diferenças entre as médias por meio do comportamento da variância.

De forma prática, o teste ANOVA é amplamente aplicado em diversas áreas, como pesquisas médicas, produtividade agrícola e até mesmo em estudos de desempenho no marketing. Conforme Virgillito (2017), ele pode ser usado em situações como "a comparação entre a produtividade de dois tipos de grão cultivados com dois tipos de adubo (ANOVA de dois fatores)" ou "a comparação de desempenho de equipes em termos de produtividade e incentivos" (VIRGILLITO, 2017, p. 627).

Além disso, o autor ressalta que, enquanto outros testes comparam apenas duas amostras, o ANOVA "é mais abrangente, visto que pode comparar mais de duas amostras e testar se há ou não igualdade entre as médias das populações das quais elas foram retiradas" (VIRGILLITO, 2017, p. 627). Por isso, é uma técnica essencial em análises multigrupos, tanto com uma variável dependente (ANOVA) quanto com mais de uma variável dependente (MANOVA).

In [1]:
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import f_oneway, shapiro, levene, kruskal, skew, mannwhitneyu
import warnings
import statsmodels.api as sm
from statsmodels.formula.api import ols
import ace_tools_open as tools
import scikit_posthocs as sp


sns.set_theme(style="whitegrid")
plt.rc("figure", figsize=(10, 6))


warnings.filterwarnings('ignore')

Coleta de dados

Os dados utilizados nesta análise foram obtidos do repositório público Ames Housing Dataset, disponível na plataforma Kaggle. Contém informações detalhadas sobre propriedades residenciais em Ames, Iowa, incluindo variáveis como localização, qualidade geral e características físicas das propriedades.

In [2]:
try:
    df = pd.read_csv("/home/buso/mestrado/aedi-ppca/dados/AmesHousing.csv")
except FileNotFoundError:
    print("Arquivo não encontrado. Por favor, verifique o caminho do dataset.")

Dicionário de Dados

Documento ou estrutura que descreve detalhadamente cada variável presente em um conjunto de dados

Nome da Variável Descrição
SalePricePreço de venda da propriedade em dólares. Esta é a variável alvo que se tenta prever.
MSSubClassClasse do edifício.
MSZoningClassificação geral de zoneamento.
LotFrontagePés lineares de rua conectados à propriedade.
LotAreaTamanho do lote em pés quadrados.
StreetTipo de acesso à estrada.
AlleyTipo de acesso à viela.
LotShapeFormato geral da propriedade.
LandContourPlanura da propriedade.
UtilitiesTipo de utilidades disponíveis.
LotConfigConfiguração do lote.
LandSlopeDeclive da propriedade.
NeighborhoodLocalização física dentro dos limites da cidade de Ames.
Condition1Proximidade a rodovias principais ou ferrovias.
Condition2Proximidade a rodovias principais ou ferrovias (se houver uma segunda).
BldgTypeTipo de habitação.
HouseStyleEstilo da habitação.
OverallQualQualidade geral do material e acabamento.
OverallCondClassificação geral do estado de conservação.
YearBuiltAno de construção original.
YearRemodAddAno de reforma.
RoofStyleTipo de telhado.
RoofMatlMaterial do telhado.
Exterior1stRevestimento exterior principal da casa.
Exterior2ndRevestimento exterior secundário da casa (se houver mais de um material).
MasVnrTypeTipo de revestimento de alvenaria.
MasVnrAreaÁrea de revestimento de alvenaria em pés quadrados.
ExterQualQualidade do material exterior.
ExterCondCondição atual do material no exterior.
FoundationTipo de fundação.
BsmtQualAltura do porão.
BsmtCondCondição geral do porão.
BsmtExposureParedes do porão com saída para o jardim ou nível inferior.
BsmtFinType1Qualidade da área finalizada do porão.
BsmtFinSF1Pés quadrados finalizados do tipo 1.
BsmtFinType2Qualidade da segunda área finalizada do porão (se houver).
BsmtFinSF2Pés quadrados finalizados do tipo 2.
BsmtUnfSFPés quadrados não finalizados do porão.
TotalBsmtSFÁrea total do porão em pés quadrados.
HeatingTipo de aquecimento.
HeatingQCQualidade e condição do aquecimento.
CentralAirAr condicionado central.
ElectricalSistema elétrico.
1stFlrSFÁrea do primeiro andar em pés quadrados.
2ndFlrSFÁrea do segundo andar em pés quadrados.
LowQualFinSFÁrea finalizada de baixa qualidade (todos os andares).
GrLivAreaÁrea habitável acima do nível do solo em pés quadrados.
BsmtFullBathBanheiros completos no porão.
BsmtHalfBathMeio banheiro no porão.
FullBathBanheiros completos acima do nível do solo.
HalfBathMeio banheiro acima do nível do solo.
BedroomNúmero de quartos acima do nível do porão.
KitchenNúmero de cozinhas.
KitchenQualQualidade da cozinha.
TotRmsAbvGrdTotal de cômodos acima do nível do solo (não inclui banheiros).
FunctionalAvaliação da funcionalidade da casa.
FireplacesNúmero de lareiras.
FireplaceQuQualidade da lareira.
GarageTypeLocalização da garagem.
GarageYrBltAno de construção da garagem.
GarageFinishAcabamento interior da garagem.
GarageCarsTamanho da garagem em capacidade de carros.
GarageAreaTamanho da garagem em pés quadrados.
GarageQualQualidade da garagem.
GarageCondCondição da garagem.
PavedDriveEntrada pavimentada.
WoodDeckSFÁrea do deck de madeira em pés quadrados.
OpenPorchSFÁrea de varanda aberta em pés quadrados.
EnclosedPorchÁrea de varanda fechada em pés quadrados.
3SsnPorchÁrea de varanda de três estações em pés quadrados.
ScreenPorchÁrea de varanda com tela em pés quadrados.
PoolAreaÁrea da piscina em pés quadrados.
PoolQCQualidade da piscina.
FenceQualidade da cerca.
MiscFeatureCaracterísticas diversas não incluídas em outras categorias.
MiscValValor ($) de características diversas.
MoSoldMês de venda.
YrSoldAno de venda.
SaleTypeTipo de venda.
SaleConditionCondição de venda.

Análise Exploratória de Dados (EDA)

Uma etapa fundamental no processo de análise estatística e ciência de dados. Seu objetivo é compreender as características principais do conjunto de dados, identificar padrões, verificar anomalias e resumir as relações entre variáveis. Durante a EDA, utilizam-se métodos estatísticos descritivos e visualizações gráficas, como histogramas, boxplots e gráficos de dispersão, para obter insights iniciais que guiam as etapas subsequentes de modelagem e tomada de decisão. Essa abordagem permite não apenas detectar problemas nos dados, como valores ausentes ou inconsistências, mas também revelar tendências e correlações que podem impactar diretamente os resultados da análise.

In [3]:
print(f"Dimensões dos dados: com {df.shape[1]} features e {df.shape[0]} linhas!")
Dimensões dos dados: com 82 features e 2930 linhas!
In [4]:
print("\nPrimeiras 5 linhas dos dados:")
df.head()
Primeiras 5 linhas dos dados:
Out[4]:
Order PID MS SubClass MS Zoning Lot Frontage Lot Area Street Alley Lot Shape Land Contour ... Pool Area Pool QC Fence Misc Feature Misc Val Mo Sold Yr Sold Sale Type Sale Condition SalePrice
0 1 526301100 20 RL 141.0 31770 Pave NaN IR1 Lvl ... 0 NaN NaN NaN 0 5 2010 WD Normal 215000
1 2 526350040 20 RH 80.0 11622 Pave NaN Reg Lvl ... 0 NaN MnPrv NaN 0 6 2010 WD Normal 105000
2 3 526351010 20 RL 81.0 14267 Pave NaN IR1 Lvl ... 0 NaN NaN Gar2 12500 6 2010 WD Normal 172000
3 4 526353030 20 RL 93.0 11160 Pave NaN Reg Lvl ... 0 NaN NaN NaN 0 4 2010 WD Normal 244000
4 5 527105010 60 RL 74.0 13830 Pave NaN IR1 Lvl ... 0 NaN MnPrv NaN 0 3 2010 WD Normal 189900

5 rows × 82 columns

In [5]:
print("\nInformações gerais sobre os dados:")
print(df.info())
Informações gerais sobre os dados:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2930 entries, 0 to 2929
Data columns (total 82 columns):
 #   Column           Non-Null Count  Dtype  
---  ------           --------------  -----  
 0   Order            2930 non-null   int64  
 1   PID              2930 non-null   int64  
 2   MS SubClass      2930 non-null   int64  
 3   MS Zoning        2930 non-null   object 
 4   Lot Frontage     2440 non-null   float64
 5   Lot Area         2930 non-null   int64  
 6   Street           2930 non-null   object 
 7   Alley            198 non-null    object 
 8   Lot Shape        2930 non-null   object 
 9   Land Contour     2930 non-null   object 
 10  Utilities        2930 non-null   object 
 11  Lot Config       2930 non-null   object 
 12  Land Slope       2930 non-null   object 
 13  Neighborhood     2930 non-null   object 
 14  Condition 1      2930 non-null   object 
 15  Condition 2      2930 non-null   object 
 16  Bldg Type        2930 non-null   object 
 17  House Style      2930 non-null   object 
 18  Overall Qual     2930 non-null   int64  
 19  Overall Cond     2930 non-null   int64  
 20  Year Built       2930 non-null   int64  
 21  Year Remod/Add   2930 non-null   int64  
 22  Roof Style       2930 non-null   object 
 23  Roof Matl        2930 non-null   object 
 24  Exterior 1st     2930 non-null   object 
 25  Exterior 2nd     2930 non-null   object 
 26  Mas Vnr Type     1155 non-null   object 
 27  Mas Vnr Area     2907 non-null   float64
 28  Exter Qual       2930 non-null   object 
 29  Exter Cond       2930 non-null   object 
 30  Foundation       2930 non-null   object 
 31  Bsmt Qual        2850 non-null   object 
 32  Bsmt Cond        2850 non-null   object 
 33  Bsmt Exposure    2847 non-null   object 
 34  BsmtFin Type 1   2850 non-null   object 
 35  BsmtFin SF 1     2929 non-null   float64
 36  BsmtFin Type 2   2849 non-null   object 
 37  BsmtFin SF 2     2929 non-null   float64
 38  Bsmt Unf SF      2929 non-null   float64
 39  Total Bsmt SF    2929 non-null   float64
 40  Heating          2930 non-null   object 
 41  Heating QC       2930 non-null   object 
 42  Central Air      2930 non-null   object 
 43  Electrical       2929 non-null   object 
 44  1st Flr SF       2930 non-null   int64  
 45  2nd Flr SF       2930 non-null   int64  
 46  Low Qual Fin SF  2930 non-null   int64  
 47  Gr Liv Area      2930 non-null   int64  
 48  Bsmt Full Bath   2928 non-null   float64
 49  Bsmt Half Bath   2928 non-null   float64
 50  Full Bath        2930 non-null   int64  
 51  Half Bath        2930 non-null   int64  
 52  Bedroom AbvGr    2930 non-null   int64  
 53  Kitchen AbvGr    2930 non-null   int64  
 54  Kitchen Qual     2930 non-null   object 
 55  TotRms AbvGrd    2930 non-null   int64  
 56  Functional       2930 non-null   object 
 57  Fireplaces       2930 non-null   int64  
 58  Fireplace Qu     1508 non-null   object 
 59  Garage Type      2773 non-null   object 
 60  Garage Yr Blt    2771 non-null   float64
 61  Garage Finish    2771 non-null   object 
 62  Garage Cars      2929 non-null   float64
 63  Garage Area      2929 non-null   float64
 64  Garage Qual      2771 non-null   object 
 65  Garage Cond      2771 non-null   object 
 66  Paved Drive      2930 non-null   object 
 67  Wood Deck SF     2930 non-null   int64  
 68  Open Porch SF    2930 non-null   int64  
 69  Enclosed Porch   2930 non-null   int64  
 70  3Ssn Porch       2930 non-null   int64  
 71  Screen Porch     2930 non-null   int64  
 72  Pool Area        2930 non-null   int64  
 73  Pool QC          13 non-null     object 
 74  Fence            572 non-null    object 
 75  Misc Feature     106 non-null    object 
 76  Misc Val         2930 non-null   int64  
 77  Mo Sold          2930 non-null   int64  
 78  Yr Sold          2930 non-null   int64  
 79  Sale Type        2930 non-null   object 
 80  Sale Condition   2930 non-null   object 
 81  SalePrice        2930 non-null   int64  
dtypes: float64(11), int64(28), object(43)
memory usage: 1.8+ MB
None
In [6]:
print("\nResumo de valores ausentes por coluna:")
missing_data = df.isnull().sum()
missing_data = missing_data[missing_data > 0].sort_values(ascending=False)
print(missing_data)
Resumo de valores ausentes por coluna:
Pool QC           2917
Misc Feature      2824
Alley             2732
Fence             2358
Mas Vnr Type      1775
Fireplace Qu      1422
Lot Frontage       490
Garage Qual        159
Garage Cond        159
Garage Yr Blt      159
Garage Finish      159
Garage Type        157
Bsmt Exposure       83
BsmtFin Type 2      81
Bsmt Cond           80
Bsmt Qual           80
BsmtFin Type 1      80
Mas Vnr Area        23
Bsmt Full Bath       2
Bsmt Half Bath       2
BsmtFin SF 1         1
BsmtFin SF 2         1
Electrical           1
Total Bsmt SF        1
Bsmt Unf SF          1
Garage Area          1
Garage Cars          1
dtype: int64
In [7]:
if not missing_data.empty:
    plt.figure(figsize=(12, 6))
    sns.barplot(x=missing_data.index, y=missing_data.values)
    plt.title("Valores Ausentes por Variável")
    plt.ylabel("Quantidade de Valores Ausentes")
    plt.xticks(rotation=45)
    plt.show()
else:
    print("Nenhum valor ausente encontrado.")
No description has been provided for this image
In [8]:
print("\nEstatísticas descritivas das variáveis numéricas:")
print(df.describe().transpose())
Estatísticas descritivas das variáveis numéricas:
                  count          mean           std          min  \
Order            2930.0  1.465500e+03  8.459625e+02          1.0   
PID              2930.0  7.144645e+08  1.887308e+08  526301100.0   
MS SubClass      2930.0  5.738737e+01  4.263802e+01         20.0   
Lot Frontage     2440.0  6.922459e+01  2.336533e+01         21.0   
Lot Area         2930.0  1.014792e+04  7.880018e+03       1300.0   
Overall Qual     2930.0  6.094881e+00  1.411026e+00          1.0   
Overall Cond     2930.0  5.563140e+00  1.111537e+00          1.0   
Year Built       2930.0  1.971356e+03  3.024536e+01       1872.0   
Year Remod/Add   2930.0  1.984267e+03  2.086029e+01       1950.0   
Mas Vnr Area     2907.0  1.018968e+02  1.791126e+02          0.0   
BsmtFin SF 1     2929.0  4.426296e+02  4.555908e+02          0.0   
BsmtFin SF 2     2929.0  4.972243e+01  1.691685e+02          0.0   
Bsmt Unf SF      2929.0  5.592625e+02  4.394942e+02          0.0   
Total Bsmt SF    2929.0  1.051615e+03  4.406151e+02          0.0   
1st Flr SF       2930.0  1.159558e+03  3.918909e+02        334.0   
2nd Flr SF       2930.0  3.354560e+02  4.283957e+02          0.0   
Low Qual Fin SF  2930.0  4.676792e+00  4.631051e+01          0.0   
Gr Liv Area      2930.0  1.499690e+03  5.055089e+02        334.0   
Bsmt Full Bath   2928.0  4.313525e-01  5.248202e-01          0.0   
Bsmt Half Bath   2928.0  6.113388e-02  2.452536e-01          0.0   
Full Bath        2930.0  1.566553e+00  5.529406e-01          0.0   
Half Bath        2930.0  3.795222e-01  5.026293e-01          0.0   
Bedroom AbvGr    2930.0  2.854266e+00  8.277311e-01          0.0   
Kitchen AbvGr    2930.0  1.044369e+00  2.140762e-01          0.0   
TotRms AbvGrd    2930.0  6.443003e+00  1.572964e+00          2.0   
Fireplaces       2930.0  5.993174e-01  6.479209e-01          0.0   
Garage Yr Blt    2771.0  1.978132e+03  2.552841e+01       1895.0   
Garage Cars      2929.0  1.766815e+00  7.605664e-01          0.0   
Garage Area      2929.0  4.728197e+02  2.150465e+02          0.0   
Wood Deck SF     2930.0  9.375188e+01  1.263616e+02          0.0   
Open Porch SF    2930.0  4.753345e+01  6.748340e+01          0.0   
Enclosed Porch   2930.0  2.301160e+01  6.413906e+01          0.0   
3Ssn Porch       2930.0  2.592491e+00  2.514133e+01          0.0   
Screen Porch     2930.0  1.600205e+01  5.608737e+01          0.0   
Pool Area        2930.0  2.243345e+00  3.559718e+01          0.0   
Misc Val         2930.0  5.063515e+01  5.663443e+02          0.0   
Mo Sold          2930.0  6.216041e+00  2.714492e+00          1.0   
Yr Sold          2930.0  2.007790e+03  1.316613e+00       2006.0   
SalePrice        2930.0  1.807961e+05  7.988669e+04      12789.0   

                          25%          50%           75%           max  
Order            7.332500e+02       1465.5  2.197750e+03  2.930000e+03  
PID              5.284770e+08  535453620.0  9.071811e+08  1.007100e+09  
MS SubClass      2.000000e+01         50.0  7.000000e+01  1.900000e+02  
Lot Frontage     5.800000e+01         68.0  8.000000e+01  3.130000e+02  
Lot Area         7.440250e+03       9436.5  1.155525e+04  2.152450e+05  
Overall Qual     5.000000e+00          6.0  7.000000e+00  1.000000e+01  
Overall Cond     5.000000e+00          5.0  6.000000e+00  9.000000e+00  
Year Built       1.954000e+03       1973.0  2.001000e+03  2.010000e+03  
Year Remod/Add   1.965000e+03       1993.0  2.004000e+03  2.010000e+03  
Mas Vnr Area     0.000000e+00          0.0  1.640000e+02  1.600000e+03  
BsmtFin SF 1     0.000000e+00        370.0  7.340000e+02  5.644000e+03  
BsmtFin SF 2     0.000000e+00          0.0  0.000000e+00  1.526000e+03  
Bsmt Unf SF      2.190000e+02        466.0  8.020000e+02  2.336000e+03  
Total Bsmt SF    7.930000e+02        990.0  1.302000e+03  6.110000e+03  
1st Flr SF       8.762500e+02       1084.0  1.384000e+03  5.095000e+03  
2nd Flr SF       0.000000e+00          0.0  7.037500e+02  2.065000e+03  
Low Qual Fin SF  0.000000e+00          0.0  0.000000e+00  1.064000e+03  
Gr Liv Area      1.126000e+03       1442.0  1.742750e+03  5.642000e+03  
Bsmt Full Bath   0.000000e+00          0.0  1.000000e+00  3.000000e+00  
Bsmt Half Bath   0.000000e+00          0.0  0.000000e+00  2.000000e+00  
Full Bath        1.000000e+00          2.0  2.000000e+00  4.000000e+00  
Half Bath        0.000000e+00          0.0  1.000000e+00  2.000000e+00  
Bedroom AbvGr    2.000000e+00          3.0  3.000000e+00  8.000000e+00  
Kitchen AbvGr    1.000000e+00          1.0  1.000000e+00  3.000000e+00  
TotRms AbvGrd    5.000000e+00          6.0  7.000000e+00  1.500000e+01  
Fireplaces       0.000000e+00          1.0  1.000000e+00  4.000000e+00  
Garage Yr Blt    1.960000e+03       1979.0  2.002000e+03  2.207000e+03  
Garage Cars      1.000000e+00          2.0  2.000000e+00  5.000000e+00  
Garage Area      3.200000e+02        480.0  5.760000e+02  1.488000e+03  
Wood Deck SF     0.000000e+00          0.0  1.680000e+02  1.424000e+03  
Open Porch SF    0.000000e+00         27.0  7.000000e+01  7.420000e+02  
Enclosed Porch   0.000000e+00          0.0  0.000000e+00  1.012000e+03  
3Ssn Porch       0.000000e+00          0.0  0.000000e+00  5.080000e+02  
Screen Porch     0.000000e+00          0.0  0.000000e+00  5.760000e+02  
Pool Area        0.000000e+00          0.0  0.000000e+00  8.000000e+02  
Misc Val         0.000000e+00          0.0  0.000000e+00  1.700000e+04  
Mo Sold          4.000000e+00          6.0  8.000000e+00  1.200000e+01  
Yr Sold          2.007000e+03       2008.0  2.009000e+03  2.010000e+03  
SalePrice        1.295000e+05     160000.0  2.135000e+05  7.550000e+05  

Na análise de dados, a identificação de variáveis categóricas é uma etapa essencial, pois essas variáveis representam dados qualitativos que são organizados em categorias ou grupos distintos. As variáveis categóricas podem ser analisadas para identificar padrões de frequência, diferenças entre grupos e sua relação com variáveis dependentes, como o preço de venda. Ferramentas como tabelas de contingência, gráficos de barras e análises de associação são frequentemente utilizadas para explorar essas variáveis e obter insights significativos no contexto da análise. E nem sempre podem estrar representadas em string!

In [9]:
categorical_cols = df.select_dtypes(include=['object']).columns
print("\nVariáveis categóricas:")
print(categorical_cols)
Variáveis categóricas:
Index(['MS Zoning', 'Street', 'Alley', 'Lot Shape', 'Land Contour',
       'Utilities', 'Lot Config', 'Land Slope', 'Neighborhood', 'Condition 1',
       'Condition 2', 'Bldg Type', 'House Style', 'Roof Style', 'Roof Matl',
       'Exterior 1st', 'Exterior 2nd', 'Mas Vnr Type', 'Exter Qual',
       'Exter Cond', 'Foundation', 'Bsmt Qual', 'Bsmt Cond', 'Bsmt Exposure',
       'BsmtFin Type 1', 'BsmtFin Type 2', 'Heating', 'Heating QC',
       'Central Air', 'Electrical', 'Kitchen Qual', 'Functional',
       'Fireplace Qu', 'Garage Type', 'Garage Finish', 'Garage Qual',
       'Garage Cond', 'Paved Drive', 'Pool QC', 'Fence', 'Misc Feature',
       'Sale Type', 'Sale Condition'],
      dtype='object')
In [10]:
df.nunique().sort_values()
Out[10]:
Street               2
Alley                2
Central Air          2
Land Slope           3
Bsmt Half Bath       3
                  ... 
Bsmt Unf SF       1137
Gr Liv Area       1292
Lot Area          1960
Order             2930
PID               2930
Length: 82, dtype: int64
In [11]:
valores_unicos = df.nunique()
possiveis_categoricas = valores_unicos[valores_unicos <= 30]
print("Possíveis variáveis categóricas:")
print(possiveis_categoricas)
Possíveis variáveis categóricas:
MS SubClass       16
MS Zoning          7
Street             2
Alley              2
Lot Shape          4
Land Contour       4
Utilities          3
Lot Config         5
Land Slope         3
Neighborhood      28
Condition 1        9
Condition 2        8
Bldg Type          5
House Style        8
Overall Qual      10
Overall Cond       9
Roof Style         6
Roof Matl          8
Exterior 1st      16
Exterior 2nd      17
Mas Vnr Type       4
Exter Qual         4
Exter Cond         5
Foundation         6
Bsmt Qual          5
Bsmt Cond          5
Bsmt Exposure      4
BsmtFin Type 1     6
BsmtFin Type 2     6
Heating            6
Heating QC         5
Central Air        2
Electrical         5
Bsmt Full Bath     4
Bsmt Half Bath     3
Full Bath          5
Half Bath          3
Bedroom AbvGr      8
Kitchen AbvGr      4
Kitchen Qual       5
TotRms AbvGrd     14
Functional         8
Fireplaces         5
Fireplace Qu       5
Garage Type        6
Garage Finish      3
Garage Cars        6
Garage Qual        5
Garage Cond        5
Paved Drive        3
Pool Area         14
Pool QC            4
Fence              4
Misc Feature       5
Mo Sold           12
Yr Sold            5
Sale Type         10
Sale Condition     6
dtype: int64
Análise Univariada

A análise univariada da variável SalePrice (preço de venda) foca na compreensão de sua distribuição e principais características estatísticas, como média, mediana, desvio padrão e assimetria. Essa análise permite identificar a tendência central, dispersão e possíveis outliers no conjunto de dados. Além disso, visualizações como histogramas e boxplots são ferramentas úteis para observar o comportamento da variável, revelando padrões, assimetrias ou concentrações que podem influenciar diretamente na modelagem e interpretação dos resultados.

In [12]:
plt.figure(figsize=(10, 6))
sns.histplot(df["SalePrice"], kde=True, color="blue", bins=30)
plt.xlabel("Preço de Venda (SalePrice)")
plt.ylabel("Frequência")
plt.title('Distribuição do Preço de Venda')
plt.show()
No description has been provided for this image
In [13]:
print(df["SalePrice"].describe())
print(df["SalePrice"].quantile([0.95]))
count      2930.000000
mean     180796.060068
std       79886.692357
min       12789.000000
25%      129500.000000
50%      160000.000000
75%      213500.000000
max      755000.000000
Name: SalePrice, dtype: float64
0.95    335000.0
Name: SalePrice, dtype: float64

A variável SalePrice apresenta uma distribuição assimétrica à direita, o que indica que a maioria das propriedades está concentrada em faixas de preços mais baixas. A maior parte dos preços está abaixo de 300.000 dólares, com um pico evidente na faixa entre 150.000 e 200.000 dólares. A análise da curva de densidade suavizada reforça essa assimetria, destacando a concentração de propriedades em preços menores. Além disso, a cauda longa no lado direito da distribuição revela a presença de algumas propriedades com preços excepcionalmente altos, que podem ser considerados outliers. Esses padrões são importantes para entender a dinâmica dos preços e orientar análises mais aprofundadas.

In [14]:
saleprice_skewness = skew(df["SalePrice"], bias=False)
print(f"Skewness de SalePrice: {saleprice_skewness}")
Skewness de SalePrice: 1.743500075737647

A interpretação do coeficiente de skewness (assimetria) é uma medida essencial para avaliar a simetria da distribuição de uma variável. Um valor positivo indica uma assimetria à direita, caracterizada por uma cauda mais longa no lado direito da distribuição, como observado nos gráficos da variável SalePrice. Um valor negativo indica uma assimetria à esquerda, onde a cauda mais longa está no lado esquerdo. Já valores próximos de 0 sugerem uma distribuição aproximadamente simétrica. Essa análise é fundamental para compreender a natureza da variável e suas implicações em modelos estatísticos ou preditivos.

In [15]:
plt.figure(figsize=(8, 6))
sns.boxplot(x=df["SalePrice"], color="orange")
plt.title("Boxplot de SalePrice para Identificação de Outliers")
plt.xlabel("Preço de Venda (SalePrice)")
plt.show()
No description has been provided for this image

A análise do gráfico de boxplot para a variável SalePrice destaca importantes características da distribuição dos dados. A linha dentro da caixa representa a mediana, que está em torno de 200.000 dólares, refletindo o preço central da maioria das propriedades. A maior parte dos dados está concentrada no intervalo interquartil (IQR), que varia aproximadamente entre 150.000 e 250.000 dólares, abrangendo cerca de 50% das observações. No entanto, uma análise baseada no princípio de Pareto revela que uma minoria das propriedades, representada por valores acima de 300.000 dólares, contribui de forma desproporcional para o valor total. Esses valores são identificados como outliers, indicados pelos pontos isolados no gráfico. Entre eles, um ou mais valores ultrapassam 700.000 dólares, reforçando a existência de propriedades de altíssimo valor que desviam significativamente da norma, o que pode influenciar análises estatísticas e preditivas.

Seleção de Variáveis para ANOVA

1. Neighborhood (Bairros)

Motivo da Escolha: A localização é um dos fatores mais importantes no mercado imobiliário, com bairros apresentando preços médios significativamente diferentes.

Níveis para ANOVA: Cada bairro é considerado um nível, permitindo comparações diretas entre eles.

2. OverallQual (Qualidade Geral dos Materiais e Acabamentos)

Motivo da Escolha: A qualidade dos materiais e acabamentos impacta diretamente o preço de venda. Propriedades de alta qualidade são geralmente mais valorizadas.

Níveis para ANOVA: Classificações de qualidade (de 1 a 10) fornecem grupos claros para análise.

3. GarageCars (Capacidade da Garagem em Carros)

Motivo da Escolha: O tamanho da garagem é um fator prático e valorizado pelos compradores. Garagens maiores tendem a influenciar positivamente o preço.

Níveis para ANOVA: O número de carros suportados (0, 1, 2, etc.) fornece uma divisão natural para comparação.

O pré-processamento dos dados foi realizado com base em dois aspectos principais: (i) devido à sensibilidade da técnica ANOVA de lidar com valores nulos e constatou que 1 registro contém dados falatantes, adotou-se a premissa de excluir todo o registro. É importante destacar que lidar com valores missing exige técnicas específicas e conhecimento do domínio do negócio para minimizar impactos na análise. (ii) Além disso, foi realizada a padronização dos rótulos das features selecionadas, removendo espaços nos nomes das variáveis para garantir consistência e facilitar o processamento posterior. Esses passos foram essenciais para preparar o conjunto de dados para a aplicação das técnicas estatísticas.

In [16]:
print(missing_data)
Pool QC           2917
Misc Feature      2824
Alley             2732
Fence             2358
Mas Vnr Type      1775
Fireplace Qu      1422
Lot Frontage       490
Garage Qual        159
Garage Cond        159
Garage Yr Blt      159
Garage Finish      159
Garage Type        157
Bsmt Exposure       83
BsmtFin Type 2      81
Bsmt Cond           80
Bsmt Qual           80
BsmtFin Type 1      80
Mas Vnr Area        23
Bsmt Full Bath       2
Bsmt Half Bath       2
BsmtFin SF 1         1
BsmtFin SF 2         1
Electrical           1
Total Bsmt SF        1
Bsmt Unf SF          1
Garage Area          1
Garage Cars          1
dtype: int64
In [17]:
feature_anova = ['Neighborhood', 'Garage Cars', 'Overall Qual', 'SalePrice']
df_anova = df[feature_anova]
df_anova.head()
Out[17]:
Neighborhood Garage Cars Overall Qual SalePrice
0 NAmes 2.0 6 215000
1 NAmes 1.0 5 105000
2 NAmes 1.0 6 172000
3 NAmes 2.0 7 244000
4 Gilbert 2.0 5 189900
In [18]:
df_anova.shape
Out[18]:
(2930, 4)
In [19]:
df_anova.dropna(axis=0, inplace=True)
In [20]:
df_anova.shape
Out[20]:
(2929, 4)
In [21]:
df_anova.columns
Out[21]:
Index(['Neighborhood', 'Garage Cars', 'Overall Qual', 'SalePrice'], dtype='object')
In [22]:
df_anova.rename(columns={'Garage Cars': 'GarageCars', 'Overall Qual':'OverallQual'}, inplace=True)
In [23]:
df_anova.head()
Out[23]:
Neighborhood GarageCars OverallQual SalePrice
0 NAmes 2.0 6 215000
1 NAmes 1.0 5 105000
2 NAmes 1.0 6 172000
3 NAmes 2.0 7 244000
4 Gilbert 2.0 5 189900
Neighborhood vs. SalePrice

Objetivo: Analisar como diferentes bairros influenciam o preço médio das propriedades.

Os bairros podem desempenhar um papel crucial na determinação do preço de venda das propriedades? Empiricamente, fatores como localização, infraestrutura, segurança e proximidade a serviços essenciais variam entre regiões, e se não tivermos de posse disso, como faremos?

Nesta análise, a variável Neighborhood será examinada em relação ao SalePrice, utilizando a ANOVA para identificar diferenças significativas entre os preços médios das propriedades nos diferentes bairros.

In [24]:
df_anova.groupby('Neighborhood')['SalePrice'].mean()
Out[24]:
Neighborhood
Blmngtn    196661.678571
Blueste    143590.000000
BrDale     105608.333333
BrkSide    124756.250000
ClearCr    208662.090909
CollgCr    201803.434457
Crawfor    207550.834951
Edwards    130843.381443
Gilbert    190646.575758
Greens     193531.250000
GrnHill    280000.000000
IDOTRR     103240.336957
Landmrk    137000.000000
MeadowV     95756.486486
Mitchel    162226.631579
NAmes      145097.349887
NPkVill    140710.869565
NWAmes     188406.908397
NoRidge    330319.126761
NridgHt    322018.265060
OldTown    123991.891213
SWISU      135071.937500
Sawyer     136751.152318
SawyerW    184070.184000
Somerst    229707.324176
StoneBr    324229.196078
Timber     246599.541667
Veenker    248314.583333
Name: SalePrice, dtype: float64
In [25]:
plt.figure(figsize=(12, 6))
sns.boxplot(data=df_anova, x='Neighborhood', y='SalePrice')
plt.xticks(rotation=45)
plt.title('Distribuição de SalePrice por Neighborhood')
plt.ylabel('Preço de Venda (SalePrice)')
plt.xlabel('Bairro (Neighborhood)')
plt.show()
No description has been provided for this image

A análise da relação entre Neighborhood e SalePrice revela padrões claros no impacto da localização sobre os preços das propriedades. Bairros como NridgHt e StoneBr possuem preços consistentemente altos, refletindo maior valorização e exclusividade, enquanto bairros como Edwards e BrDale apresentam preços médios mais baixos, indicando menor valorização imobiliária. A variabilidade de preços também varia entre os bairros: regiões como NAmes e Gilbert mostram ampla dispersão, incluindo outliers significativos, enquanto BrDale apresenta uma faixa de preços mais estreita. Esses resultados reforçam que o bairro é um forte indicador do preço das propriedades, com áreas de prestígio mostrando maior demanda e preços elevados.

OverallQual vs. SalePrice

Objetivo: Explorar como a qualidade geral dos materiais e acabamentos influencia o preço de venda.

A variável OverallQual mede a qualidade geral dos materiais e acabamentos de uma propriedade, com classificações que variam de 1 (qualidade muito baixa) a 10 (qualidade excelente). Essa característica tem um impacto direto no preço de venda, pois propriedades com materiais e acabamentos superiores geralmente são mais valorizadas. Faz sentido? vamos testar?

In [26]:
df_anova.groupby('OverallQual')['SalePrice'].mean()
Out[26]:
OverallQual
1      48725.000000
2      52325.307692
3      83185.975000
4     106485.097345
5     134732.908981
6     162130.318306
7     205025.760797
8     270913.594286
9     368336.766355
10    450217.322581
Name: SalePrice, dtype: float64
In [27]:
avg_price_quality = df_anova.groupby('OverallQual')['SalePrice'].mean().reset_index()
plt.figure(figsize=(8, 5))
sns.barplot(data=avg_price_quality, x='OverallQual', y='SalePrice')
plt.title('Média de SalePrice por Overall Qual')
plt.ylabel('Preço Médio de Venda (SalePrice)')
plt.xlabel('Qualidade Geral (Overall Qual)')
plt.show()
No description has been provided for this image

A análise de OverallQual mostra uma tendência crescente, onde o preço médio de venda (SalePrice) aumenta consistentemente com a qualidade geral. Casas com qualidade superior (níveis 9 e 10) apresentam preços médios significativamente mais altos, frequentemente acima de $400.000.

In [28]:
plt.figure(figsize=(8, 5))
sns.regplot(data=df_anova, x='OverallQual', y='SalePrice', scatter_kws={'alpha':0.6})
plt.title('Relação entre OverallQual e SalePrice')
plt.ylabel('Preço de Venda (SalePrice)')
plt.xlabel('Qualidade Geral (OverallQual)')
plt.show()
No description has been provided for this image

A análise de OverallQual revela uma correlação linear positiva com SalePrice, evidenciada pela linha de regressão ajustada. No entanto, há variabilidade dentro de cada nível de qualidade, indicando que outros fatores também influenciam o preço final.

GarageCars vs. SalePrice

Objetivo: Avaliar o impacto do tamanho da garagem no preço de venda.

A variável GarageCars representa a capacidade da garagem, medida pelo número de carros que ela pode acomodar.

In [29]:
df_anova.groupby('GarageCars')['SalePrice'].mean()
Out[29]:
GarageCars
0.0    104949.254777
1.0    127267.422879
2.0    183562.102932
3.0    310304.622995
4.0    228748.687500
5.0    126500.000000
Name: SalePrice, dtype: float64
In [30]:
avg_price_garage = df_anova.groupby('GarageCars')['SalePrice'].mean().reset_index()
plt.figure(figsize=(8, 5))
sns.barplot(data=avg_price_garage, x='GarageCars', y='SalePrice')
plt.title('Média de SalePrice por GarageCars')
plt.ylabel('Preço Médio de Venda (SalePrice)')
plt.xlabel('Capacidade da Garagem (GarageCars)')
plt.show()
No description has been provided for this image

A análise de GarageCars mostra que o preço médio de venda (SalePrice) aumenta com a capacidade da garagem, atingindo o pico em garagens para 3 carros (~$300.000), que são altamente valorizadas. No entanto, garagens maiores (4 ou mais carros) apresentam preços médios menores.

In [31]:
plt.figure(figsize=(8, 5))
sns.scatterplot(data=df_anova, x='GarageCars', y='SalePrice', alpha=0.6)
plt.title('Relação entre Garage Cars e SalePrice')
plt.ylabel('Preço de Venda (SalePrice)')
plt.xlabel('Capacidade da Garagem (Garage Cars)')
plt.show()
No description has been provided for this image

A análise de GarageCars indica uma correlação positiva entre a capacidade da garagem e o preço de venda (SalePrice), com propriedades maiores tendendo a preços mais altos. Capacidades de 0, 1 e 2 carros apresentam maior densidade de propriedades, enquanto garagens para 3 carros têm preços significativamente maiores, mas também mostram maior variabilidade, incluindo outliers. Garagens para 4 ou 5 carros são raras e algumas apresentam preços muito elevados, sugerindo influência de fatores adicionais, como localização ou qualidade geral.

ANOVA: Comparação de Preços Médios

Nesta etapa, aplica-se o teste de ANOVA para avaliar se há diferenças significativas nos preços de venda (SalePrice) em relação às três características selecionadas: Neighborhood, OverallQual, e GarageCars. Para cada variável, o teste de ANOVA compara as médias dos preços entre os grupos formados por suas categorias. O objetivo é identificar se a variação do preço médio pode ser explicada de forma estatisticamente significativa por essas características. Os valores-p resultantes para cada análise são armazenados em um dicionário consolidado para facilitar a revisão e interpretação dos resultados.

Princípios do ANOVA

Hipóteses:

  • H₀: Todas as médias dos grupos são iguais.
  • H₁: Pelo menos uma média de grupo é diferente.

Divisão da Variância: O ANOVA divide a variância total em duas partes:

  • Entre os grupos: Diferença nas médias dos grupos.
  • Dentro dos grupos: Variabilidade interna de cada grupo.
O teste utiliza a estatística F para avaliar a relação entre essas variâncias.

Resultado do Teste: O valor-p representa a probabilidade de que as diferenças observadas entre as médias sejam devido ao acaso. Se valor-p < 0.05, rejeitamos H₀, indicando diferenças significativas.

In [ ]:
anova_results = {}

anova_neighborhood = f_oneway(*[df_anova[df_anova['Neighborhood'] == n]['SalePrice'] for n in df_anova['Neighborhood'].unique()])
anova_results['Neighborhood'] = anova_neighborhood.pvalue

anova_overallqual = f_oneway(*[df_anova[df_anova['OverallQual'] == q]['SalePrice'] for q in df_anova['OverallQual'].unique()])
anova_results['Overall Qual'] = anova_overallqual.pvalue

anova_garagecars = f_oneway(*[df_anova[df_anova['GarageCars'] == g]['SalePrice'] for g in df_anova['GarageCars'].unique()])
anova_results['Garage Cars'] = anova_garagecars.pvalue

results = {"ANOVA Results (p-values)": anova_results}
tools.display_dataframe_to_user(name="Resultados de ANOVA e Validação de Pressupostos", dataframe=pd.DataFrame(results))
Resultados de ANOVA e Validação de Pressupostos
ANOVA Results (p-values)
Loading ITables v2.2.4 from the internet... (need help?)

Os resultados da ANOVA mostram que, para todas as variáveis analisadas (Neighborhood, OverallQual, e GarageCars), os valores-p foram iguais a 0, indicando diferenças significativas nos preços médios de venda. Conclui-se que a localização, a qualidade geral dos materiais e acabamentos, e o tamanho da garagem são fatores relevantes que impactam diretamente o preço de venda.

In [33]:
from statsmodels.formula.api import ols

# Melting the filtered data for analysis in the OLS model
melted_data_for_ols_Neighborhood = pd.melt(df_anova, id_vars=['Neighborhood'], value_vars=['SalePrice'])
# Ordinary Least Squares (OLS) model
model_Neighborhood = ols('value ~ Neighborhood', data=melted_data_for_ols_Neighborhood).fit()
# Performing ANOVA
anova_table_Neighborhood = sm.stats.anova_lm(model_Neighborhood, typ=2)

# Melting the filtered data for analysis in the OLS model
melted_data_for_ols_OverallQual = pd.melt(df_anova, id_vars=['OverallQual'], value_vars=['SalePrice'])
# Ordinary Least Squares (OLS) model
model_OverallQual = ols('value ~ OverallQual', data=melted_data_for_ols_OverallQual).fit()
# Performing ANOVA
anova_table_OverallQual = sm.stats.anova_lm(model_OverallQual, typ=2)

# Melting the filtered data for analysis in the OLS model
melted_data_for_ols_GarageCars = pd.melt(df_anova, id_vars=['GarageCars'], value_vars=['SalePrice'])
# Ordinary Least Squares (OLS) model
model_GarageCars = ols('value ~ GarageCars', data=melted_data_for_ols_GarageCars).fit()
# Performing ANOVA
anova_table_GarageCars = sm.stats.anova_lm(model_GarageCars, typ=2)
In [34]:
# Displaying the ANOVA table
anova_table_Neighborhood
Out[34]:
sum_sq df F PR(>F)
Neighborhood 1.071736e+13 27.0 144.404258 0.0
Residual 7.974285e+12 2901.0 NaN NaN
In [35]:
# Displaying the ANOVA table
anova_table_OverallQual
Out[35]:
sum_sq df F PR(>F)
OverallQual 1.194065e+13 1.0 5177.056079 0.0
Residual 6.750995e+12 2927.0 NaN NaN
In [36]:
# Displaying the ANOVA table
anova_table_GarageCars
Out[36]:
sum_sq df F PR(>F)
GarageCars 7.845707e+12 1.0 2117.325984 0.0
Residual 1.084594e+13 2927.0 NaN NaN

Validação de Pressupostos para Interpretação da ANOVA

Antes de interpretar os resultados do teste ANOVA tradicional, é essencial validar seus pressupostos. A ANOVA assume que os dados seguem uma distribuição normal em cada grupo e que as variâncias entre os grupos são homogêneas. A validação desses pressupostos é crucial para garantir a confiabilidade dos resultados e evitar conclusões equivocadas. Caso essas condições não sejam atendidas, métodos alternativos, como testes não paramétricos, devem ser considerados.

Teste de Normalidade

Objetivo: Verificar se os resíduos do modelo ANOVA seguem uma distribuição normal, conforme exigido pelo pressuposto da ANOVA tradicional.

Para testar a normalidade, utiliza-se o teste de Shapiro-Wilk, bem como visualizações como o histograma e o Q-Q Plot. Resíduos que não seguem uma distribuição normal podem comprometer a validade dos resultados da ANOVA. Desvios significativos, especialmente nas extremidades, indicam que o pressuposto de normalidade foi violado, sendo necessário considerar alternativas não paramétricas para fazer inferências.

In [37]:
shapiro_tests = {}
shapiro_tests['Neighborhood'] = shapiro(df_anova['SalePrice'])[1]
shapiro_tests['OverallQual'] = shapiro(df_anova['SalePrice'])[1]
shapiro_tests['GarageCars'] = shapiro(df_anova['SalePrice'])[1]

results = {
    "Normalidade (Shapiro-Wilk p-values)": shapiro_tests
}

tools.display_dataframe_to_user(name="Validação de Pressupostos", dataframe=pd.DataFrame(results))
Validação de Pressupostos
Normalidade (Shapiro-Wilk p-values)
Loading ITables v2.2.4 from the internet... (need help?)

Os p-valores extremamente baixos (2.408963e-43) indicam violação da normalidade dos resíduos.

Teste de Homogeneidade das Variâncias

Objetivo: Avaliar se as variâncias dos grupos são homogêneas, uma condição essencial para a aplicação da ANOVA tradicional.

O teste de Levene ou de Bartlett pode ser usado para verificar a homogeneidade das variâncias. No scatterplot de resíduos versus valores ajustados, padrões como aumento da variabilidade (padrão em funil) sugerem heterocedasticidade. A violação deste pressuposto pode impactar a confiabilidade das conclusões, indicando a necessidade de técnicas robustas ou ajustes nos dados.

In [38]:
levene_tests = {}
levene_tests['Neighborhood'] = levene(*[df_anova[df_anova['Neighborhood'] == n]['SalePrice'] for n in df_anova['Neighborhood'].unique()]).pvalue
levene_tests['OverallQual'] = levene(*[df_anova[df_anova['OverallQual'] == q]['SalePrice'] for q in df_anova['OverallQual'].unique()]).pvalue
levene_tests['GarageCars'] = levene(*[df_anova[df_anova['GarageCars'] == g]['SalePrice'] for g in df_anova['GarageCars'].unique()]).pvalue

results = {
    "Homogeneidade (Levene p-values)": levene_tests
}

tools.display_dataframe_to_user(name="Validação de Pressupostos", dataframe=pd.DataFrame(results))
Validação de Pressupostos
Homogeneidade (Levene p-values)
Loading ITables v2.2.4 from the internet... (need help?)

P-valores muito baixos para todas as características (Neighborhood, OverallQual, GarageCars), indicando que as variâncias entre os grupos não são homogêneas.

Teste dos Resíduos com ANOVA Tradicional

Objetivo: Verificar se os resíduos do modelo ANOVA tradicional atendem aos pressupostos de normalidade, homogeneidade de variâncias e independência.

Os resíduos do modelo são as diferenças entre os valores observados e as médias estimadas para cada grupo. Na ANOVA tradicional, é crucial testar se esses resíduos:

  • Seguem uma distribuição normal, validada por testes como Shapiro-Wilk ou QQ-Plot;
  • Apresentam homogeneidade de variâncias, avaliada por testes como Levene ou Bartlett;
  • São independentes, não pode haver multicolinearidade entre as varíaveis preditoras.
In [39]:
def plot_residuals(variable, data):
    model = ols(f'SalePrice ~ C({variable})', data=data).fit()
    residuals = model.resid
    
    # Histograma dos resíduos
    plt.figure(figsize=(12, 6))
    plt.subplot(1, 3, 1)
    sns.histplot(residuals, kde=True, color='blue')
    plt.title(f'Histograma dos Resíduos ({variable})')
    plt.xlabel('Resíduos')
    
    # Q-Q Plot
    plt.subplot(1, 3, 2)
    sm.qqplot(residuals, line='s', ax=plt.gca())
    plt.title(f'Q-Q Plot ({variable})')
    
    # Scatterplot: Resíduos vs Valores Ajustados
    fitted_values = model.fittedvalues
    plt.subplot(1, 3, 3)
    plt.scatter(fitted_values, residuals, alpha=0.6, color='red')
    plt.axhline(0, color='black', linestyle='--', linewidth=1)
    plt.title(f'Resíduos vs Ajustados ({variable})')
    plt.xlabel('Valores Ajustados')
    plt.ylabel('Resíduos')
    
    plt.tight_layout()
    plt.show()
In [40]:
plot_residuals('Neighborhood', df_anova)
plot_residuals('OverallQual', df_anova)
plot_residuals('GarageCars', df_anova)
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

A análise dos resíduos revela que os pressupostos da ANOVA tradicional foram violados. O histograma dos resíduos mostra assimetria, indicando que a normalidade não é perfeita. No Q-Q Plot, os desvios das caudas reforçam a ausência de normalidade. O scatterplot de resíduos versus valores ajustados sugere heterocedasticidade, com maior variabilidade em valores ajustados mais altos, violando a homogeneidade das variâncias. Esses resultados destacam limitações na aplicação da ANOVA tradicional.


Testes não paramétricos

O teste de Kruskal-Wallis é uma alternativa não paramétrica à ANOVA, utilizado para comparar k amostras independentes (k > 2), especialmente quando as hipóteses de normalidade e homogeneidade das variâncias são violadas ou quando os dados estão em escala ordinal. Segundo Belfiore (2015), este teste verifica se as k amostras são provenientes da mesma população ou de populações com a mesma mediana (μ). Os dados são organizados em uma tabela de dupla entrada, onde as linhas representam as observações e as colunas, os grupos. Em casos com k = 2, o teste é equivalente ao teste Mann-Whitney. O Kruskal-Wallis é particularmente útil em situações com tamanhos de amostra pequenos ou dados que não atendem às premissas dos testes paramétricos, proporcionando uma análise robusta e confiável em cenários desafiadores. (BELFIORE, 2015)

Sendo uma alternativa não paramétrica ao ANOVA e utilizado quando as premissas de normalidade e homogeneidade das variâncias são violadas, esse teste de Kruskal-Wallis compara as medianas de dois ou mais grupos, sendo ideal para variáveis categóricas com múltiplos níveis (como Neighborhood) e uma variável contínua (SalePrice).

Hipóteses:

  • H₀: As distribuições dos grupos são idênticas.
  • H₁: Pelo menos uma distribuição é diferente.

Funcionamento: Os valores são ranqueados, e o teste avalia diferenças nas somas dos rankings entre os grupos. O valor-p indica se as diferenças observadas são significativas:

  • Valor-p < 0.05: Rejeitamos H₀, indicando diferenças significativas.
  • Valor-p ≥ 0.05: Não rejeitamos H₀, sugerindo medianas similares.

In [ ]:
# Neighborhood
kruskal_neighborhood = kruskal(*[df_anova[df_anova['Neighborhood'] == n]['SalePrice'] for n in df_anova['Neighborhood'].unique()])

# OverallQual
kruskal_overallqual = kruskal(*[df_anova[df_anova['OverallQual'] == q]['SalePrice'] for q in df_anova['OverallQual'].unique()])

# GarageCars
kruskal_garagecars = kruskal(*[df_anova[df_anova['GarageCars'] == g]['SalePrice'] for g in df_anova['GarageCars'].unique()])

print("Kruskal-Wallis Results:")
print(f"Neighborhood: H-statistic = {kruskal_neighborhood.statistic}, p-value = {kruskal_neighborhood.pvalue}")
print(f"OverallQual: H-statistic = {kruskal_overallqual.statistic}, p-value = {kruskal_overallqual.pvalue}")
print(f"GarageCars: H-statistic = {kruskal_garagecars.statistic}, p-value = {kruskal_garagecars.pvalue}")
Kruskal-Wallis Results:
Neighborhood: H-statistic = 1799.0853609248172, p-value = 0.0
OverallQual: H-statistic = 1937.79982200856, p-value = 0.0
GarageCars: H-statistic = 1459.5960458881416, p-value = 0.0

Os resultados do teste de Kruskal-Wallis indicam que todas as variáveis analisadas (Neighborhood, OverallQual, e GarageCars) têm um impacto significativo no preço de venda (SalePrice). Com valores-p iguais a 0 para todas as variáveis, rejeitamos a hipótese nula, concluindo que há diferenças estatisticamente significativas entre os grupos. Esses resultados destacam que localização, qualidade geral e capacidade da garagem influenciam diretamente o preço dos imóveis.

Após os resultados do teste de Kruskal-Wallis, que indicaram diferenças significativas entre os grupos das variáveis Neighborhood, OverallQual, e GarageCars, utilizamos o gráfico de violino para ilustrar visualmente essas diferenças. Esse tipo de gráfico combina a distribuição dos dados em cada classe com uma representação da densidade, permitindo observar tanto a variabilidade interna dos grupos quanto a sobreposição entre eles. Dessa forma, os gráficos de violino reforçam os resultados estatísticos, destacando como cada classe dentro das variáveis analisadas contribui para a diferenciação nos preços de venda (SalePrice).

In [42]:
plt.figure(figsize=(14, 8))
sns.violinplot(x='Neighborhood', y='SalePrice', data=df_anova, inner='quartile')
plt.title('Distribuição de Preços por Bairro (Neighborhood)')
plt.xticks(rotation=45)
plt.show()
No description has been provided for this image

O gráfico de violino para Neighborhood mostra diferenças claras na distribuição de preços entre os bairros. Alguns bairros, como NridgHt e StoneBr, possuem distribuições com preços consistentemente altos, enquanto outros, como BrDale e MeadowV, apresentam preços mais baixos e menos variabilidade. A presença de distribuições assimétricas e outliers em alguns bairros reforça a importância da localização como fator determinante no preço de venda.

In [43]:
plt.figure(figsize=(10, 6))
sns.violinplot(x='OverallQual', y='SalePrice', data=df_anova, inner='quartile')
plt.title('Distribuição de Preços por Qualidade Geral (OverallQual)')
plt.show()
No description has been provided for this image

Para OverallQual, esse plot revela uma tendência clara: conforme a qualidade geral dos materiais aumenta, o preço de venda (SalePrice) também cresce significativamente. Níveis mais altos de qualidade (9 e 10) apresentam distribuições mais amplas, incluindo propriedades com preços mais altos. Já níveis baixos de qualidade (1 a 4) têm uam densidade de concentração nos níveis de preços mais baixos. Isso reforça o impacto direto da qualidade dos materiais no valor de mercado das propriedades.

In [44]:
plt.figure(figsize=(10, 6))
sns.violinplot(x='GarageCars', y='SalePrice', data=df_anova, inner='quartile')
plt.title('Distribuição de Preços por Capacidade de Garagem (GarageCars)')
plt.show()
No description has been provided for this image

Para a quantidade de garagens dessas casas, GarageCars, mostra que o preço de venda (SalePrice) tende a aumentar conforme a capacidade da garagem cresce, especialmente até o nível de 3 carros. Sendo esse nível (até 3 carros) que apresenta os preços mais elevados e uma ampla variabilidade.

Após os resultados do teste de Kruskal-Wallis, que indicaram diferenças significativas nos preços de venda (SalePrice) entre os bairros, foi necessário investigar mais profundamente como essas diferenças se manifestam entre pares de bairros específicos. Para isso, utilizamos o teste não paramétrico Mann-Whitney U, ideal para comparar duas amostras independentes, como os bairros "Gilbert" e "StoneBr". Esses bairros foram escolhidos com base em suas distribuições de preços no gráfico de violino, que indicaram diferenças aparentes em suas medianas e amplitudes. Essa abordagem permite identificar se as diferenças observadas entre os dois bairros são estatisticamente significativas.

Segundo Belfiore (2015), o teste U de Mann-Whitney é uma alternativa não paramétrica ao teste t de Student, utilizado para comparar duas amostras independentes quando a hipótese de normalidade é violada ou o tamanho da amostra é pequeno. Esse teste avalia a igualdade das medianas entre as amostras, utilizando a transformação dos dados em postos. Embora perca um pouco de poder em relação ao teste t, é amplamente aplicado devido à sua robustez em condições menos restritivas.

In [ ]:
group1 = df_anova[df_anova['Neighborhood'] == "Gilbert"]['SalePrice']
group2 = df_anova[df_anova['Neighborhood'] == "StoneBr"]['SalePrice']
mann_whitney_result = mannwhitneyu(group1, group2)

test_results = {
    "Mann-Whitney U (Neighborhoods entre Gilbert e StoneBr)": {
        "Statistic": mann_whitney_result.statistic,
        "p-value": mann_whitney_result.pvalue,
    }
}
tools.display_dataframe_to_user(name="Resultados dos Testes Não Paramétricos", dataframe=pd.DataFrame(test_results))
Resultados dos Testes Não Paramétricos
Mann-Whitney U (Neighborhoods entre Gilbert e StoneBr)
Loading ITables v2.2.4 from the internet... (need help?)

O valor-p é extremamente pequeno (muito menor que 0.05), indicando que há uma diferença significativa entre os dois bairros analisados. Isso significa que as distribuições dos preços de venda (SalePrice) nesses dois bairros não são iguais.

Após identificar diferenças significativas entre múltiplos grupos por meio de testes como o Kruskal-Wallis, é fundamental determinar quais grupos específicos diferem entre si. Para isso, utilizamos testes post hoc, que realizam comparações múltiplas para identificar pares de grupos com diferenças estatisticamente significativas (Estatística Fácil).

Entre os testes post hoc disponíveis, o teste de Dunn é uma análise não paramétrica eficaz para comparações múltiplas entre grupos independentes. Ele realiza comparações par a par entre os grupos e indica quais pares apresentam diferenças estatisticamente significativas em um determinado nível de significância (Statorials).

O ajuste de Bonferroni foi utilizado como parâmetro no teste de Dunn para corrigir o nível de significância em comparações múltiplas. Quando realizamos muitos testes simultaneamente, como no caso de comparações par a par entre grupos, o risco de cometer erros do tipo I (falsos positivos) aumenta. O ajuste de Bonferroni reduz esse risco, dividindo o nível de significância (α) pelo número de comparações realizadas. Isso garante que os resultados permaneçam confiáveis, mesmo ao lidar com múltiplos pares de grupos.

In [46]:
# Neighborhood
dunn_neighborhood = sp.posthoc_dunn(df_anova, val_col='SalePrice', group_col='Neighborhood', p_adjust='bonferroni')
# indicando os nomes dos bairros
dunn_neighborhood.index = dunn_neighborhood.columns = df_anova['Neighborhood'].unique()

# OverallQual
dunn_overallqual = sp.posthoc_dunn(df_anova, val_col='SalePrice', group_col='OverallQual', p_adjust='bonferroni')

# GarageCars
dunn_garagecars = sp.posthoc_dunn(df_anova, val_col='SalePrice', group_col='GarageCars', p_adjust='bonferroni')

results_dunn = {
    "Neighborhood": dunn_neighborhood,
    "OverallQual": dunn_overallqual,
    "GarageCars": dunn_garagecars
}

for variable, result in results_dunn.items():
    print(f"Resultados do Teste de Dunn para {variable}:")
    print(result)
    print("\n")
Resultados do Teste de Dunn para Neighborhood:
                NAmes   Gilbert       StoneBr        NWAmes       Somerst  \
NAmes    1.000000e+00  1.000000  9.476928e-11  3.642617e-09  1.000000e+00   
Gilbert  1.000000e+00  1.000000  1.000000e+00  1.000000e+00  4.599787e-01   
StoneBr  9.476928e-11  1.000000  1.000000e+00  1.000000e+00  5.757742e-14   
NWAmes   3.642617e-09  1.000000  1.000000e+00  1.000000e+00  5.855917e-14   
Somerst  1.000000e+00  0.459979  5.757742e-14  5.855917e-14  1.000000e+00   
BrDale   1.000000e+00  0.562534  3.707741e-19  1.741906e-30  1.000000e+00   
NPkVill  1.000000e+00  0.717226  1.814349e-16  8.814735e-21  1.000000e+00   
NridgHt  3.581866e-09  1.000000  1.000000e+00  1.000000e+00  1.220744e-14   
Blmngtn  1.000000e+00  0.845474  2.088080e-17  1.142385e-24  1.000000e+00   
NoRidge  1.000000e+00  1.000000  6.222772e-04  3.655834e-02  1.000000e+00   
SawyerW  1.000000e+00  1.000000  1.143249e-01  9.333566e-01  1.000000e+00   
Sawyer   6.763374e-14  1.000000  1.000000e+00  1.000000e+00  2.152595e-20   
Greens   1.000000e+00  1.000000  1.000000e+00  1.000000e+00  1.000000e+00   
BrkSide  6.489281e-13  1.000000  1.000000e+00  1.000000e+00  4.115140e-17   
OldTown  2.971875e-01  1.000000  1.211676e-06  1.571007e-05  1.166521e-02   
IDOTRR   2.782004e-05  1.000000  1.353277e-03  8.537697e-02  3.128040e-09   
ClearCr  3.366738e-02  1.000000  1.000000e+00  1.000000e+00  3.948854e-03   
SWISU    1.000000e+00  1.000000  2.552779e-15  7.647365e-20  1.000000e+00   
Edwards  3.645136e-02  0.000002  4.350657e-35  2.852576e-49  4.658095e-03   
CollgCr  5.892801e-02  0.000003  1.788844e-39  2.407841e-69  4.673292e-03   
Crawfor  2.695215e-11  1.000000  1.000000e+00  1.000000e+00  5.030906e-18   
Blueste  9.540438e-05  1.000000  1.000000e+00  1.000000e+00  6.399638e-07   
Mitchel  1.727987e-06  1.000000  1.266739e-01  1.000000e+00  1.911439e-10   
Timber   1.000000e+00  1.000000  1.381964e-12  5.488557e-15  1.000000e+00   
MeadowV  1.000000e+00  0.008635  2.756164e-26  7.454469e-43  1.000000e+00   
Veenker  1.000000e+00  0.000106  5.691476e-27  4.102302e-33  6.745770e-01   
GrnHill  1.000000e+00  0.004509  1.404205e-23  2.040611e-30  1.000000e+00   
Landmrk  1.000000e+00  0.022101  5.923956e-15  7.585747e-14  1.000000e+00   

               BrDale       NPkVill       NridgHt       Blmngtn   NoRidge  \
NAmes    1.000000e+00  1.000000e+00  3.581866e-09  1.000000e+00  1.000000   
Gilbert  5.625342e-01  7.172258e-01  1.000000e+00  8.454735e-01  1.000000   
StoneBr  3.707741e-19  1.814349e-16  1.000000e+00  2.088080e-17  0.000622   
NWAmes   1.741906e-30  8.814735e-21  1.000000e+00  1.142385e-24  0.036558   
Somerst  1.000000e+00  1.000000e+00  1.220744e-14  1.000000e+00  1.000000   
BrDale   1.000000e+00  1.000000e+00  1.475204e-40  1.000000e+00  1.000000   
NPkVill  1.000000e+00  1.000000e+00  3.872894e-24  1.000000e+00  1.000000   
NridgHt  1.475204e-40  3.872894e-24  1.000000e+00  1.283627e-30  0.060739   
Blmngtn  1.000000e+00  1.000000e+00  1.283627e-30  1.000000e+00  1.000000   
NoRidge  1.000000e+00  1.000000e+00  6.073925e-02  1.000000e+00  1.000000   
SawyerW  1.000000e+00  1.000000e+00  1.000000e+00  1.000000e+00  1.000000   
Sawyer   2.793761e-42  5.627196e-30  5.981728e-01  3.543503e-35  0.000667   
Greens   1.000000e+00  1.000000e+00  1.000000e+00  1.000000e+00  1.000000   
BrkSide  3.557324e-25  4.641957e-21  2.234424e-01  1.194421e-22  0.000148   
OldTown  6.917644e-06  1.131685e-03  5.325278e-06  2.929627e-04  1.000000   
IDOTRR   2.128116e-33  1.780604e-16  5.064922e-02  1.881576e-22  1.000000   
ClearCr  9.233306e-04  3.035585e-03  1.000000e+00  2.865896e-03  1.000000   
SWISU    1.000000e+00  1.000000e+00  1.094676e-23  1.000000e+00  1.000000   
Edwards  4.537258e-10  3.637133e-07  1.751134e-56  2.259631e-09  1.000000   
CollgCr  2.730388e-15  5.886943e-09  2.328697e-89  4.892628e-13  1.000000   
Crawfor  2.094612e-54  6.136811e-31  1.000000e+00  2.853991e-40  0.014615   
Blueste  9.428136e-11  1.585909e-08  1.000000e+00  3.259932e-09  0.579072   
Mitchel  6.338688e-26  2.865744e-16  1.000000e+00  5.965175e-20  0.391826   
Timber   1.000000e+00  1.000000e+00  1.521537e-17  1.000000e+00  1.000000   
MeadowV  9.358315e-02  1.000000e+00  4.725132e-55  1.539159e-01  1.000000   
Veenker  3.177103e-04  4.815326e-03  2.800422e-36  4.184084e-04  1.000000   
GrnHill  2.346396e-01  1.000000e+00  2.060433e-34  2.417734e-01  1.000000   
Landmrk  1.000000e+00  1.000000e+00  5.289234e-14  1.000000e+00  1.000000   

         ...       Edwards        CollgCr        Crawfor       Blueste  \
NAmes    ...  3.645136e-02   5.892801e-02   2.695215e-11  9.540438e-05   
Gilbert  ...  1.990410e-06   3.243735e-06   1.000000e+00  1.000000e+00   
StoneBr  ...  4.350657e-35   1.788844e-39   1.000000e+00  1.000000e+00   
NWAmes   ...  2.852576e-49   2.407841e-69   1.000000e+00  1.000000e+00   
Somerst  ...  4.658095e-03   4.673292e-03   5.030906e-18  6.399638e-07   
BrDale   ...  4.537258e-10   2.730388e-15   2.094612e-54  9.428136e-11   
NPkVill  ...  3.637133e-07   5.886943e-09   6.136811e-31  1.585909e-08   
NridgHt  ...  1.751134e-56   2.328697e-89   1.000000e+00  1.000000e+00   
Blmngtn  ...  2.259631e-09   4.892628e-13   2.853991e-40  3.259932e-09   
NoRidge  ...  1.000000e+00   1.000000e+00   1.461455e-02  5.790718e-01   
SawyerW  ...  1.000000e+00   1.000000e+00   6.987211e-01  1.000000e+00   
Sawyer   ...  1.790491e-60   3.998349e-83   1.000000e+00  7.392170e-01   
Greens   ...  1.000000e+00   1.000000e+00   1.000000e+00  1.000000e+00   
BrkSide  ...  1.000141e-42   1.029715e-49   1.000000e+00  1.695098e-01   
OldTown  ...  6.155017e-23   1.632311e-31   1.778103e-09  9.878922e-01   
IDOTRR   ...  2.344279e-48   1.565441e-86   1.007747e-05  1.000000e+00   
ClearCr  ...  7.494066e-14   1.322076e-14   1.000000e+00  1.000000e+00   
SWISU    ...  4.188193e-10   1.511538e-13   3.475265e-31  2.022985e-07   
Edwards  ...  1.000000e+00   1.000000e+00   5.388632e-66  1.256984e-26   
CollgCr  ...  1.000000e+00   1.000000e+00  5.413457e-109  1.242282e-31   
Crawfor  ...  5.388632e-66  5.413457e-109   1.000000e+00  1.000000e+00   
Blueste  ...  1.256984e-26   1.242282e-31   1.000000e+00  1.000000e+00   
Mitchel  ...  1.281790e-44   1.009594e-66   1.000000e+00  1.000000e+00   
Timber   ...  3.548152e-13   7.854088e-18   9.926279e-24  4.068527e-05   
MeadowV  ...  7.626218e-03   1.265331e-03   1.056487e-69  9.064469e-18   
Veenker  ...  1.000000e+00   1.000000e+00   2.386181e-42  1.291921e-18   
GrnHill  ...  1.000000e+00   1.000000e+00   1.862816e-41  3.094264e-15   
Landmrk  ...  1.000000e+00   1.000000e+00   2.090393e-16  2.213201e-08   

              Mitchel        Timber       MeadowV       Veenker       GrnHill  \
NAmes    1.727987e-06  1.000000e+00  1.000000e+00  1.000000e+00  1.000000e+00   
Gilbert  1.000000e+00  1.000000e+00  8.635027e-03  1.064576e-04  4.509084e-03   
StoneBr  1.266739e-01  1.381964e-12  2.756164e-26  5.691476e-27  1.404205e-23   
NWAmes   1.000000e+00  5.488557e-15  7.454469e-43  4.102302e-33  2.040611e-30   
Somerst  1.911439e-10  1.000000e+00  1.000000e+00  6.745770e-01  1.000000e+00   
BrDale   6.338688e-26  1.000000e+00  9.358315e-02  3.177103e-04  2.346396e-01   
NPkVill  2.865744e-16  1.000000e+00  1.000000e+00  4.815326e-03  1.000000e+00   
NridgHt  1.000000e+00  1.521537e-17  4.725132e-55  2.800422e-36  2.060433e-34   
Blmngtn  5.965175e-20  1.000000e+00  1.539159e-01  4.184084e-04  2.417734e-01   
NoRidge  3.918259e-01  1.000000e+00  1.000000e+00  1.000000e+00  1.000000e+00   
SawyerW  1.000000e+00  1.000000e+00  1.000000e+00  1.000000e+00  1.000000e+00   
Sawyer   5.908286e-03  1.362620e-23  2.776512e-55  3.207251e-42  4.697358e-40   
Greens   1.000000e+00  1.000000e+00  1.000000e+00  1.000000e+00  1.000000e+00   
BrkSide  6.625595e-03  1.708782e-16  1.107351e-33  1.732684e-32  4.009724e-29   
OldTown  2.259572e-02  1.000000e+00  7.667610e-14  8.678911e-14  2.252960e-10   
IDOTRR   1.000000e+00  3.095698e-10  2.039432e-48  8.495996e-29  1.347805e-26   
ClearCr  1.000000e+00  2.256711e-01  1.882041e-07  5.671568e-10  2.526161e-07   
SWISU    2.847849e-15  1.000000e+00  2.989857e-02  9.019558e-05  5.943192e-02   
Edwards  1.281790e-44  3.548152e-13  7.626218e-03  1.000000e+00  1.000000e+00   
CollgCr  1.009594e-66  7.854088e-18  1.265331e-03  1.000000e+00  1.000000e+00   
Crawfor  1.000000e+00  9.926279e-24  1.056487e-69  2.386181e-42  1.862816e-41   
Blueste  1.000000e+00  4.068527e-05  9.064469e-18  1.291921e-18  3.094264e-15   
Mitchel  1.000000e+00  1.115298e-10  1.265653e-38  1.386755e-28  8.615831e-26   
Timber   1.115298e-10  1.000000e+00  1.018291e-04  7.173827e-07  8.508374e-04   
MeadowV  1.265653e-38  1.018291e-04  1.000000e+00  1.000000e+00  1.000000e+00   
Veenker  1.386755e-28  7.173827e-07  1.000000e+00  1.000000e+00  1.000000e+00   
GrnHill  8.615831e-26  8.508374e-04  1.000000e+00  1.000000e+00  1.000000e+00   
Landmrk  7.044197e-11  3.702665e-01  1.000000e+00  1.000000e+00  1.000000e+00   

              Landmrk  
NAmes    1.000000e+00  
Gilbert  2.210129e-02  
StoneBr  5.923956e-15  
NWAmes   7.585747e-14  
Somerst  1.000000e+00  
BrDale   1.000000e+00  
NPkVill  1.000000e+00  
NridgHt  5.289234e-14  
Blmngtn  1.000000e+00  
NoRidge  1.000000e+00  
SawyerW  1.000000e+00  
Sawyer   5.043907e-19  
Greens   1.000000e+00  
BrkSide  1.708875e-17  
OldTown  2.374524e-04  
IDOTRR   1.248124e-09  
ClearCr  8.081704e-05  
SWISU    1.000000e+00  
Edwards  1.000000e+00  
CollgCr  1.000000e+00  
Crawfor  2.090393e-16  
Blueste  2.213201e-08  
Mitchel  7.044197e-11  
Timber   3.702665e-01  
MeadowV  1.000000e+00  
Veenker  1.000000e+00  
GrnHill  1.000000e+00  
Landmrk  1.000000e+00  

[28 rows x 28 columns]


Resultados do Teste de Dunn para OverallQual:
              1             2             3              4              5   \
1   1.000000e+00  1.000000e+00  1.000000e+00   1.000000e+00   1.000000e+00   
2   1.000000e+00  1.000000e+00  1.000000e+00   1.000000e+00   1.263615e-02   
3   1.000000e+00  1.000000e+00  1.000000e+00   1.000000e+00   1.136036e-05   
4   1.000000e+00  1.000000e+00  1.000000e+00   1.000000e+00   4.346188e-11   
5   1.000000e+00  1.263615e-02  1.136036e-05   4.346188e-11   1.000000e+00   
6   6.766878e-02  4.659551e-07  9.379318e-17   1.441635e-47   3.461726e-29   
7   1.825201e-04  5.335505e-15  1.181649e-37  1.027198e-121  1.333976e-129   
8   4.328370e-07  5.255800e-23  7.704950e-58  1.124369e-174  3.293898e-189   
9   8.294305e-09  6.518857e-27  3.293642e-60  3.843044e-122  8.515679e-104   
10  5.186127e-08  4.221323e-21  7.068872e-36   1.404916e-45   1.725053e-32   

              6              7              8              9             10  
1   6.766878e-02   1.825201e-04   4.328370e-07   8.294305e-09  5.186127e-08  
2   4.659551e-07   5.335505e-15   5.255800e-23   6.518857e-27  4.221323e-21  
3   9.379318e-17   1.181649e-37   7.704950e-58   3.293642e-60  7.068872e-36  
4   1.441635e-47  1.027198e-121  1.124369e-174  3.843044e-122  1.404916e-45  
5   3.461726e-29  1.333976e-129  3.293898e-189  8.515679e-104  1.725053e-32  
6   1.000000e+00   1.550159e-37   1.588719e-86   7.063796e-56  1.500973e-17  
7   1.550159e-37   1.000000e+00   6.803223e-16   2.441885e-17  2.507932e-05  
8   1.588719e-86   6.803223e-16   1.000000e+00   4.882564e-02  1.000000e+00  
9   7.063796e-56   2.441885e-17   4.882564e-02   1.000000e+00  1.000000e+00  
10  1.500973e-17   2.507932e-05   1.000000e+00   1.000000e+00  1.000000e+00  


Resultados do Teste de Dunn para GarageCars:
               0.0            1.0            2.0            3.0           4.0  \
0.0   1.000000e+00   5.982412e-04   4.446881e-64  2.967527e-146  7.526057e-12   
1.0   5.982412e-04   1.000000e+00  1.419913e-130  6.033504e-243  1.757405e-08   
2.0   4.446881e-64  1.419913e-130   1.000000e+00   4.375129e-71  9.259091e-01   
3.0  2.967527e-146  6.033504e-243   4.375129e-71   1.000000e+00  4.115659e-01   
4.0   7.526057e-12   1.757405e-08   9.259091e-01   4.115659e-01  1.000000e+00   
5.0   1.000000e+00   1.000000e+00   1.000000e+00   3.972046e-01  1.000000e+00   

          5.0  
0.0  1.000000  
1.0  1.000000  
2.0  1.000000  
3.0  0.397205  
4.0  1.000000  
5.0  1.000000  


Para aprofundar a análise do impacto do bairro (Neighborhood) no preço de venda (SalePrice), será construído um heatmap. Este gráfico permitirá identificar pares de bairros onde o valor de alfa é menor que 0,05, representados por "1", enquanto pares com alfa maior ou igual a 0,05 serão representados por "0". Essa binarização facilita a visualização e compreensão das relações significativas entre os bairros.

In [47]:
dunn_matrix_neighborhood = dunn_neighborhood.copy()

# Converter valores-p em uma matriz binária: 1 (significativo), 0 (não significativo)
significance_matrix = dunn_matrix_neighborhood.applymap(lambda x: 1 if x < 0.05 else 0)

plt.figure(figsize=(12, 10))
sns.heatmap(significance_matrix, cmap="coolwarm", cbar_kws={'label': 'Significância (0 = Não (p-value ≥ 0.05), 1 = Sim (p-value < 0.05)'})
plt.title("Matriz de Significância do Teste de Dunn - Neighborhood")
plt.xticks(rotation=45, ha='right')
plt.yticks(rotation=0)

plt.show()
No description has been provided for this image

O mapa de calor utiliza uma matriz binária para representar a significância estatística entre grupos de Neighborhood:

  • 1 (cor quente): Comparação significativa (p-value < 0.05), indicando diferença nos preços médios.
  • 0 (cor fria): Comparação não significativa (p-value ≥ 0.05), sugerindo preços médios semelhantes.

Por exemplo, uma célula quente entre "NAmes" e "StoneBr" indica preços significativamente diferentes, enquanto uma célula fria entre "NAmes" e "Gilbert" sugere preços médios semelhantes.

Conclusões

Com base na análise realizada, selecionamos três características do banco de dados para avaliar seu impacto no preço médio de venda (SalePrice) das propriedades. Essas características foram: Neighborhood (bairros), que representa as localizações físicas das propriedades dentro dos limites da cidade de Ames; OverallQual (qualidade geral), que reflete a qualidade dos materiais e acabamentos; e GarageCars (capacidade da garagem), que indica o número de carros que podem ser acomodados. Os testes aplicados, incluindo ANOVA tradicional, Kruskal-Wallis e testes post hoc (como o de Dunn), mostraram que todas as três variáveis influenciam significativamente o preço médio de venda.

A análise revelou que as distribuições dos preços diferem estatisticamente entre bairros, níveis de qualidade geral e capacidades de garagem, indicando que essas características desempenham papéis determinantes na precificação dos imóveis. Além disso, ao investigar as comparações par a par entre categorias dentro de cada variável, observamos diferenças consistentes, reforçando a importância dessas variáveis como fatores críticos para a valorização das propriedades.

Como questão secundária, avaliamos a possibilidade de linearizar os preços das propriedades para implementar uma campanha promocional com preços únicos para todas as casas do portfólio. No entanto, os resultados indicam que essa abordagem não seria viável. As diferenças significativas encontradas entre os grupos sugerem que os preços são fortemente influenciados por características específicas, como localização, qualidade e tamanho da garagem. Assim, alinhar todos os preços a um valor único ignoraria essas variações e poderia levar a decisões de precificação inadequadas, afetando negativamente o equilíbrio do mercado e a percepção de valor dos imóveis.


Bibliografia

BELFIORE, Patrícia. Estatística - Aplicada à Administração, Contabilidade e Economia com Excel e SPSS. Rio de Janeiro: GEN LTC, 2015. E-book ISBN 9788595155596. Disponível em: https://unibb.minhabiblioteca.com.br/reader/books/9788595155596/. Acesso em: 04 dez. 2024.

Estatística Fácil. "O que é: Post-Hoc Test". Disponível em: https://estatisticafacil.org/glossario/o-que-e-post-hoc-test/. Acesso em: 05 dez. 2024.

KAGGLE. Ames Housing Dataset. Disponível em: https://www.kaggle.com/datasets/prevek18/ames-housing-dataset/data. Acesso em: 08 dez. 2024.

Statorials. "Teste de Dunn para comparações múltiplas". Disponível em: https://statorials.org/pt/teste-dunn/. Acesso em: 05 dez. 2024.

VIRGILLITO, Salvatore B. Estatística Aplicada. Rio de Janeiro: Saraiva Uni, 2017. ISBN 9788547214753. Disponível em: https://unibb.minhabiblioteca.com.br/reader/books/9788547214753/. Acesso em: 04 dez. 2024.