ricardoadriano commited on
Commit
ec00b52
·
verified ·
1 Parent(s): d7518cf

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +84 -152
src/streamlit_app.py CHANGED
@@ -1,159 +1,91 @@
1
- #!/usr/bin/env python
2
- # coding: utf-8
3
-
4
- # =====================================================
5
- # Dashboard - Testes de Hipóteses com AmesHousing
6
- # =====================================================
7
-
8
  import streamlit as st
9
  import pandas as pd
10
  import matplotlib.pyplot as plt
11
  import seaborn as sns
12
  import plotly.express as px
13
- import numpy as np
14
-
15
- from scipy import stats
16
- from scipy.stats import shapiro, levene, kruskal
17
- from statsmodels.formula.api import ols
18
- import statsmodels.api as sm
19
-
20
- # -----------------------------------------------------
21
- # Configuração da Página
22
- # -----------------------------------------------------
23
- st.set_page_config(
24
- page_title="Dashboard - Testes de Hipóteses com AmesHousing",
25
- layout="wide",
26
- initial_sidebar_state="expanded"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  )
28
 
29
- st.markdown("<h1 style='text-align:center;color:#003366;'>Simulador de Testes de Hipótese</h1>", unsafe_allow_html=True)
30
- st.markdown("<h3 style='text-align:center;color:#003366;'>Análise do Dataset AmesHousing</h3>", unsafe_allow_html=True)
31
- st.markdown("---")
32
-
33
- # -----------------------------------------------------
34
- # Abas do Dashboard
35
- # -----------------------------------------------------
36
- tabs = st.tabs(["Simulações Teóricas", "Análise AmesHousing"])
37
-
38
- # -----------------------------------------------------
39
- # Aba 1: Simulações Teóricas (mantida)
40
- # -----------------------------------------------------
41
- with tabs[0]:
42
- st.subheader("Teste de Hipótese para Proporção de Testes Positivos de COVID-19")
43
-
44
- st.sidebar.markdown("### Parâmetros do Teste (Proporção)")
45
- p_pop = st.sidebar.slider("Proporção populacional (H0)", 0.0, 1.0, 0.1, 0.01, key="p_pop")
46
- p_sample = st.sidebar.slider("Proporção amostral", 0.0, 1.0, 0.12, 0.01, key="p_sample")
47
- n = st.sidebar.slider("Tamanho da amostra", 100, 10000, 1000, 10, key="n_sample")
48
- alpha_prop = st.sidebar.slider("Nível de significância (α)", 0.01, 0.10, 0.05, 0.01, key="alpha_prop")
49
-
50
- se = np.sqrt(p_pop*(1-p_pop)/n)
51
- z = (p_sample - p_pop)/se
52
- p_value = 2*(1 - stats.norm.cdf(abs(z)))
53
-
54
- st.write(f"**Z** = {z:.4f}")
55
- st.write(f"**p-valor** = {p_value:.4f}")
56
- if p_value < alpha_prop:
57
- st.write("**Rejeitamos H0**: diferença significativa.")
58
- else:
59
- st.write("**Não rejeitamos H0**: sem diferença significativa.")
60
-
61
- # -----------------------------------------------------
62
- # Aba 2: Análise AmesHousing
63
- # -----------------------------------------------------
64
- with tabs[1]:
65
- st.subheader("Análise de Variância - AmesHousing Dataset")
66
- st.markdown("---")
67
-
68
- # Leitura fixa do CSV dentro da pasta Dados
69
- casa_data = pd.read_csv("../Dados/AmesHousing.csv")
70
-
71
- # Renomear colunas para evitar problemas com espaços
72
- casa_data.columns = casa_data.columns.str.strip().str.replace(" ", "_")
73
-
74
- # -------------------------------------------------
75
- # Análise Exploratória
76
- # -------------------------------------------------
77
- st.markdown("### Distribuição do Preço de Venda")
78
- fig, ax = plt.subplots(figsize=(8,5))
79
- sns.histplot(casa_data['SalePrice'], kde=True, ax=ax)
80
- ax.set_title("Distribuição do Preço de Venda")
81
- st.pyplot(fig)
82
-
83
- # Boxplots
84
- st.markdown("### Boxplots das Variáveis Selecionadas")
85
- variavel = st.selectbox("Escolha a variável categórica para comparar preços:",
86
- ["Neighborhood","Garage_Type","Fireplaces"])
87
-
88
- fig2, ax2 = plt.subplots(figsize=(12,6))
89
- sns.boxplot(x=variavel, y="SalePrice", data=casa_data, ax=ax2)
90
- plt.xticks(rotation=90)
91
- ax2.set_title(f"Preço de Venda por {variavel}")
92
- st.pyplot(fig2)
93
-
94
- # Scatter interativo (média de preço por bairro)
95
- st.markdown("### Preço Médio de Venda por Bairro")
96
- bairro_grouped = casa_data.groupby('Neighborhood').agg(
97
- count=('SalePrice','size'),
98
- mean_price=('SalePrice','mean')
99
- ).reset_index()
100
-
101
- bairro_filtered = bairro_grouped[bairro_grouped['count'] >= 5]
102
- fig3 = px.scatter(
103
- bairro_filtered,
104
- x='mean_price',
105
- y='Neighborhood',
106
- size='count',
107
- color='Neighborhood',
108
- title='Preço Médio de Venda vs Bairro (Ames, Iowa)',
109
- labels={'mean_price': 'Preço Médio de Venda', 'Neighborhood':'Bairro'},
110
- opacity=0.8
111
- )
112
- st.plotly_chart(fig3, use_container_width=True)
113
-
114
- # -------------------------------------------------
115
- # ANOVA
116
- # -------------------------------------------------
117
- st.markdown("### ANOVA para Neighborhood, Garage_Type e Fireplaces")
118
- alpha = st.sidebar.slider("Nível de significância (α) - ANOVA AmesHousing",
119
- 0.01,0.10,0.05,0.01,key="alpha_ames")
120
-
121
- modelos = {
122
- "Neighborhood": ols('SalePrice ~ C(Neighborhood)', data=casa_data).fit(),
123
- "Garage_Type": ols('SalePrice ~ C(Garage_Type)', data=casa_data).fit(),
124
- "Fireplaces": ols('SalePrice ~ C(Fireplaces)', data=casa_data).fit()
125
- }
126
-
127
- for nome, modelo in modelos.items():
128
- st.markdown(f"#### ANOVA - {nome}")
129
- anova = sm.stats.anova_lm(modelo, typ=2)
130
- st.dataframe(anova)
131
-
132
- # -------------------------------------------------
133
- # Validação dos Pressupostos
134
- # -------------------------------------------------
135
- st.markdown("### Validação dos Pressupostos da ANOVA")
136
-
137
- st.markdown("#### Teste de Normalidade (Shapiro-Wilk)")
138
- for nome, modelo in modelos.items():
139
- residuos = modelo.resid
140
- stat, p = shapiro(residuos.dropna())
141
- st.write(f"{nome}: estatística={stat:.3f}, p={p:.3f} "
142
- + ("resíduos normais" if p >= alpha else "violação de normalidade"))
143
-
144
- st.markdown("#### Teste de Homocedasticidade (Levene)")
145
- for nome in ["Neighborhood","Garage_Type","Fireplaces"]:
146
- grupos = [grupo["SalePrice"].dropna() for _, grupo in casa_data.groupby(nome)]
147
- stat, p = levene(*grupos)
148
- st.write(f"{nome}: estatística={stat:.3f}, p={p:.3f} "
149
- + ("variâncias iguais" if p >= alpha else "variâncias diferentes"))
150
-
151
- # -------------------------------------------------
152
- # Kruskal-Wallis
153
- # -------------------------------------------------
154
- st.markdown("### Teste não-paramétrico (Kruskal-Wallis)")
155
- for nome in ["Neighborhood","Garage_Type","Fireplaces"]:
156
- grupos = [grupo["SalePrice"].dropna() for _, grupo in casa_data.groupby(nome)]
157
- stat, p = kruskal(*grupos)
158
- st.write(f"{nome}: estatística={stat:.3f}, p={p:.3f} "
159
- + ("diferenças significativas" if p < alpha else "sem diferença significativa"))
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
  import pandas as pd
