Análise de ONA para Identificação de Key Talents
Mapeamento de redes organizacionais para identificar talentos críticos, influenciadores e gargalos de conhecimento em uma organização global.
Demonstração do projeto
Na Vale, identificamos que os critérios tradicionais de "high performer" (desempenho individual em avaliações 9-box) não capturavam uma dimensão crítica: o papel de cada pessoa na rede de conhecimento da organização. Usamos Organizational Network Analysis (ONA) para mapear quem é consultado, quem conecta times e quem retém conhecimento crítico — revelando talentos invisíveis nos processos formais e riscos de conhecimento em colaboradores próximos à saída.
Impacto & Métricas
1.200
Colaboradores mapeados
14
Comunidades identificadas
38
Brokers críticos encontrados
12%
Talentos não reconhecidos formalmente
6
Países cobertos
Por que ONA?
As avaliações formais de desempenho capturam o que uma pessoa entrega individualmente.
A ONA captura como ela opera dentro da rede — quem ela conecta, quem depende dela,
quem ela desenvolve. Esses dois eixos juntos revelam o real impacto organizacional.
Coleta de Dados
Os dados de colaboração foram coletados de 3 fontes:
1. E-mail e calendário (Microsoft Graph API): frequência e direção das comunicações
2. Pesquisa de rede (questionário dirigido): "A quem você recorre quando precisa de
ajuda técnica? A quem você recorreria para entender processos da empresa?"
3. Dados de projetos (JIRA/Confluence): co-autoria de documentos e issues
Construção do Grafo
Cada colaborador é um nó. Cada interação é uma aresta ponderada.
O peso é calculado por frequência e reciprocidade da interação.
Calculamos 3 métricas principais:
- Betweenness Centrality: identifica quem faz a ponte entre grupos (brokers)
- In-Degree Centrality: quem é mais consultado (especialistas)
- PageRank: influência ponderada pela influência de quem te consulta
Descobertas e Ações
14 comunidades orgânicas foram identificadas, muitas não alinhadas com org chart formal.
38 colaboradores classificados como "Broker Crítico" — apenas 11 estavam no plano de
sucessão. Os outros 27 representavam riscos de conhecimento não gerenciados.
O projeto gerou uma revisão do programa de retenção e um protocolo de
"knowledge transfer" para brokers com alto risco de saída.
import networkx as nx
import pandas as pd
from collections import defaultdict
def build_organizational_network(
collaboration_data: pd.DataFrame,
min_interactions: int = 3,
) -> nx.DiGraph:
"""
Constrói grafo direcionado de colaboração a partir de dados de interação.
Args:
collaboration_data: DataFrame com colunas [source_id, target_id, weight]
min_interactions: filtro mínimo para eliminar ruído
Returns:
DiGraph ponderado com atributos de centralidade calculados
"""
# Filtrar interações fracas
filtered = collaboration_data[
collaboration_data["weight"] >= min_interactions
]
G = nx.from_pandas_edgelist(
filtered,
source="source_id",
target="target_id",
edge_attr="weight",
create_using=nx.DiGraph(),
)
# Calcular métricas de centralidade
betweenness = nx.betweenness_centrality(G, weight="weight", normalized=True)
in_degree = nx.in_degree_centrality(G)
pagerank = nx.pagerank(G, weight="weight", alpha=0.85)
# Adicionar atributos aos nós
nx.set_node_attributes(G, betweenness, "betweenness_centrality")
nx.set_node_attributes(G, in_degree, "in_degree_centrality")
nx.set_node_attributes(G, pagerank, "pagerank_score")
return G
def identify_key_roles(G: nx.DiGraph) -> pd.DataFrame:
"""
Classifica nós em papéis organizacionais com base em métricas de centralidade.
Papéis:
- Broker: alta betweenness, conecta silos
- Influenciador: alto in-degree, muito consultado
- Periférico: baixa conectividade, risco de isolamento
"""
records = []
for node, data in G.nodes(data=True):
betweenness = data.get("betweenness_centrality", 0)
in_degree = data.get("in_degree_centrality", 0)
pagerank = data.get("pagerank_score", 0)
if betweenness > 0.15:
role = "Broker Crítico"
elif in_degree > 0.20:
role = "Influenciador"
elif pagerank < 0.005:
role = "Periférico"
else:
role = "Colaborador"
records.append({
"employee_id": node,
"network_role": role,
"betweenness": betweenness,
"in_degree": in_degree,
"pagerank": pagerank,
})
return pd.DataFrame(records).sort_values("betweenness", ascending=False)import networkx as nx
import pandas as pd
from collections import defaultdict
def build_organizational_network(
collaboration_data: pd.DataFrame,
min_interactions: int = 3,
) -> nx.DiGraph:
"""
Constrói grafo direcionado de colaboração a partir de dados de interação.
Args:
collaboration_data: DataFrame com colunas [source_id, target_id, weight]
min_interactions: filtro mínimo para eliminar ruído
Returns:
DiGraph ponderado com atributos de centralidade calculados
"""
# Filtrar interações fracas
filtered = collaboration_data[
collaboration_data["weight"] >= min_interactions
]
G = nx.from_pandas_edgelist(
filtered,
source="source_id",
target="target_id",
edge_attr="weight",
create_using=nx.DiGraph(),
)
# Calcular métricas de centralidade
betweenness = nx.betweenness_centrality(G, weight="weight", normalized=True)
in_degree = nx.in_degree_centrality(G)
pagerank = nx.pagerank(G, weight="weight", alpha=0.85)
# Adicionar atributos aos nós
nx.set_node_attributes(G, betweenness, "betweenness_centrality")
nx.set_node_attributes(G, in_degree, "in_degree_centrality")
nx.set_node_attributes(G, pagerank, "pagerank_score")
return G
def identify_key_roles(G: nx.DiGraph) -> pd.DataFrame:
"""
Classifica nós em papéis organizacionais com base em métricas de centralidade.
Papéis:
- Broker: alta betweenness, conecta silos
- Influenciador: alto in-degree, muito consultado
- Periférico: baixa conectividade, risco de isolamento
"""
records = []
for node, data in G.nodes(data=True):
betweenness = data.get("betweenness_centrality", 0)
in_degree = data.get("in_degree_centrality", 0)
pagerank = data.get("pagerank_score", 0)
if betweenness > 0.15:
role = "Broker Crítico"
elif in_degree > 0.20:
role = "Influenciador"
elif pagerank < 0.005:
role = "Periférico"
else:
role = "Colaborador"
records.append({
"employee_id": node,
"network_role": role,
"betweenness": betweenness,
"in_degree": in_degree,
"pagerank": pagerank,
})
return pd.DataFrame(records).sort_values("betweenness", ascending=False)