Como funciona?
O primeiro passo do algoritmo consiste no pré-processamento do texto de entrada, que é normalizado para minúsculas e todas as pontuações, acentos e espaços excedentes são removidos do conteúdo. Depois disso, o texto é tokenizado e as palavras irrelevantes (stopwords) também são removidas. A última etapa de preparação consiste na substituição de algumas gírias da internet por seus respectivos sinônimos "formais". Essa lógica de substituição utiliza uma versão aprimorada do dicionário léxico desenvolvido no projeto UGCNormal.
Depois disso, um algoritmo de coocorrência lexical simples é utilizado para "quebrar" o texto em uma lista de n-gramas, cujo comprimento está baseado no parâmetro coocurrenceWindow
. Desta forma, a seguinte estrutura de grafo é gerada tomando como base essa lista de n-gramas:
{
"vertex": {
"[token]": {
"[token]": "boolean"
}
},
"nodes": {
"[token]": "frequency"
},
"edges": {
"[token]": {
"[token]": "frequency"
}
}
}
O vertex
é um objeto que representa as coocorrências de tokens (vértices). O objeto nodes
salva as frequências de todos os tokens. Por último, as edges
(arestas) representam as relações entre os nós, que são ponderadas pela frequência de coocorrência.
Por último, a função generateLCN
gera uma string
que segue a dot language, um formato de representação de grafos compatível com Graphviz.
Como utilizar
Esse projeto não possui dependências do NPM, mas você deve ter o Node.js versão 12+ para utilizá-lo. O trecho de código a seguir apresenta um exemplo de uso:
//example.js
const fs = require("fs");
const generateLCN = require("./generate-lcn");
// Chico Buarque's song "Construção".
const construcaoTxt = "Amou daquela vez como se fosse a última [...]";
const outputDotFile = generateLCN({
// Defines the coocurrence window (optional value, default is 4).
coocurrenceWindow: 2,
// Defines the number of edges a vertex can have, ordered by the
// coocurrence frequency (optional value, default is 1).
maxEdges: 2,
// The threshold frequency for a token to be included
// in the graph (optional value, default is 1).
minFrequency: 1,
// Limits the number of nodes by this number, ordered by
// the token frequency (optional value, default is Infinity).
nodeLimit: 100,
// The input text for the algorithm. It should have at least
// 50 words for the algorithm to behave accordingly (required value).
inputText: construcaoTxt,
});
fs.writeFileSync("example.dot", outputDotFile);
Esse trecho de código pega a letra da música de Chico Buarque e grava a rede de palavras resultante no arquivo example.dot
. Se renderizado no Graphviz, deve gerar o seguinte grafo (o tamanho do texto é de acordo com a frequência da palavra em questão):
Possíveis melhorias
Atualmente, esse algoritmo não determina a posição de renderização dos elementos da rede. Utilizar um algoritmo direcionado por força poderia melhorar a capacidade de representação do gráfico. O ideal é que o parâmetro inputText
não esperasse uma string
, pois um vetor de strings
faria mais sentido para um dataset de textos. Um algoritmo de relevância também poderia ser muito melhor do que utilizar a frequência das palavras para determinar o tamanho da fonte do gráfico. Além disso, há espaço para muitas otimizações de desempenho no código.
Código-fonte
Esse projeto é software livre e de código aberto, estando disponível no GitHub (text-network-pt-br-ugc) sob licença GPL 3.0.