Spaces:
Sleeping
Sleeping
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
|
| 75 |
-
p_sample
|
| 76 |
-
n
|
| 77 |
-
|
| 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 <
|
| 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-
|
| 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 |
-
#
|
| 113 |
-
|
| 114 |
-
st.markdown("#### Dados Brutos")
|
| 115 |
-
st.dataframe(df)
|
| 116 |
|
| 117 |
-
#
|
|
|
|
| 118 |
df.columns = [
|
| 119 |
"company","bean_bar_origin","ref","date",
|
| 120 |
"percent","location","rating","beantype","origin"
|
| 121 |
]
|
| 122 |
-
|
| 123 |
-
|
| 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=
|
| 172 |
-
st.markdown("#### Tukey HSD")
|
| 173 |
st.text(tukey.summary())
|
| 174 |
|
| 175 |
-
#
|
|
|
|
| 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 |
-
#
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
st.write(
|
|
|
|
|
|
|
|
|
|
| 191 |
grupos = [filt.query("location==@loc").rating for loc in paises]
|
| 192 |
w_lev, p_lev = levene(*grupos)
|
| 193 |
-
st.write(f"Levene:
|
| 194 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
kw_stat, kw_p = kruskal(*grupos)
|
| 196 |
-
st.write(f"Kruskal
|
| 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"Kruskal–Wallis: 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"))
|
|
|
|
|
|