joaogabrielsouza commited on
Commit
df6c009
·
1 Parent(s): 4f9dcf1

Atualiza menu de mapas e gráficos interativos

Browse files
Dashboard_Teste_de_Hipoteses_online.py CHANGED
@@ -71,10 +71,10 @@ tabs = st.tabs(["Simulações Teóricas", "Análise de Chocolate"])
71
  with tabs[0]:
72
  st.subheader("Teste de Hipótese para Proporção de Testes Positivos de COVID-19")
73
  st.sidebar.markdown("### Parâmetros do Teste")
74
- p_pop = st.sidebar.slider("Proporção populacional (H0)", 0.0, 1.0, 0.1, 0.01)
75
- p_sample = st.sidebar.slider("Proporção amostral", 0.0, 1.0, 0.12,0.01)
76
- n = st.sidebar.slider("Tamanho da amostra", 100, 10000, 1000, 10)
77
- alpha = st.sidebar.slider("Nível de significância (α)", 0.01, 0.10, 0.05, 0.01)
78
 
79
  se = np.sqrt(p_pop*(1-p_pop)/n)
80
  z = (p_sample - p_pop)/se
@@ -82,7 +82,7 @@ with tabs[0]:
82
 
83
  st.write(f"**Z** = {z:.4f}")
84
  st.write(f"**p-valor** = {p_value:.4f}")
85
- if p_value < alpha:
86
  st.write("**Rejeitamos H0**: diferença significativa.")
87
  else:
88
  st.write("**Não rejeitamos H0**: sem diferença significativa.")
@@ -93,7 +93,7 @@ with tabs[0]:
93
  fig = go.Figure()
94
  fig.add_trace(go.Scatter(x=x, y=y, mode="lines", line=dict(color="blue")))
95
  fig.add_vline(x=p_sample, line=dict(color="red", width=2))
96
- zc = stats.norm.ppf(1-alpha/2)
97
  fig.add_vrect(x0=p_pop-zc*se, x1=p_pop+zc*se, fillcolor="red", opacity=0.2, line_width=0)