3
  import matplotlib.pyplot as plt
4
  import seaborn as sns
5
  import plotly.express as px
6
+ from pathlib import Path
7
+ from sklearn.model_selection import train_test_split
8
+
9
+ st.set_page_config(page_title="Dashboard Ames Housing", layout="wide")
10
+
11
+ # -----------------------
12
+ # Carregando o CSV de forma robusta
13
+ # -----------------------
14
+ HERE = Path(__file__).resolve().parent
15
+ CANDIDATES = [
16
+ HERE.parent / "Dados" / "AmesHousing.csv",
17
+ HERE / "Dados" / "AmesHousing.csv",
18
+ Path("Dados") / "AmesHousing.csv",
19
+ ]
20
+ csv_path = next((p for p in CANDIDATES if p.exists()), None)
21
+ if csv_path is None:
22
+ st.error("Arquivo 'Dados/AmesHousing.csv' não encontrado. Confirme o nome e a pasta.")
23
+ st.stop()
24
+
25
+ casa_data = pd.read_csv(csv_path)
26
+ casa_data.columns = casa_data.columns.str.strip().str.replace(" ", "_")
27
+
28
+ # -----------------------
29
+ # Sidebar: proporção treino/teste
30
+ # -----------------------
31
+ st.sidebar.header("Configurações")
32
+ prop_treino = st.sidebar.slider("Proporção de treino", 0.1, 0.9, 0.7)
33
+
34
+ train, test = train_test_split(casa_data, train_size=prop_treino, random_state=42)
35
+
36
+ # O usuário escolhe qual conjunto visualizar
37
+ dataset_opcao = st.sidebar.radio(
38
+ "Conjunto de dados a visualizar:",
39
+ ["Treino", "Teste"],
40
+ index=0
41
  )
