Entity Linker

Índice


O que é Entity Linking

Entity Linking é o processo de mapear menções textuais livres (extraídas por modelos de linguagem) a partir de currículos e vagas para entidades canônicas em uma base de conhecimento estruturada. No sistema, essa etapa vincula termos como "Python", "Comunicação" ou "Power BI" aos respectivos conceitos na ontologia ESCO.

O Entity Linker implementado no serviço processor-entity-linker que recebe os termos candidatos gerados pelo modelo de linguagem e identifica, para cada candidato, o conceito correspondente na ontologia ESCO.

LLM extrai: "Python"
Entity Linker resolve: "Python" -(fuzzy match)-> "Python (programação informática)" (score = 1.0)

LLM extrai: "Comunicação"
Entity Linker resolve: "Comunicação" -(KNN + PPR)-> "comunicar com colegas e clientes" (score = 0.66)

LLM extrai: "Power BI"
Entity Linker resolve: "Power BI" -(fuzzy match)-> SkillCustom (termo não identificado na ontologia)

Como Funciona

Eventos processados pelo serviço:

DireçãoEventoConteúdo
ConsumidorOpportunitySkillCandidateExtractedLista de candidatos com type (hard/soft/knowledge) para uma vaga
ConsumidorResumeSkillCandidateExtractedLista de candidatos com type (hard/soft/knowledge) para um currículo
ProdutorOpportunitySkillLinkedSkill da vaga vinculada a um conceito da ESCO
ProdutorOpportunitySkillCustomSkill da vaga sem correspondência na ESCO
ProdutorResumeSkillLinkedSkill do currículo vinculada a um conceito da ESCO
ProdutorResumeSkillCustomSkill do currículo sem correspondência na ESCO
ProdutorEntityLinkingAnalysisRecordedResultado intermediário do processo de ancoragem com a ESCO (fuzzy, KNN e PPR) persistido para posterior análise humana
Custom Skill

As habilidades classificadas como Custom Skill não são descartadas. Elas são persistidas no Neo4j sob o tipo do nó (:CustomSkill) e podem representar termos legítimos ainda não catalogados na ontologia ESCO, comuns no mercado de trabalho de tecnologia, porém elas também podem representar alucinações do modelo generativo.

Escolhas de Implementação

Roteamento do método de ancoragem por tipo de competência: as hard skills são processadas inicialmente pelo FuzzyMatcher (com limiar de 0,9), com redirecionamento para o método Duplo Diamante apenas se a pontuação obtida for menor que o limiar. As soft skills e as áreas de conhecimento são enviadas diretamente para o método Duplo Diamante. Esse fluxo compensa a assimetria de representação dos embeddings da ontologia ESCO, cujo índice foi gerado utilizando o formato {label}\n{description}\n{alt_labels}, enquanto a busca em tempo de execução utiliza somente o texto extraído da skill. Essa diferença de formato reduz a similaridade de termos curtos e canônicos, como "Python", no espaço vetorial.

Pesos uniformes 1/K no vetor de personalização do PPR: em vez de adotar os valores de similaridade de cosseno do KNN como pesos (devido à proximidade numérica desses valores entre posições adjacentes no ranking), distribui-se peso igual entre os candidatos. Esse procedimento impede que pequenas variações na métrica de cosseno influenciem excessivamente o resultado do Personalized PageRank (PPR).

Fórmula de pontuação final (PPR / PR_global) * cosine_similarity: o valor bruto do PPR é normalizado pela divisão pelo PageRank global de cada nó e, em seguida, multiplicado pela similaridade de cosseno. Essa normalização reduz a influência de nós centrais (hubs) na ontologia (conceitos com alto grau de conectividade que receberiam pontuações elevadas independentemente da pertinência direta com a consulta).


Fuzzy Matching (Hard Skills)

O FuzzyMatcher carrega as propriedades preferredLabel do dataset digitalSkillsCollection_pt.csv em memória durante a inicialização do serviço. A busca textual utiliza o algoritmo token_set_ratio da biblioteca RapidFuzz, que ignora a ordenação das palavras e suporta substrings:

