O Brasil em Dados: Do Óbvio ao Oculto

Uma análise exploratória completa sobre a demografia, economia e desenvolvimento dos 5.570 municípios do país.

Sobre a Base de Dados

Fontes Oficiais

Um compilado rico extraído de diversas fontes governamentais e institucionais, unindo dados do IBGE, PNUD (para o cálculo do IDHM), Correios, e dados corporativos de mercado (como McDonald's e Uber).

Período Analisado

Trata-se da revisão consolidada (REV 2022). A base mapeia a evolução demográfica e econômica cruzando o Censo Histórico do IBGE com estimativas recentes (2018-2021).

O que contém?

Informações socioeconômicas hiperdetalhadas de todos os 5.570 municípios brasileiros. São mais de 80 colunas contendo indicadores de PIB, arrecadação de impostos, agropecuária, frota de veículos e acesso bancário.

Acesso Aberto: Faça o download dos arquivos brutos para reproduzir o estudo.

5.570

Municípios Analisados

+80

Variáveis Cruzadas

14

Respostas Estatísticas

2

Modelos de IA (RF e K-Means)

Parte 1: O Brasil no Cenário Global

Para encerrar a análise, contextualizamos o Brasil em relação à elite global. Os dados abaixo, extraídos do Relatório de Desenvolvimento Humano (PNUD/ONU), comparam os nossos indicadores de 2018 com o Top 3 mundial.

Indicador 1º Noruega 2º Suíça 3º Irlanda 79º Brasil
Índice de Desenvolvimento Humano (IDH) 0,954 0,946 0,942 0,761
Expectativa de Vida 82,3 anos 83,6 anos 82,1 anos 75,7 anos
Anos Esperados de Estudo 18,1 anos 16,2 anos 18,8 anos 15,4 anos
Média de Anos de Estudo 12,6 anos 13,4 anos 12,5 anos 7,8 anos
Renda Per Capita (Anual) US$ 68.059 US$ 59.375 US$ 55.660 US$ 14.068

Parte 2: Modelagem e Insights Avançados

Oportunidades de Negócio

Por que não tem um McDonald's na sua cidade?

A expansão de grandes marcas não é aleatória; ela segue a matemática. Analisamos o perfil financeiro de todas as cidades do Brasil que já possuem grandes franquias para descobrir a "nota de corte" exigida pelo mercado.

O resultado é impressionante: o modelo destacou em VERDE no gráfico ao lado as cidades classificadas como "Minas de Ouro". São municípios que já têm o poder de compra e a população ideal, mas que continuam ignorados pelas grandes redes.

Top 10 Cidades (Maior Potencial)
Cidade UF População PIB per Capita
Ribeirão Preto SP 604.682 R$ 44.464
Contagem MG 603.442 R$ 40.513
Serra ES 409.267 R$ 37.089
Camaçari BA 242.970 R$ 75.104
Embu Das Artes SP 240.230 R$ 37.832

Os Extremos do Desenvolvimento

Alerta Social
O Paradoxo da Riqueza

Cidades no Top 10% de PIB, mas com Educação entre os 25% piores. Riqueza que não chega à base.

Cidade UF PIB per Capita IDH Educação
Santo Antônio Dos Lopes MA R$ 89.607 0.465
Santa Margarida Do Sul RS R$ 72.488 0.484
Santana Do Mundaú AL R$ 71.760 0.362
Parazinho RN R$ 70.769 0.424
Vitória Do Xingu PA R$ 69.540 0.451
Pedra Grande RN R$ 62.197 0.430
São Bento Do Norte RN R$ 57.339 0.415
Referência
Elite do Desenvolvimento

Onde o capital gera progresso real. Municípios com PIB e Educação no Top 10% do país.

Cidade UF PIB per Capita IDH Educação
Paulínia SP R$ 314.638 0.727
Sebastianópolis Do Sul SP R$ 253.147 0.740
Louveira SP R$ 250.827 0.697
Piratuba SC R$ 180.825 0.714
Barueri SP R$ 177.735 0.708
Jaguariúna SP R$ 158.704 0.715
Confins MG R$ 153.860 0.711
Eficiência Social
Superação Educacional

Cidades com baixo PIB, mas que entregam Educação de Top 10%. O milagre da gestão pública.

Cidade UF PIB per Capita IDH Educação
Paço Do Lumiar MA R$ 6.672 0.739
Gráfico do Paradoxo

O gráfico acima demonstra visualmente os desvios: em vermelho, as cidades do paradoxo.


Qualidade de Vida

O Mapa do Desenvolvimento (IDHM)

Enquanto algumas cidades brasileiras apresentam um Índice de Desenvolvimento Humano (IDHM) comparável ao de países de primeiro mundo, outras ainda lutam com indicadores críticos de vulnerabilidade.

O gráfico ao lado ilustra perfeitamente esse abismo social. Contrastamos o Top 10 das melhores cidades para se viver no Brasil (dominado pelo eixo Sul-Sudeste, com destaque para São Paulo e Santa Catarina) com o Bottom 10, mostrando os extremos da desigualdade nacional em um único painel.

Melhores e Piores Cidades

Machine Learning: Random Forest

O Verdadeiro Motor da Qualidade de Vida

Aplicamos um modelo de Árvore de Decisão (Random Forest) para descobrir: o que mais impacta o IDH de uma cidade? O algoritmo leu todos os dados e ranqueou os setores. O resultado comprova que o setor de Serviços e a Gestão Pública são os grandes responsáveis pelo índice de desenvolvimento do município.

Importância Random Forest

Parte 1: Descobertas Visuais (Análise Exploratória)

Durante a exploração dos dados (EDA), cruzei diversas variáveis para entender como o dinheiro circula no país. Abaixo, alguns dos gráficos gerados que revelam fortes correlações estatísticas.

Matriz de Correlação: Riqueza x IDH
Correlação IDH

O mapa de calor comprova: a Renda tem fortíssima correlação positiva com a Longevidade e a Educação.

O Motor do Emprego: Empresas vs PIB
PIB vs Empresas

Dispersão em escala Logarítmica comprovando que a densidade de empresas é quem dita o tamanho da economia local.

Poder de Compra: Frota vs PIB per Capita
Frota vs PIB

Quanto mais rica a cidade (GDP_CAPITA), maior o número de veículos por habitante.

Visão Geral: População e Frota
Pairplot Frota

Pairplot demonstrando a distribuição conjunta de carros, motos, população e renda.

Parte 4: Respostas ao Desafio Oficial

Aqui estão as validações estatísticas do escopo do projeto, calculadas dinamicamente com Python e Pandas.

O maior estado é SP que tem a "População Geral" dentre os estados com 41.357.343 habitantes, com a maior quantidade de estrangeiros no estado de 205.671 habitantes, representando um percentual de 0.5% que é o maior dentre os outros estados.

Sendo que o menor estado apresentado em "População Geral" é RR com o total de 450.479 habitantes.

População Geral por Estado
População Estrangeira por Estado
Ver código Python utilizado
# Filtrando o dataset para analisar a população geral
df_pg = df[['STATE', 'IBGE_RES_POP', 'IBGE_RES_POP_BRAS','IBGE_RES_POP_ESTR']]

# Agrupando os estados e sumando a população
cols_estados = ['IBGE_RES_POP','IBGE_RES_POP_BRAS','IBGE_RES_POP_ESTR']
df_pg = df_pg.groupby('STATE')[cols_estados].sum().reset_index()

# Ordenando os valores e ajustando o index
df_pg.sort_values(by='IBGE_RES_POP', ascending=False, inplace=True)
df_pg.reset_index(drop=True, inplace=True)

# Plotando o Grafico com a população geral por estado
plt.figure(figsize=(16,6))
plt.bar(df_pg['STATE'], df_pg['IBGE_RES_POP'], color='green')
plt.title('Total da População Geral por Estado')
plt.xlabel('Estado')
plt.ylabel('População')
plt.show()

# Plotando o Grafico com a população estrangeira por estado
plt.figure(figsize=(16,6))
plt.bar(df_pg['STATE'], df_pg['IBGE_RES_POP_ESTR'], color='gray')
plt.title('Total da População Estrangeira por Estado')
plt.xlabel('Estado')
plt.ylabel('População')
plt.show()

# Criando as colunas auxiliares para identificar o percentual
df_pg['Perc_BRAS'] = round((df_pg['IBGE_RES_POP_BRAS'] / df_pg['IBGE_RES_POP']) * 100, 2)
df_pg['Perc_Estr'] = round((df_pg['IBGE_RES_POP_ESTR'] / df_pg['IBGE_RES_POP']) * 100, 2)

# Extraindo os valores formatados
df_maior_estado = df_pg[df_pg['IBGE_RES_POP'] == df_pg['IBGE_RES_POP'].max()]
nome_maior_estado = df_maior_estado['STATE'].iloc[0]
maior_ppg = '{:,.0F}'.format(df_maior_estado['IBGE_RES_POP'].iloc[0]).replace(',', '.')
maior_estr = '{:,.0F}'.format(df_maior_estado['IBGE_RES_POP_ESTR'].iloc[0]).replace(',', '.')
maior_perc_estr = '{:,.1F}'.format(df_maior_estado['Perc_Estr'].iloc[0])

df_menor_estado = df_pg[df_pg['IBGE_RES_POP'] == df_pg['IBGE_RES_POP'].min()]
nome_menor_estado = df_menor_estado['STATE'].iloc[0]
menor_ppg = '{:,.0F}'.format(df_menor_estado['IBGE_RES_POP'].iloc[0]).replace(',', '.')

A cidade com a maior "População Geral" é São Paulo, com 11.253.503 habitantes, tendo também a maior quantidade de estrangeiros na cidade, totalizando 119.727 habitantes. Isso representa um percentual de 1,1% em relação à população total da cidade, o maior entre todas as cidades.

Por outro lado, a cidade com a menor "População Geral" é Borá, totalizando 805 habitantes.

Top 10 População Geral
Top 10 População Estrangeira
Top 10 Menor População
Ver código Python utilizado
# Filtrando o dataset para analisar a população geral
df_city = df[['CITY','STATE','IBGE_RES_POP', 'IBGE_RES_POP_BRAS','IBGE_RES_POP_ESTR']]

# Agrupando as cidades e somando a população
cols_cidade = ['IBGE_RES_POP','IBGE_RES_POP_BRAS','IBGE_RES_POP_ESTR']
df_city = df_city.groupby(['CITY', 'STATE'])[cols_cidade].sum().reset_index()

# Ordenando os valores
df_city.sort_values(by='IBGE_RES_POP', ascending=False, inplace=True)
df_city.reset_index(drop=True, inplace=True)

# Criando a coluna auxiliar de percentual
df_city['Perc_BRAS'] = round((df_city['IBGE_RES_POP_BRAS'] / df_city['IBGE_RES_POP']) * 100, 2)
df_city['Perc_Estr'] = round((df_city['IBGE_RES_POP_ESTR'] / df_city['IBGE_RES_POP']) * 100, 2)

# Separando os top 10
top10_city = df_city.nlargest(10,'IBGE_RES_POP')
top10_city_estr = df_city.nlargest(10,'IBGE_RES_POP_ESTR').reset_index(drop=True)
top10_menor_city = df_city.nsmallest(10,'IBGE_RES_POP').reset_index(drop=True)

# Plotando os gráficos de Top 10 (Geral, Estrangeira e Menores)
plt.figure(figsize=(16,6))
sns.barplot(data=top10_city, x='CITY', y='IBGE_RES_POP')
plt.title('Top 10 Cidades com a Maior População Geral', fontsize=14, fontweight='bold')
plt.show()

# Extraindo as variáveis formatadas para resposta
df_maior_city = top10_city.iloc[0]
df_menor_cidade = top10_menor_city.iloc[0]

A maior concentração de renda per capita é encontrada na região Sul, onde o valor médio é de R$ 2.623.

Já a menor renda per capita está concentrada na região Nordeste, com um valor médio de R$ 857.

Gráfico Renda Per Capita por Região
Ver código Python utilizado
# Filtrando o dataset para tratar o valor per capita
df_pcapita = df[['CITY','STATE','GDP_CAPITA', 'REGION']]

# Agrupando os valores por regiao e calculando a media
df_pcapita = df_pcapita.groupby('REGION')['GDP_CAPITA'].mean().reset_index()

# Ordenando os valores e reajustando o index
df_pcapita.sort_values(by='GDP_CAPITA', ascending=False, inplace=True)
df_pcapita.reset_index(drop=True, inplace=True)

# Ajustando a Coluna GDP_CAPITA para o valor mensal
df_pcapita['GDP_CAPITA'] = df_pcapita['GDP_CAPITA'] / 12

# Plotando o grafico de pizza
plt.figure(figsize=(10,6))
plt.pie(df_pcapita['GDP_CAPITA'],
        labels=df_pcapita['REGION'],
        autopct='%1.1f%%',
        startangle=90)
        
centro_circulo = plt.Circle((0,0), 0.7, fc='white')
fig = plt.gcf()
fig.gca().add_artist(centro_circulo)

plt.title('Média Mensal de Renda Per Capita por Região')
plt.show()

A maior contribuição de imposto é encontrada no estado de "SP", com um valor de R$ 313.740.977.
Por outro lado, a menor contribuição de imposto está no estado de "RR", totalizando R$ 835.732.

Em relação às cidades, a maior contribuição de imposto é da cidade de "São Paulo", que arrecadou R$ 117.125.387.
Já a menor contribuição de imposto foi registrada na cidade de "Varre-Sai", com um valor de R$ -14.159.

Histograma de Impostos por Estado
Boxplot de Impostos por Estado
Ver código Python utilizado
# Filtrando o dataset para analisar as cidades e estados pela contribuição imposto
df_imposto = df[['CITY', 'STATE', 'TAXES']]

# Agrupando o Estado para buscar o valor total
df_imposto_estado = df_imposto.groupby('STATE')['TAXES'].sum().reset_index()

# Ordenando os valores
df_imposto.sort_values(by='TAXES', ascending=False, inplace=True)
df_imposto_estado.sort_values(by='TAXES', ascending=False, inplace=True)

# Ajustando o index
df_imposto.reset_index(drop=True, inplace=True)
df_imposto_estado.reset_index(drop=True, inplace=True)

# Distribuição das populações (Histograma)
plt.figure(figsize=(12, 5))
sns.histplot(df_imposto_estado['TAXES'], kde=True, color='blue', label='STATE')
plt.title('Histograma de Contribuição de Impostos por Estado')
plt.show()

# Plotando um grafico de Boxplot
plt.figure(figsize=(18, 6))
sns.boxplot(data=df_imposto, x='STATE', y='TAXES' )
plt.title('Distribuição de Contribuição de Impostos por Estado')
plt.xlabel('Estado', fontstyle='italic')
plt.ylabel('Imposto', fontstyle='italic')
plt.show()

# Extraindo as Variáveis Máximas e Mínimas (Estado e Cidade)
df_maior_imposto_estado = df_imposto_estado[df_imposto_estado['TAXES'] == df_imposto_estado['TAXES'].max()]
df_menor_imposto_cidade = df_imposto[df_imposto['TAXES'] == df_imposto['TAXES'].min()]
# (Trecho omitido para brevidade visual)

O estado com maior variação entre a população real (censo) e a população estimada é o "SP", apresentando uma distorção total de 4.310.959 habitantes.

Gráfico de Dispersão
Boxplot das Populações
Variação por Estado
Ver código Python utilizado
# Filtrando o dataset para analisar a população real
df_ppl_real = df[['STATE', 'IBGE_RES_POP', 'ESTIMATED_POP']].copy()

# Calcular a variação absoluta entre a população real e estimada
df_ppl_real['VARIATION'] = abs(df_ppl_real['IBGE_RES_POP'] - df_ppl_real['ESTIMATED_POP'])

# Agrupar por estado e somar a variação
df_estado_var = df_ppl_real.groupby('STATE')['VARIATION'].sum().sort_values(ascending=False).reset_index()

# Plotando um de dispersão para comparação entre população real e estimada
plt.figure(figsize=(12, 6))
sns.scatterplot(data=df_ppl_real, x='IBGE_RES_POP', y='ESTIMATED_POP')
plt.title('Comparação entre População Real e Estimada')
plt.show()

# Boxplot para análise de outliers
plt.figure(figsize=(7,9))
sns.boxplot(data=df_ppl_real[['IBGE_RES_POP', 'ESTIMATED_POP']])
plt.title('Boxplot das Populações Real e Estimada')
plt.show()

# Plotando um grafico para analisar a variação por estado
plt.figure(figsize=(12,6))
sns.barplot(data=df_estado_var, x='STATE', y='VARIATION')
plt.title('Variação entre População Real e Estimada por Estado')
plt.show()

# Extraindo a resposta final
df_maior_maior_var = df_estado_var.iloc[0]
# (Trecho da variável final formatada ocultado para brevidade)

A região com a maior área por quilômetro quadrado é a "Norte" com uma área total de 3.846.293 km².

Gráfico de Dispersão Geoespacial
Ver código Python utilizado
# Filtrando o dataset para analisar a area por km²
df_area = df[['REGION', 'STATE', 'CITY', 'AREA', 'LONG', 'LAT', 'ALT']]

# Calcular o total de Area km^2 de cada regiao
regiao_area = df_area.groupby('REGION')['AREA'].sum().reset_index()

# Identificacao de regiao com o maior area km²
area_regiao_max = regiao_area.loc[regiao_area['AREA'].idxmax()]

# Criando os objetos para responder a pergunta
nome_maior_area = area_regiao_max["REGION"]
area_total_maior_regiao = '{:,.0F}'.format(area_regiao_max["AREA"]).replace(',', '.')

# Limpando do dataset Longitude, Latitude e Altitude zeradas
df_area_plt = df_area[(df_area['LONG'] != 0) & (df_area['LAT'] != 0) & (df_area['ALT'] != 0)]

# Plotando o grafico de dispersao 
plt.figure(figsize=(7,7))
sns.scatterplot(data=df_area_plt,
                x='LONG',
                y='LAT',
                hue='REGION',
                size='AREA',
                sizes=(20,200),
                legend=False)

max_region_data = df_area_plt[df_area_plt['REGION'] == area_regiao_max['REGION']]
plt.scatter(max_region_data['LONG'], max_region_data['LAT'], color='green', label=f'Maior Área: {area_regiao_max["REGION"]}')

plt.title('Dispersão da Area km² por Regiões com a Longitude e Latitude')
plt.xlabel('Longitude', fontstyle='italic')
plt.ylabel('Latitude', fontstyle='italic')
plt.legend(fontsize=9, bbox_to_anchor=(0.32, 0.073))
plt.show()

A região com a maior área plantada é a "Centro-Oeste" com uma área de 27.415.868 (unidades de medida).

Por outro lado, a região com a menor área plantada é o "Norte" com uma área de 3.999.773.

Gráfico de Área Plantada por Região
Ver código Python utilizado
# Filtrando o dataset para analisar a area plantada
df_area_plantada = df[['REGION','IBGE_PLANTED_AREA']]

# Calcular o total de Area km^2 de cada regiao
regiao_area_plantada = df_area_plantada.groupby('REGION')['IBGE_PLANTED_AREA'].sum().sort_values(ascending=False).reset_index()

# Criando os objetos para responder a pergunta
df_maior_area_plantada = regiao_area_plantada[regiao_area_plantada['IBGE_PLANTED_AREA'] == regiao_area_plantada['IBGE_PLANTED_AREA'].max()]
nome_maior_area_plantada = df_maior_area_plantada['REGION'].iloc[0]
maior_renda_area_plantada = df_maior_area_plantada['IBGE_PLANTED_AREA'].iloc[0]

df_menor_area_plantada = regiao_area_plantada[regiao_area_plantada['IBGE_PLANTED_AREA'] == regiao_area_plantada['IBGE_PLANTED_AREA'].min()]
nome_menor_area_plantada = df_menor_area_plantada['REGION'].iloc[0]
menor_renda_area_plantada = df_menor_area_plantada['IBGE_PLANTED_AREA'].iloc[0]

# Plotando o grafico com maior area
plt.figure(figsize=(7,6))
sns.barplot(data=regiao_area_plantada,
            y='REGION', 
            x='IBGE_PLANTED_AREA',
            orient='h' )

plt.xlabel('Area Plantada',fontstyle='italic')
plt.ylabel('Região', fontstyle='italic')
plt.show()

Os Estados com os maiores índices de IDH são: "Distrito Federal, São Paulo, Santa Catarina, Rio Grande do Sul, Rio de Janeiro".
Por outro lado, as regiões com os menores índices de IDH são: "Pará, Maranhão, Piauí, Amazonas, Alagoas".

A estatística utilizada no processo de resolução foi a mediana, devido à sua capacidade de representar a concentração central dos dados na população, sendo menos suscetível a mudanças devido a valores extremos (outliers).

Dashboard Estatístico de IDH por Estado
Ver código Python utilizado
# Filtrando o dataset (usando df_clean)
df_idh = df_clean[['STATE','NAME_STATE','REGION', 'CITY', 'IDHM','LONG', 'LAT', 'ALT']].copy()

# Calcular a mediana do IDH por estado
df_idh_estado = (df_idh
                .groupby(['STATE','NAME_STATE','REGION'])
                .agg({'IDHM': 'median'})
                .sort_values(by=['IDHM'], ascending=False)
                .reset_index())

# Extração de percentis para identificar outliers (LCI e LCS)
percentis = np.percentile(df_idh_estado['IDHM'], [25, 50, 75])
iqr = percentis[2] - percentis[0]
lci = percentis[0] - 1.5 * iqr
lcs = percentis[2] + 1.5 * iqr

# Região com o maior IDH
df_maior_idh = df_idh_estado[df_idh_estado['IDHM'] >= percentis[2]].head(5)
nome_maior_idh_regiao = ', '.join(df_maior_idh['NAME_STATE'].values.tolist())

# Região com o menor IDH
df_menor_idh = df_idh_estado[df_idh_estado['IDHM'] <= percentis[0]].tail(5)
nome_menor_idh_regiao = ', '.join(df_menor_idh['NAME_STATE'].values.tolist())

# Criando o Dashboard com três gráficos (Subplot2Grid)
fig = plt.figure(figsize=(11, 8.3))

# Plot 1: Barras Horizontais com anotações de Quartis
ax1 = plt.subplot2grid((3, 2), (0, 0), rowspan=3)
sns.barplot(data=df_idh_estado, x='IDHM', y='STATE', orient='h', palette="cividis", ax=ax1)
ax1.axvline(percentis[2], color='blue', linestyle='--') # Q3
ax1.axvline(percentis[0], color='orange', linestyle='--') # Q1

# Plot 2: Dispersão Geoespacial
ax2 = plt.subplot2grid((3, 2), (1, 1), rowspan=2)
sns.scatterplot(data=df_idh_plt, x='LONG', y='LAT', hue='REGION', size='IDHM', palette='pastel', ax=ax2)

# Plot 3: Histograma com Média, Mediana e Assimetria
ax3 = plt.subplot2grid((3, 2), (0, 1))
sns.histplot(df_idh_estado['IDHM'], kde=True, color='#5EAAA8', bins=10, ax=ax3)

plt.tight_layout()
plt.show()

Sim, existe uma relação entre o PIB per capita e o IDH das pessoas, onde regiões com maiores valores de PIB per capita tendem a ter um IDH mais alto. No entanto, o dinheiro não é um fator determinante absoluto, pois apenas 17.7% da variação no IDHM pode ser explicada matematicamente pelo PIB per capita.

Gráfico de Regressão PIB e IDH
Ver código Python utilizado (Scikit-Learn)
# Preparacao dos dados para o modelo
X = np.array(df_pib_idh['IDHM']).reshape(-1,1)
y = df_pib_idh['GDP_CAPITA']

# Dividindo dados em treinamento e teste
X_treino, X_teste, y_treino, y_teste = train_test_split(X, y, test_size=0.2, random_state=42)

# Criando o modelo de regressao linear
modelo_regressao = LinearRegression()
modelo_regressao.fit(X_treino, y_treino)

# Avalia o modelo nos dados de teste
score = modelo_regressao.score(X_teste,y_teste)
score_perc = score * 100

# Visualizacao da reta de regressao linear (previsoes)
plt.scatter(X, y, label='Dados Reais')
plt.plot(X, modelo_regressao.predict(X), color='orange', label='Reta com as previsões do modelo')
plt.title('Relação entre o PIB per capita e IDH')
plt.show()

Sim, verificamos uma correlação positiva. Através do modelo de regressão OLS (Statsmodels), comprovamos que um maior PIB per capita reflete em melhor expectativa de vida. Contudo, assim como no IDH geral, a renda explica apenas 19.4% da variância da longevidade, indicando que fatores como saneamento e infraestrutura do SUS (não apenas renda direta) são vitais.

Histograma Longevidade
Regressão Longevidade
Ver código Python utilizado (Statsmodels)
# Preparacao dos dados para o modelo - Independente
X1 = np.array(df_pib_idh_long['IDHM_Longevidade']).reshape(-1,1)
y1 = df_pib_idh_long['GDP_CAPITA']

# Adicao constante da variavel independente
X1 = sm.add_constant(X1)

# Criando e treinando o modelo OLS - Statsmodels
modelo_ols = sm.OLS(y1, X1)
resultado_ols = modelo_ols.fit()

# Imprimindo a tabela de resultado estatístico detalhado
print(resultado_ols.summary())

# Grafico de Dispersao 
plt.figure(figsize=(10,7))
plt.scatter(df_pib_idh_long['IDHM_Longevidade'], y1, label='Dados Reais', color='#028391')
plt.plot(df_pib_idh_long['IDHM_Longevidade'], resultado_ols.fittedvalues, color='#FDDE55', label='Linha de Previsoes OLS')
plt.title('Relacao entre o PIB per capita e IDH Longividade')
plt.show()

Sim, a relação é fortíssima e positiva. Através da Regressão Linear (OLS), identificamos que o número de empresas e a geração de riqueza crescem juntos de forma proporcional. O modelo nos mostra que a densidade de empresas consegue explicar 74.0% da variância do PIB nesses agrupamentos, comprovando que a força empreendedora e de infraestrutura logística é o verdadeiro motor econômico.

Gráfico de Regressão: Empresas x PIB
Ver código Python utilizado
# Filtrando o dataset para analisar o PIB e total de empresas
df_pib_empresa = df[['STATE','REGION','COMP_TOT','GDP_CAPITA']]

# Preparacao dos dados para o modelo
cols_empresas = ['COMP_TOT', 'GDP_CAPITA']
df_pib_empresa_estado = df_pib_empresa.groupby(['STATE','REGION'])[cols_empresas].sum().sort_values(by='GDP_CAPITA',ascending=False).reset_index()

# Preparacao dos dados para o modelo (Independente e Dependente)
X2 = np.array(df_pib_empresa_estado['COMP_TOT']).reshape(-1,1)
y2 = df_pib_empresa_estado['GDP_CAPITA']

# Adicao constante da variavel independente
X2_sm = sm.add_constant(X2) 

# Criando e treinando o modelo OLS - statsmodels
modelo_ols_empresas = sm.OLS(y2, X2_sm)
resultado_empresas = modelo_ols_empresas.fit()

# Imprimindo a tabela de resultado
print(resultado_empresas.summary())

# Grafico de Dispersao 
plt.scatter(y=y2, x=df_pib_empresa_estado['COMP_TOT'], label='Dados reais')
plt.plot(df_pib_empresa_estado['COMP_TOT'], resultado_empresas.fittedvalues, color='#FDDE55', label='Linha de Previsoes do modelo')
plt.xlabel('Total empresas')
plt.ylabel('PIB per capita')
plt.title('Relacao entre o PIB per capita e Total de empresas')
plt.legend()
plt.show()

Sim, notamos uma correlação moderada a positiva (0.09). O aumento da renda per capita reflete no poder de compra da frota veicular local. Observamos também através dos histogramas que a distribuição de veículos no Brasil é extremamente assimétrica (muito concentrada em poucos estados), com destaque para a assimetria total da frota, que marcou uma distorção de 3.48.

Histogramas de Veículos por Estado
Ver código Python utilizado
# Filtrando o dataset para analisar os veículos
df_pib_car_moto = df[['CITY','STATE','REGION', 'GDP_CAPITA', 'Cars', 'Motorcycles']]

# Criando uma coluna auxiliar com a soma de Carros e Motos
df_pib_car_moto['Total_Car_Moto'] = df_pib_car_moto['Cars'] + df_pib_car_moto['Motorcycles']

# Agrupando as medidas por estado (Mediana para PIB, Soma para frota)
df_pib_car_moto_estado = df_pib_car_moto.groupby(['STATE','REGION']).agg({
    'GDP_CAPITA':'median', 
    'Cars':'sum', 
    'Motorcycles':'sum', 
    'Total_Car_Moto':'sum'
}).sort_values(by='GDP_CAPITA', ascending=False).reset_index()

# Calculando Assimetria (Skewness)
skew_car = round(skew(df_pib_car_moto_estado['Cars']),2)
skew_moto = round(skew(df_pib_car_moto_estado['Motorcycles']),2)
skew_car_moto = round(skew(df_pib_car_moto_estado['Total_Car_Moto']), 2)

# Plotando o Histograma dos Dados de carros e Motos em 3 colunas
fig, axes = plt.subplots(1, 3, figsize=(14,4))

# Histograma do Total de Carros
sns.histplot(df_pib_car_moto_estado['Cars'], kde=True, color='#4D869C', bins=15, ax=axes[0])
axes[0].text(0.55, 0.8, f'Assimetria: {skew_car:.2f}', transform=axes[0].transAxes)
axes[0].set_title('Histograma - Carros')

# Histograma do Total de Motos
sns.histplot(df_pib_car_moto_estado['Motorcycles'], kde=True, color='#4D868A', bins=20, ax=axes[1])
axes[1].text(0.55, 0.8, f'Assimetria: {skew_moto:.2f}', transform=axes[1].transAxes)
axes[1].set_title('Histograma - Motos')

# Histograma do Total
sns.histplot(df_pib_car_moto_estado['Total_Car_Moto'], kde=True, color='#4D869C', bins=15, ax=axes[2])
axes[2].text(0.55, 0.8, f'Assimetria: {skew_car_moto:.2f}', transform=axes[2].transAxes)
axes[2].set_title('Histograma - Total')

plt.tight_layout()
plt.show()

A média nacional estadual de veículos por pessoa é 0.39.

O Estado com a maior média de veículos por pessoa é SC, com 0.654 veículos por habitante.
Enquanto isso, o Estado com a menor média é o AM, com apenas 0.205 veículos por pessoa.

Histograma de Veículos por Pessoa
Barplot de Veículos por Estado
Ver código Python utilizado
# Filtrando o dataset
df_veiculo = df[['STATE', 'IBGE_RES_POP', 'Cars', 'Motorcycles']]

# Criando uma coluna auxiliar com a soma de Carros e Motos
df_veiculo['Total_Car_Moto'] = df_veiculo['Cars'] + df_veiculo['Motorcycles']

# Agrupando por Estado e somando o total de pessoas e o total de veículos
cols_agrupamento = ['IBGE_RES_POP', 'Total_Car_Moto']
df_veiculo_estado = df_veiculo.groupby('STATE')[cols_agrupamento].sum().reset_index()

# Coluna com o Total de Veículo por Pessoa
df_veiculo_estado['Veiculo_Pessoa'] = df_veiculo_estado['Total_Car_Moto'] / df_veiculo_estado['IBGE_RES_POP']

# Organizar por Total de Veículos
df_veiculo_estado = df_veiculo_estado.sort_values(by='Veiculo_Pessoa', ascending=False).reset_index(drop=True)

# Extração de Variáveis (Estatística e Extremos)
media_veiculo = round(df_veiculo_estado['Veiculo_Pessoa'].mean(), 2)
mediana_veiculo = round(df_veiculo_estado['Veiculo_Pessoa'].median(), 2)
nome_maior_veiculo = df_veiculo_estado['STATE'].iloc[0]
nome_menor_veiculo = df_veiculo_estado['STATE'].iloc[-1]

# Histograma do Veículos por Pessoas
plt.figure(figsize=(7,5))
sns.histplot(df_veiculo_estado['Veiculo_Pessoa'], kde=True, color='gray', bins=10)
plt.axvline(media_veiculo, color='red', linestyle='--', linewidth=1, label=f'Média: {media_veiculo:.3f}')
plt.show()

# Plotando o grafico com maiores veículos por estado
plt.figure(figsize=(7,6))
ax = sns.barplot(data=df_veiculo_estado,
                x='Veiculo_Pessoa',
                y='STATE', 
                orient='h',
                palette='seismic',
                alpha=0.9)

for p in ax.patches:
    ax.annotate(f'{p.get_width():.3f}', 
                (p.get_width() + p.get_x(), p.get_y() + p.get_height() / 2.), 
                ha='left', va='center_baseline', fontsize=10, color='black', fontweight='bold')

plt.xlim(0,0.8)
plt.title('Veículo por Estado: Do Maior para o Menor')
plt.show()

Sim, existe relação, mas com forte variação regional. O modelo de regressão global aponta que o número de tratores explica cerca de 20.8% da variação da área plantada. No entanto, analisando as correlações isoladas por região, vemos os seguintes índices:
  • Sudeste: 0.87
  • Sul: 0.18
  • Centro-Oeste: -0.87
  • Nordeste: 0.36
  • Norte: 0.67

Isso evidencia que o agronegócio no Sudeste e Sul é intensivo em maquinário (mecanização de precisão), enquanto o Nordeste apresenta forte dependência de métodos tradicionais, trabalho manual e agricultura familiar.

Gráficos de Tratores e Área Plantada
Ver código Python utilizado
# Filtrando o dataset 
df_trator = df[['STATE', 'REGION','IBGE_PLANTED_AREA', 'Wheeled_tractor']]

# Agrupando os dados por Estado
cols_trator = ['IBGE_PLANTED_AREA', 'Wheeled_tractor']
df_trator_estado = df_trator.groupby(['STATE', 'REGION'])[cols_trator].sum().sort_values(by='Wheeled_tractor', ascending=False).reset_index()

# Preparacao dos dados para o modelo OLS 
X_trator = np.array(df_trator_estado['Wheeled_tractor']).reshape(-1,1)
y_trator = df_trator_estado['IBGE_PLANTED_AREA']

# Adicao constante da variavel independente
X_trator_sm = sm.add_constant(X_trator)

# Criando e Treinando o modelo OLS - statsmodels
modelo_trator = sm.OLS(y_trator, X_trator_sm)
resultado_trator = modelo_trator.fit()

# Imprimindo a tabela de resultado
print(resultado_trator.summary())

# Imprimindo a correlacao da Area plantada pelo total de tratores por regiao
for regiao in df_trator_estado['REGION'].unique():
    subset = df_trator_estado[df_trator_estado['REGION'] == regiao]
    print(f"Região {regiao}:", subset.select_dtypes(include='number').corr().iloc[0,1])

# Grafico de Dispersao 
plt.scatter(x=df_trator_estado['Wheeled_tractor'], y=y_trator, label='Dados reais')
plt.plot(df_trator_estado['Wheeled_tractor'], resultado_trator.fittedvalues, color='orange', label='Linha de previsoes')
plt.xlabel('Total de Tratores')
plt.ylabel('Area Plantada')
plt.title('Relacao da Area Plantada com o Total de Tratores')
plt.legend()
plt.show()

Conclusões e Aprendizados

Este projeto foi um excelente laboratório prático para trabalhar com dados reais, tratamento de nulos e modelagem preditiva.

A grande evolução técnica ocorreu ao aliar a biblioteca Pandas aos modelos do Scikit-Learn e Statsmodels, permitindo transformar dados estáticos em predições de mercado e em análises profundas de impacto social. A automação da geração do relatório HTML via script Python consolidou minha capacidade de criar fluxos de dados de ponta a ponta.