98
  fig.update_layout(
99
  title="Distribuição Normal e Região Crítica",
@@ -104,78 +104,86 @@ with tabs[0]:
104
 
105
  st.markdown("**Descrição**: Teste bilateral de proporções usando valor-p.")
106
 
107
- # Aba 2: Análise de Chocolate
108
  with tabs[1]:
109
  st.subheader("Testes de Hipótese e ANOVA em Dados de Chocolate")
110
  st.markdown("---")
111
 
112
- # 1) Carregar dados
113
- df = pd.read_csv("Dados/flavors_of_cacao.csv")
114
- st.markdown("#### Dados Brutos")
115
- st.dataframe(df)
116
 
117
- # 2) Renomear colunas
 
118
  df.columns = [
119
  "company","bean_bar_origin","ref","date",
120
  "percent","location","rating","beantype","origin"
121
  ]
122
- st.markdown("#### Colunas Renomeadas")
123
- st.dataframe(df.head())
124
-
125
- # 3) Mapa: empresas por país
126
- grp_loc = df.groupby("location").size().reset_index(name="count")
127
- url = "https://raw.githubusercontent.com/datasets/geo-countries/master/data/countries.geojson"
128
- world = gpd.read_file(url).rename(columns={"ADMIN":"name"})
129
- mapa = world.merge(grp_loc, how="left", left_on="name", right_on="location")
130
- fig_map, ax_map = plt.subplots(figsize=(8,4))
131
- mapa.boundary.plot(ax=ax_map, edgecolor="gray", linewidth=0.5)
132
- mapa.plot(column="count", ax=ax_map, cmap="OrRd", legend=True,
133
- missing_kwds={"color":"lightgrey"})
134
- ax_map.axis("off")
135
- st.pyplot(fig_map)
136
-
137
- # 4) Scatter: média por origem (count>=5)
138
- grp_ori = (
139
- df.groupby("origin")
140
- .agg(count=("rating","size"), mean_rating=("rating","mean"))
141
- .reset_index()
142
- )
143
- fil_ori = grp_ori.query("count>=5")
144
- fig_sc, ax_sc = plt.subplots()
145
- fig_sc = px.scatter(
146
- fil_ori, x="mean_rating", y="origin",
147
- size="count", color="origin",
148
- title="Avaliação Média vs Origem",
149
- labels={"mean_rating":"Avaliação Média","origin":"Origem"}
150
- )
151
- st.plotly_chart(fig_sc, use_container_width=True)
152
-
153
- # 5) WordCloud de empresas
154
- wc = WordCloud(width=800, height=300, background_color="white")
155
- freqs = df["company"].value_counts().to_dict()
156
- wc_img = wc.generate_from_frequencies(freqs)
157
- fig_wc, ax_wc = plt.subplots(figsize=(8,3))
158
- ax_wc.imshow(wc_img, interpolation="bilinear")
159
- ax_wc.axis("off")
160
- st.pyplot(fig_wc)
161
-
162
- # 6) ANOVA e Tukey
163
  paises = ["Brazil","France","U.S.A.","Canada","Ecuador","Peru","Venezuela"]
164
  filt = df[df.location.isin(paises)]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  melt = pd.melt(filt, id_vars=["location"], value_vars=["rating"])
166
  model = ols("value ~ C(location)", data=melt).fit()
167
  anova = sm.stats.anova_lm(model, typ=2)
168
  st.markdown("#### ANOVA")
169
  st.dataframe(anova)
170
 
171
- tukey = pairwise_tukeyhsd(endog=melt.value, groups=melt.location, alpha=0.05)
172
- st.markdown("#### Tukey HSD")
173
  st.text(tukey.summary())
174
 
175
- # 7) Diagnóstico de resíduos
 
176
  std_res = model.get_influence().resid_studentized_internal
177
  fig_qq = sm.qqplot(std_res, line="45", fit=True)
178
- plt.title("QQ-plot Resíduos Padronizados")
179
  st.pyplot(fig_qq)
180
 
181
  fig_h, ax_h = plt.subplots()
@@ -184,16 +192,34 @@ with tabs[1]:
184
  ax_h.set_xlabel("Resíduos"); ax_h.set_ylabel("Frequência")
185
  st.pyplot(fig_h)
186
 
187
- # 8) Testes de premissas
188
- st.markdown("#### Testes de Premissas")
189
- w, p_sh = shapiro(model.resid)
190
- st.write(f"Shapiro-Wilk: estatística={w:.3f}, p-valor={p_sh:.3f}")
 
 
 
191
  grupos = [filt.query("location==@loc").rating for loc in paises]
192
  w_lev, p_lev = levene(*grupos)
193
- st.write(f"Levene: estatística={w_lev:.3f}, p-valor={p_lev:.3f}")
194
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  kw_stat, kw_p = kruskal(*grupos)
196
- st.write(f"Kruskal-Wallis: estatística={kw_stat:.3f}, p-valor={kw_p:.3f}")
197
-
198
-
199
-
 
71
  with tabs[0]:
72
  st.subheader("Teste de Hipótese para Proporção de Testes Positivos de COVID-19")
73
  st.sidebar.markdown("### Parâmetros do Teste")
74
+ p_pop = st.sidebar.slider("Proporção populacional (H0)", 0.0, 1.0, 0.1, 0.01, key="p_pop")
75
+ p_sample = st.sidebar.slider("Proporção amostral", 0.0, 1.0, 0.12,0.01, key="p_sample")
76
+ n = st.sidebar.slider("Tamanho da amostra", 100, 10000, 1000, 10, key="n_sample")
77
+ alpha_prop = st.sidebar.slider("Nível de significância (α)", 0.01, 0.10, 0.05, 0.01, key="alpha_prop")
78
 
79
  se = np.sqrt(p_pop*(1-p_pop)/n)
80
  z = (p_sample - p_pop)/se
 
82
 
83
  st.write(f"**Z** = {z:.4f}")
84
  st.write(f"**p-valor** = {p_value:.4f}")
85
+ if p_value < alpha_prop:
86
  st.write("**Rejeitamos H0**: diferença significativa.")
87
  else:
88
  st.write("**Não rejeitamos H0**: sem diferença significativa.")
 
93
  fig = go.Figure()
94
  fig.add_trace(go.Scatter(x=x, y=y, mode="lines", line=dict(color="blue")))
95
  fig.add_vline(x=p_sample, line=dict(color="red", width=2))
96
+ zc = stats.norm.ppf(1-alpha_prop/2)
97
  fig.add_vrect(x0=p_pop-zc*se, x1=p_pop+zc*se, fillcolor="red", opacity=0.2, line_width=0)
98
  fig.update_layout(
99
  title="Distribuição Normal e Região Crítica",
 
104
 
105
  st.markdown("**Descrição**: Teste bilateral de proporções usando valor-p.")
106
 
107
+ # Aba 2: Análise de Chocolate (atualizada)
108
  with tabs[1]:
109
  st.subheader("Testes de Hipótese e ANOVA em Dados de Chocolate")
110
  st.markdown("---")
111
 
112
+ # parâmetro interativo de significância para chocolate
113
+ alpha_choc = st.sidebar.slider("Nível de significância (α) - ANOVA Chocolate", 0.01, 0.10, 0.05, 0.01, key="alpha_choc")
 
 
114
 
115
+ # 1) Carrega e renomeia dados
116
+ df = pd.read_csv("Dados/flavors_of_cacao.csv")
117
  df.columns = [
118
  "company","bean_bar_origin","ref","date",
119
  "percent","location","rating","beantype","origin"
120
  ]
121
+
122
+ # Filtra países
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  paises = ["Brazil","France","U.S.A.","Canada","Ecuador","Peru","Venezuela"]
124
  filt = df[df.location.isin(paises)]
125
+
126
+ # 2) Mapas Interativos — menu de seleção
127
+ st.markdown("#### Mapas Interativos")
128
+ map_type = st.selectbox(
129
+ "Selecione o mapa",
130
+ ["Empresas de Chocolate por País", "Plantações de Cacau por País"],
131
+ key="map_selector"
132
+ )
133
+
134
+ if map_type == "Empresas de Chocolate por País":
135
+ grp = df.groupby("location").size().reset_index(name="value")
136
+ locations = "location"
137
+ color_scale = "OrRd"
138
+ title = "Número de Empresas de Chocolate por País"
139
+ label = "# Empresas"
140
+ else:
141
+ grp = df.groupby("origin").size().reset_index(name="value")
142
+ locations = "origin"
143
+ color_scale = "Greens"
144
+ title = "Número de Plantações de Cacau por País"
145
+ label = "# Plantações"
146
+
147
+ fig_map = px.choropleth(
148
+ grp,
149
+ locations=locations,
150
+ locationmode="country names",
151
+ color="value",
152
+ color_continuous_scale=color_scale,
153
+ title=title,
154
+ labels={"value": label}
155
+ )
156
+ st.plotly_chart(fig_map, use_container_width=True)
157
+
158
+ # 3) Gráfico interativo de distribuição
159
+ plot_type = st.selectbox(
160
+ "Tipo de gráfico de distribuição",
161
+ ["Boxplot","Violin","Histograma"]
162
+ )
163
+ if plot_type == "Boxplot":
164
+ fig1 = px.box(filt, x="location", y="rating", title="Boxplot de Ratings")
165
+ elif plot_type == "Violin":
166
+ fig1 = px.violin(filt, x="location", y="rating", box=True, points="all", title="Violin Plot de Ratings")
167
+ else:
168
+ fig1 = px.histogram(filt, x="rating", color="location", barmode="overlay", title="Histograma de Ratings")
169
+ st.plotly_chart(fig1, use_container_width=True)
170
+
171
+ # 3) ANOVA + Tukey
172
  melt = pd.melt(filt, id_vars=["location"], value_vars=["rating"])
173
  model = ols("value ~ C(location)", data=melt).fit()
174
  anova = sm.stats.anova_lm(model, typ=2)
175
  st.markdown("#### ANOVA")
176
  st.dataframe(anova)
177
 
178
+ tukey = pairwise_tukeyhsd(endog=melt.value, groups=melt.location, alpha=alpha_choc)
179
+ st.markdown("#### Pós-hoc Tukey HSD")
180
  st.text(tukey.summary())
181
 
182
+ # 4) Diagnóstico de resíduos
183
+ st.markdown("#### Diagnóstico de Resíduos")
184
  std_res = model.get_influence().resid_studentized_internal
185
  fig_qq = sm.qqplot(std_res, line="45", fit=True)
186
+ plt.title("QQ-plot dos Resíduos Padronizados")
187
  st.pyplot(fig_qq)
188
 
189
  fig_h, ax_h = plt.subplots()
 
192
  ax_h.set_xlabel("Resíduos"); ax_h.set_ylabel("Frequência")
193
  st.pyplot(fig_h)
194
 
195
+ # Normalidade dos resíduos: Kolmogorov–Smirnov
196
+ ks_stat, ks_p = stats.kstest((model.resid - model.resid.mean())/model.resid.std(), "norm")
197
+ st.write(f"Kolmogorov–Smirnov (resíduos): estatística={ks_stat:.3f}, p-valor={ks_p:.3f}")
198
+ st.write("➡️ " + ("resíduos normais" if ks_p >= alpha_choc else "violação de normalidade"))
199
+
200
+ # 5) Homocedasticidade (Levene)
201
+ st.markdown("#### Homocedasticidade (Levene)")
202
  grupos = [filt.query("location==@loc").rating for loc in paises]
203
  w_lev, p_lev = levene(*grupos)
204
+ st.write(f"Levene: W={w_lev:.3f}, p-valor={p_lev:.3f}")
205
+ st.write("➡️ " + ("variâncias iguais" if p_lev >= alpha_choc else "variâncias diferentes"))
206
+
207
+ # 6) Testes Não Paramétricos Par a Par (Wilcoxon)
208
+ st.markdown("#### Testes Não Paramétricos Par a Par (Wilcoxon)")
209
+ col1, col2 = st.columns(2)
210
+ with col1:
211
+ g1 = st.selectbox("Grupo 1", paises, index=0)
212
+ with col2:
213
+ g2 = st.selectbox("Grupo 2", paises, index=1)
214
+ d1 = filt[filt.location==g1].rating.dropna().values
215
+ d2 = filt[filt.location==g2].rating.dropna().values
216
+ m = min(len(d1), len(d2))
217
+ w_stat, w_p = wilcoxon(d1[:m], d2[:m])
218
+ st.write(f"Wilcoxon signed-rank: W={w_stat:.3f}, p-valor={w_p:.3f}")
219
+ st.write("➡️ " + ("diferença significativa" if w_p < alpha_choc else "sem diferença significativa"))
220
+
221
+ # 7) Teste Kruskal–Wallis (todas as comparações)
222
+ st.markdown("#### Teste Kruskal–Wallis (todas as comparações)")
223
  kw_stat, kw_p = kruskal(*grupos)
224
+ st.write(f"KruskalWallis: estatística={kw_stat:.3f}, p-valor={kw_p:.3f}")
225
+ st.write("➡️ " + ("distribuições diferentes" if kw_p < alpha_choc else "mesma distribuição"))