ScorerExemploPontuação Esperada
token_set_ratio"Python" vs "Python (Linguagem de Programação)"100
token_set_ratio"design responsivo" vs "responsive design"100
token_set_ratio"Docker" vs "Docker"100

O fluxo de comparação para as hard skills é estruturado em três níveis de contingência:

  1. Correspondência exata (case-insensitive) -> score = 1.00
  2. Busca difusa (token_set_ratio >= 0.9) -> score = [0.9 .. 0.99]
  3. Fallback (score < 0.9) -> redireciona para método de Duplo Diamante

Método Duplo Diamante (KNN e PPR)

KNN (Expansão Semântica)

O vetor de embedding da skill candidata (768 dimensões, gerado pelo Ollama com o modelo embeddinggemma) é comparado com o índice vetorial HNSW do Neo4j. O índice retorna os K nós (:Skill) com maior similaridade de cosseno, que constituem o conjunto inicial de candidatos.

PPR (Convergência Topológica)

Utilizando os candidatos retornados pelo KNN como nós de ativação inicial (seeds), o algoritmo Personalized PageRank navega pelo grafo de conhecimento por meio dos relacionamentos ([:BROADER], [:NARROWER] e [:ESSENTIAL]) e também através do teleporte. Os candidatos que apresentam maior proximidade topológica em relação à vizinhança ativa obtêm pontuações mais elevadas. O nó com maior pontuação calculada é selecionado para o vínculo.

AspectoKNN (Expansão)PPR (Convergência)
ObjetivoIdentificar candidatos potenciaisSelecionar nó com maior coerência topológica
EntradaEmbedding de 768 dimensõesCandidatos do KNN e topologia do grafo
MétricaSimilaridade de cossenoPontuação do PageRank personalizado
RequisitosÍndice vetorial do Neo4jNeo4j Graph Data Science (GDS)

Abaixo o fluxo completo do método Duplo Diamante:

1. Limiar do KNN: os candidatos retornados pelo índice HNSW são filtrados com base em um valor limite de similaridade de cosseno (definido em knn_pruning). Candidatos com valores inferiores são excluídos antes da execução do PPR para evitar distorções na propagação de pesos.

2. Distribuição de pesos uniformes: para neutralizar diferenças pequenas nas pontuações de similaridade de cosseno entre candidatos adjacentes, adota-se um vetor de personalização com pesos uniformes equivalentes a 1/K1/K para todos os nós sementes. Esse ajuste previne que flutuações discretas da similaridade semântica determinem o resultado da análise topológica.

3. Execução do PPR: o algoritmo é executado utilizando a biblioteca Neo4j Graph Data Science (GDS) por meio do procedimento gds.pageRank.stream com o parâmetro sourceNodes. A distribuição de probabilidade propaga-se a partir dos nós sementes pelas conexões da ontologia.

4. Normalização pelo PageRank global: a pontuação obtida pelo PPR é dividida pelo PageRank global correspondente a cada nó (calculado previamente sem personalização). Essa etapa reduz a pontuação de conceitos que possuem alta centralidade na ontologia (nós de alto grau de entrada e saída), os quais tenderiam a atrair peso independentemente do contexto específico da busca.

5. Ponderação final: o resultado da análise topológica é multiplicado pelo valor original da similaridade de cosseno:

score_final = (PPR / PR_global) * cosine_similarity

Evolução do processor-entity-linker

O algoritmo de vinculação foi desenvolvido em três etapas distintas:

Fase 1 - String Matching com RapidFuzz

Abordagem inicial baseada na comparação hierárquica de strings com a biblioteca RapidFuzz utilizando a métrica fuzz.ratio (desempenho médio de 135 milhões de operações por segundo).

O fluxo de comparação ocorria em quatro níveis:

  1. Correspondência exata (score = 1.00)
  2. Correspondência insensível a maiúsculas (score = 0.95)
  3. Correspondência difusa (distância de Levenshtein normalizada) com limiar de 0.85
  4. Ausência de correspondência (classificação como CustomSkill)