42
 
43
+ if dataset_opcao == "Treino":
44
+ dados = train.copy()
45
+ else:
46
+ dados = test.copy()
47
+
48
+ # -----------------------
49
+ # Gráfico 1: Distribuição do Preço de Venda
50
+ # -----------------------
51
+ st.subheader("Distribuição do Preço de Venda")
52
+ fig, ax = plt.subplots()
53
+ sns.histplot(dados['SalePrice'], kde=True, ax=ax)
54
+ st.pyplot(fig)
55
+
56
+ # -----------------------
57
+ # Gráfico 2: Boxplot de Preço de Venda por Bairro
58
+ # -----------------------
59
+ st.subheader("Boxplot de Preço de Venda por Bairro")
60
+ fig2, ax2 = plt.subplots(figsize=(12, 6))
61
+ sns.boxplot(x="Neighborhood", y="SalePrice", data=dados, ax=ax2)
62
+ plt.xticks(rotation=90)
63
+ st.pyplot(fig2)
64
+
65
+ # -----------------------
66
+ # Gráfico 3: Dispersão Área vs Preço
67
+ # -----------------------
68
+ st.subheader("Dispersão: Área vs Preço de Venda")
69
+ fig3 = px.scatter(dados, x="Gr_Liv_Area", y="SalePrice",
70
+ color="Overall_Qual", hover_data=["Year_Built"])
71
+ st.plotly_chart(fig3, use_container_width=True)
72
+
73
+ # -----------------------
74
+ # Gráfico 4: Heatmap de Correlação
75
+ # -----------------------
76
+ st.subheader("Matriz de Correlação (variáveis numéricas)")
77
+ corr = dados.corr(numeric_only=True)
78
+ fig4, ax4 = plt.subplots(figsize=(10, 8))
79
+ sns.heatmap(corr, cmap="coolwarm", center=0, ax=ax4)
80
+ st.pyplot(fig4)
81
+
82
+ # -----------------------
83
+ # Gráfico 5: Preço médio por estilo de casa
84
+ # -----------------------
85
+ st.subheader("Preço médio por estilo de casa")
86
+ mean_price = dados.groupby("House_Style")["SalePrice"].mean().sort_values(ascending=False)
87
+ fig5, ax5 = plt.subplots()
88
+ mean_price.plot(kind="bar", ax=ax5)
89
+ st.pyplot(fig5)
90
+
91
+ st.success(f"Visualizando {dataset_opcao} ({dados.shape[0]} registros, proporção treino = {prop_treino:.2f})")