Análise Temática do Dataset GovBrNews¶
Parte 2 do guia de exploração do dataset - Análise de distribuição por tema, temporal e por órgão governamental.
Nível: Intermediário Tempo estimado: 45-60 minutos Pré-requisitos: Conclusão da Parte 1, Python com Pandas
Parte 2: Análise Temática (Intermediário)¶
Distribuição por Tema¶
O dataset usa um sistema de classificação hierárquica com 3 níveis:
flowchart TD
subgraph "Exemplo de Hierarquia"
A[Nível 1: Saúde] --> B[Nível 2: Vigilância Sanitária]
A --> C[Nível 2: Atenção Primária]
B --> D[Nível 3: Fiscalização de Alimentos]
B --> E[Nível 3: Controle de Medicamentos]
C --> F[Nível 3: Vacinação]
C --> G[Nível 3: Saúde da Família]
end
Análise de Temas por Nível¶
import matplotlib.pyplot as plt
import seaborn as sns
# Configurar estilo
plt.style.use('seaborn-v0_8-whitegrid')
fig, axes = plt.subplots(1, 3, figsize=(18, 6))
# Nível 1
theme_1 = df['theme_1_level_1'].value_counts().head(10)
theme_1.plot(kind='barh', ax=axes[0], color='steelblue')
axes[0].set_title('Top 10 Temas - Nível 1')
axes[0].set_xlabel('Quantidade de Notícias')
# Nível 2
theme_2 = df['theme_1_level_2'].value_counts().head(10)
theme_2.plot(kind='barh', ax=axes[1], color='coral')
axes[1].set_title('Top 10 Temas - Nível 2')
axes[1].set_xlabel('Quantidade de Notícias')
# Nível 3
theme_3 = df['theme_1_level_3'].value_counts().head(10)
theme_3.plot(kind='barh', ax=axes[2], color='seagreen')
axes[2].set_title('Top 10 Temas - Nível 3')
axes[2].set_xlabel('Quantidade de Notícias')
plt.tight_layout()
plt.savefig('distribuicao_temas.png', dpi=150, bbox_inches='tight')
plt.show()
Visualização Interativa com Altair¶
import altair as alt
# Preparar dados
theme_counts = df['theme_1_level_1'].value_counts().reset_index()
theme_counts.columns = ['tema', 'quantidade']
# Criar gráfico interativo
chart = alt.Chart(theme_counts).mark_bar().encode(
x=alt.X('quantidade:Q', title='Quantidade de Notícias'),
y=alt.Y('tema:N', sort='-x', title='Tema'),
color=alt.Color('quantidade:Q', scale=alt.Scale(scheme='blues')),
tooltip=['tema', 'quantidade']
).properties(
title='Distribuição de Notícias por Tema (Nível 1)',
width=600,
height=400
).interactive()
chart.save('distribuicao_temas_interativo.html')
chart
Treemap com Plotly¶
import plotly.express as px
# Preparar dados hierárquicos
df_treemap = df.groupby(
['theme_1_level_1', 'theme_1_level_2']
).size().reset_index(name='count')
fig = px.treemap(
df_treemap,
path=['theme_1_level_1', 'theme_1_level_2'],
values='count',
title='Hierarquia Temática das Notícias',
color='count',
color_continuous_scale='Blues'
)
fig.update_layout(width=900, height=600)
fig.write_html('treemap_temas.html')
fig.show()
Análise Temporal¶
Tendências por Mês/Ano¶
# Extrair componentes temporais
df['year'] = df['published_at'].dt.year
df['month'] = df['published_at'].dt.month
df['year_month'] = df['published_at'].dt.to_period('M')
# Publicações por mês
monthly_counts = df.groupby('year_month').size()
# Visualizar com Matplotlib
fig, ax = plt.subplots(figsize=(14, 6))
monthly_counts.plot(kind='line', ax=ax, color='steelblue', linewidth=2)
ax.set_title('Volume de Publicações ao Longo do Tempo')
ax.set_xlabel('Período')
ax.set_ylabel('Quantidade de Notícias')
ax.fill_between(range(len(monthly_counts)), monthly_counts.values, alpha=0.3)
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('tendencia_temporal.png', dpi=150, bbox_inches='tight')
plt.show()
Heatmap de Publicações por Tema e Ano¶
# Criar tabela pivot
pivot_tema_ano = df.pivot_table(
index='theme_1_level_1',
columns='year',
values='unique_id',
aggfunc='count',
fill_value=0
)
# Heatmap com Seaborn
fig, ax = plt.subplots(figsize=(12, 10))
sns.heatmap(
pivot_tema_ano,
annot=True,
fmt='d',
cmap='YlOrRd',
ax=ax,
cbar_kws={'label': 'Quantidade'}
)
ax.set_title('Publicações por Tema e Ano')
ax.set_xlabel('Ano')
ax.set_ylabel('Tema')
plt.tight_layout()
plt.savefig('heatmap_tema_ano.png', dpi=150, bbox_inches='tight')
plt.show()
Visualização Temporal Interativa com Plotly¶
import plotly.express as px
# Preparar dados mensais por tema
df['year_month_str'] = df['year_month'].astype(str)
monthly_by_theme = df.groupby(
['year_month_str', 'theme_1_level_1']
).size().reset_index(name='count')
# Top 5 temas para visualização
top_themes = df['theme_1_level_1'].value_counts().head(5).index.tolist()
monthly_top = monthly_by_theme[
monthly_by_theme['theme_1_level_1'].isin(top_themes)
]
fig = px.line(
monthly_top,
x='year_month_str',
y='count',
color='theme_1_level_1',
title='Evolução Temporal dos Top 5 Temas',
labels={
'year_month_str': 'Período',
'count': 'Quantidade',
'theme_1_level_1': 'Tema'
}
)
fig.update_layout(width=1000, height=500, xaxis_tickangle=-45)
fig.write_html('evolucao_temas.html')
fig.show()
Análise por Órgão Governamental¶
Distribuição de Publicações por Órgão¶
# Top 20 órgãos
top_agencies = df['agency'].value_counts().head(20)
fig, ax = plt.subplots(figsize=(12, 8))
top_agencies.plot(kind='barh', ax=ax, color='darkblue')
ax.set_title('Top 20 Órgãos por Volume de Publicações')
ax.set_xlabel('Quantidade de Notícias')
ax.set_ylabel('Órgão')
ax.invert_yaxis()
# Adicionar valores nas barras
for i, v in enumerate(top_agencies.values):
ax.text(v + 100, i, f'{v:,}', va='center', fontsize=9)
plt.tight_layout()
plt.savefig('top_orgaos.png', dpi=150, bbox_inches='tight')
plt.show()
Matriz Órgão x Tema¶
# Top 10 órgãos e temas
top_10_agencies = df['agency'].value_counts().head(10).index.tolist()
top_10_themes = df['theme_1_level_1'].value_counts().head(10).index.tolist()
# Filtrar dados
df_filtered = df[
(df['agency'].isin(top_10_agencies)) &
(df['theme_1_level_1'].isin(top_10_themes))
]
# Criar matriz
matrix = df_filtered.pivot_table(
index='agency',
columns='theme_1_level_1',
values='unique_id',
aggfunc='count',
fill_value=0
)
# Heatmap
fig, ax = plt.subplots(figsize=(14, 10))
sns.heatmap(
matrix,
annot=True,
fmt='d',
cmap='Blues',
ax=ax,
linewidths=0.5
)
ax.set_title('Matriz: Órgão x Tema (Top 10)')
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.savefig('matriz_orgao_tema.png', dpi=150, bbox_inches='tight')
plt.show()
Sunburst Interativo com Plotly¶
import plotly.express as px
# Preparar dados agregados
df_sunburst = df.groupby(
['theme_1_level_1', 'agency']
).size().reset_index(name='count')
# Filtrar para top órgãos
df_sunburst = df_sunburst[df_sunburst['agency'].isin(top_10_agencies)]
fig = px.sunburst(
df_sunburst,
path=['theme_1_level_1', 'agency'],
values='count',
title='Distribuição Hierárquica: Tema e Órgão',
color='count',
color_continuous_scale='Blues'
)
fig.update_layout(width=800, height=800)
fig.write_html('sunburst_tema_orgao.html')
fig.show()
Navegação¶
| Parte | Conteúdo | Nível |
|---|---|---|
| Parte 1: Básico | Estrutura, Carregamento e Análise Exploratória Básica | Iniciante |
| Parte 2 (esta página) | Distribuição por Tema, Análise Temporal, Órgãos | Intermediário |
| Parte 3: Análise de Texto | Estatísticas de Texto, Nuvem de Palavras, Exercícios | Intermediário |
Próximos Passos¶
Continue para a Parte 3: Análise de Texto para aprender sobre estatísticas de texto, nuvens de palavras e exercícios práticos.
Anterior: Parte 1: Básico
Próximo: Análise de Texto