A função fuzz.ratio foi selecionada devido à sua sensibilidade em relação à ordem das palavras (por exemplo, diferenciação entre "Python Developer" e "Developer Python").

Fase 2 - Modelo Duplo Diamante

Substituição da lógica estritamente lexical por um modelo semântico estruturado em duas etapas:

Expansão (KNN): conversão da competência candidata em um vetor de 768 dimensões. A busca KNN no índice HNSW do Neo4j identifica os K candidatos com maior similaridade de cosseno, visando maximizar o índice de recuperação (recall).

Convergência (PPR): reordenação dos candidatos obtidos por meio do algoritmo Personalized PageRank (PPR) no grafo de conhecimento, utilizando as relações de dependência [:BROADER], [:NARROWER] e [:ESSENTIAL] e o mecanismo de teleporte para assegurar a coerência conceitual.

Esse método permite associar termos semanticamente semelhantes que não possuem correspondência textual direta, como "Dev" e "Desenvolvedor".

Fase 3 - Especialização por Tipo de Competência

Identificou-se uma redução na precisão do modelo Duplo Diamante para hard skills representadas por termos curtos e padronizados, tais como "Python" ou "DevOps". A discrepância ocorreu porque os embeddings armazenados foram gerados com o formato {label}\n{description}\n{alt_labels}, ao passo que a consulta em execução utiliza apenas o texto cru do termo extraído, gerando assimetria na representação vetorial.

A solução implementada consiste no roteamento conforme a categoria da competência no método resolve:

  • Hard skills: são processadas preliminarmente pelo FuzzyMatcher. Se a pontuação obtida for maior ou igual a 0.9, a associação é concluída. Caso contrário, aplica-se o método double_diamond (KNN e PPR).
  • Soft skills e áreas de conhecimento: são direcionadas diretamente para o método double_diamond.

Demonstração

Os exemplos apresentados a seguir foram extraídos de execuções do componente com os seguintes parâmetros de configuração:

ComponenteParâmetroValor
Fuzzythreshold0.9
KNNthreshold0.72
KNNtop_k10
PPRdamping0.6
PPRiterations25
PPRthreshold0.59

Hard Skill: Aceita pelo FuzzyMatcher

A skill "SQL" é identificada como correspondência exata na ontologia. O processamento por busca difusa resolve o termo com pontuação máxima, sem executar as etapas de KNN e PPR:

{
  "target_skill": "SQL",
  "target_skill_type": "hard",
  "fuzzy": {
    "uri": "http://data.europa.eu/esco/skill/598de5b0-5b58-4ea7-8058-a4bc4d18c742",
    "label": "SQL",
    "score": 1
  },
  "knn": [],
  "ppr": []
}

Hard Skill: Falhou no FuzzyMatcher e resolvida pelo método Duplo Diamante

A expressão "Open-Source Projects" não possui correspondência textual direta. O módulo de comparação difusa retorna nulo, acionando a busca semântica do KNN e a convergência topológica do PPR para localizar o nó correspondente na estrutura do grafo:

{
  "target_skill": "Open-Source Projects",
  "target_skill_type": "hard",
  "fuzzy": null,
  "knn": [
    { "label": "programar software de código-fonte aberto", "score": 0.760 },
    { "label": "modelo open source",                        "score": 0.756 },
    { "label": "dirigir, supervisionar e coordenar projetos", "score": 0.725 }
  ],
  "ppr": [
    { "label": "programar software de código-fonte aberto", "score": 0.662 }
  ]
}

A etapa do PPR descartou os candidatos "modelo open source" e "coordenar projetos" em virtude da distância topológica na ontologia em relação ao conceito mais próximo. O resultado final corresponde ao nó selecionado no segundo estágio do fluxo.

Soft Skill: Método Duplo Diamante com Múltiplos Candidatos

O termo "Gestão de Stakeholders" não possui correspondência textual direta na ontologia. A busca KNN retorna dez candidatos relacionados ao termo "gestão", enquanto o PPR atua na filtragem com base na estrutura de relações, identificando os dois conceitos mais próximos:

{
  "target_skill": "Gestão de Stakeholders",
  "target_skill_type": "soft",
  "fuzzy": null,
  "knn": [
    { "label": "competências de gestão",                  "score": 0.778 },
    { "label": "competências de gestão",                  "score": 0.778 },
    { "label": "competências de gestão",                  "score": 0.776 },
    { "label": "gerir e administrar recursos humanos",    "score": 0.764 },
    { "label": "gerir o sistema de gestão ambiental",     "score": 0.754 }
  ],
  "ppr": [
    { "label": "gerir e administrar recursos humanos",    "score": 0.655 },
    { "label": "gerir o sistema de gestão ambiental",     "score": 0.633 }
  ]
}

Os três nós com a descrição "competências de gestão" identificados no KNN correspondem a registros distintos com diferentes URIs. Após a execução do PPR, estes nós são descartados. Apesar da similaridade de cosseno elevada, são classificados como hubs com alto grau de conectividade, sendo penalizados pelo fator de normalização entre o PPR e o PageRank global.

Knowledge Skill: PPR Reordena o KNN

A entrada "Gerenciamento de Projetos" ilustra a reordenação promovida pelo PPR sobre o ranking inicial do KNN. O candidato posicionado em oitavo lugar na busca por similaridade é reordenado para a primeira posição após a análise topológica:

{
  "target_skill": "Gerenciamento de Projetos",
  "target_skill_type": "knowledge",
  "knn": [
    { "label": "dirigir, supervisionar e coordenar projetos",  "score": 0.821 },
    { "label": "gestão de projetos informáticos",              "score": 0.818 },
    { "label": "gestão ágil de projetos",                      "score": 0.816 },
    { "label": "gestão de projetos lean",                      "score": 0.815 },
    { "label": "metodologias de gestão de projetos de informática", "score": 0.797 },
    { "label": "gestão de projetos Prince2",                   "score": 0.792 },
    { "label": "gestão de processos",                          "score": 0.791 },
    { "label": "gerir projetos de desenvolvimento de conteúdos", "score": 0.787 }
  ],
  "ppr": [
    { "label": "gerir projetos de desenvolvimento de conteúdos", "score": 0.918 },
    { "label": "gerir um repositório central de projetos",       "score": 0.811 },
    { "label": "dirigir, supervisionar e coordenar projetos",    "score": 0.702 },
    { "label": "gestão de projetos informáticos",               "score": 0.591 }
  ]
}

O conceito "Gerir projetos de desenvolvimento de conteúdos", posicionado em oitavo lugar no KNN (similaridade de 0,787), obteve pontuação PPR de 0,918. Esse valor indica maior centralidade topológica do nó em relação aos demais candidatos na subestrutura de gestão de projetos da ontologia.

Custom Skills: Limitações do Sistema

Apresentam-se a seguir dois cenários em que o vínculo não é estabelecido devido a limitações estruturais distintas:

Inconsistência na classificação de categoria pelo extrator de habilidades: o termo "Desenvolvimento iOS" foi classificado como do tipo knowledge em vez de hard. O KNN retorna apenas um candidato acima do limiar estabelecido, e a estrutura local do grafo não fornece conexões suficientes para a propagação no PPR, resultando em uma CustomSkill.

Ausência do conceito na ontologia: o termo "TensorFlow" não está catalogado na base ESCO (versão de 2023). Nenhum candidato atinge os limiares mínimos de similaridade na busca difusa ou no KNN, classificando o termo como CustomSkill.

Embora ambos os cenários resultem em uma CustomSkill, as causas são distintas. O primeiro decorre de uma inconsistência de classificação no estágio anterior de extração, enquanto o segundo indica limitação de cobertura da base de conhecimento. Os registros de processamento são persistidos para subsidiar futuras análises e updates da base.


ADRs Relacionadas

IdentificadorDataDescrição da Decisão
ADR-014Janeiro de 2026Adoção da biblioteca RapidFuzz como mecanismo inicial de vinculação.
ADR-034Abril de 2026Implementação do fluxo de dois estágios (KNN e PPR).
ADR-045Junho de 2026Configuração de roteamento dual por categoria de skill.