Article by Rafał Rybnik, Chefe de Desenvolvimento de Software em Instytut Badań Pollster
Quer seja um escritor, cientista de dados ou apenas a folhear fontes para fazer um trabalho, lendo textos mais longos para arrancar migalhas de informação podem ser bastante cansativos. A automatização de tais elementos de o seu trabalho permite-lhe concentrar-se no lado criativo das coisas.

Salvo indicação em contrário, todas as fotografias do artigo são da autoria do mesmo.
O resumo do texto é a técnica de extracção de elementos informativos chave de um texto volumoso. Manual resumir o texto é uma tarefa difícil e de custo reduzido, pelo que o Processamento de Linguagem Natural e os algoritmos de aprendizagem automática se tornaram popular para a automatizar.
Existem soluções prontas no mercado, quer sob a forma de bibliotecas ou de ferramentas prontas para os utilizadores finais.
Neste artigo, iremos preparar a nossa própria solução à medida, que ao mesmo tempo não requer conhecimentos avançados de ciência de dados.
NLP Cloud é um fornecedor de múltiplas APIs para processamento de texto utilizando modelos de aprendizagem por máquina. Um deles é o sumarizador de texto, que parece promissor em termos de simples implementação.
O sumário fornecido pela NLP Cloud é abstracto, o que significa que podem ser geradas novas frases e removidas partes com baixa taxa de ruído de informação.
Vejamos um exemplo:

Passamos um bloco de texto, e o modelo devolve um resumo. Mas operar numa consola não é muito conveniente. Assim, vamos fazer com que o Google Docs resuma o fragmento de texto seleccionado desta forma.
O nosso objectivo é criar um menu conveniente para que o resumo do texto aconteça automaticamente de dentro do Google Docs.

É assim que o nosso projecto é estruturado. Usando Apps Script, iremos alargar a GUI com um botão que irá activar funções que comunicam com a NLP Cloud API e depois inserir o resultado abaixo.
Começaremos por preparar um add-on para o menu.
Utilizar o Google Apps Scripts para adicionar funcionalidades personalizadas ao Google Docs é bastante fácil. Pode personalizar a interface do utilizador com novos menus, caixas de diálogo e barras laterais. Para criar um script, após abrir o Google Docs, seleccione Tools -> Script editor.
Todos os elementos de interface devem ser acrescentados nesta função: onOpen. É executado após a abertura do documento e permite-nos adicionar o menu.
function onOpen() {
var ui = DocumentApp.getUi();
ui.createMenu('Text Summarizer')
.addItem('Summarize selection', 'summarizeSelection')
.addToUi();
}
function summarizeSelection() {
// summarization function
}
Depois de salvar o guião e refrescar os Docs, deverá encontrar o novo elemento do menu "Sumarizador de Texto".

Temos de obter o texto seleccionado e depois implementar a seguinte função: summarizeSelection.
A parte complicada é obter texto actualmente seleccionado e passá-lo para funções. É possível graças a esta função: getSelection.
DocumentApp.getActiveDocument().getSelection();
However, this function returns not only highlighted part of the documents, but a whole paragraph in which selections resides. That’s why we create more complex getSelectedText function:
function getSelectedText() {
var document = DocumentApp.getActiveDocument();
var body = document.getBody();
var text = "";
var selection = document.getSelection();
var parent = false;
var insertPoint
if (selection) {
var elements = selection.getRangeElements();
if(elements[0].isPartial()) {
text = elements[0].getElement().asText().getText();
text = text.substring(elements[0].getStartOffset(),elements[0].getEndOffsetInclusive()+1)
parent = elements[0].getElement().getParent();
} else {
text = elements.map( function(element) {
parent = element.getElement().getParent();
return element.getElement().asText().getText();
});
}
// Logger.log(text);
if (parent) {
insertPoint = body.getChildIndex(parent);
}
}
return [text, insertPoint];
}
A função simplesmente leva todo o parágrafo e reduz-o a apenas o fragmento seleccionado. Também devolve o índice do parágrafo para que se saiba onde inserir o resumo.
Agora, vamos enviar o texto para o API e analisar o resultado.
Vamos utilizar o seguinte serviço para fazer pedidos API directamente: UrlFetch. O pedido de API de sumarização de texto requer autorização através do token. Para o obter, inscreva-se no nlpcloud.com (o plano gratuito serve perfeitamente).
O API a ser solicitado devolve uma resposta em bruto do JSON para um pedido.
Lembre-se de que todo o texto processado por este script é enviado para API externo.
function summarizeSelection() {
var document = DocumentApp.getActiveDocument();
var selectedText = getSelectedText();
var text = selectedText[0];
var insertPoint = selectedText[1];
if (text) {
DocumentApp.getUi().alert(text);
var url = 'https://api.nlpcloud.io/v1/bart-large-cnn/summarization';
var response = UrlFetchApp.fetch(
url,
{
'method': 'POST',
'contentType': 'application/json',
'headers':{
'Authorization': 'Token c714fb961e7f6ef1336ab7f501f4d842f2dc2380'
},
'payload': JSON.stringify({"text":text}),
'muteHttpExceptions': true
}
);
try {
summary_text = JSON.parse(response.getContentText())['summary_text'];
DocumentApp.getUi().alert(summary_text);
} catch (e) {
DocumentApp.getUi().alert('Something went wrong 🙁');
}
} else {
DocumentApp.getUi().alert('You must select some text!');
}
}
Para testar a funcionalidade, basta seleccionar um fragmento de texto em Docs e escolher Text Summarization -> Summarize selection a partir do menu Docs.
Após um momento de processamento, deverá ver um pop-up com o resultado, que pode mesmo copiar.

Finalmente, podemos inserir um resumo gerado por API directamente no documento. Para facilidade de distinção, negrito o texto do resumo. É por isso que a função seguinte também devolve o índice de parágrafo do texto seleccionado: getSelectedText.
Desta forma, sabemos exactamente onde dizer ao Apps Script para inserir o novo texto.
function summarizeSelection() {
var document = DocumentApp.getActiveDocument();
var selectedText = getSelectedText();
var text = selectedText[0];
var insertPoint = selectedText[1];
if (text) {
DocumentApp.getUi().alert(text);
var url = 'https://api.nlpcloud.io/v1/bart-large-cnn/summarization';
var response = UrlFetchApp.fetch(
url,
{
'method': 'POST',
'contentType': 'application/json',
'headers':{
'Authorization': 'Token c714fb961e7f6ef1336ab7f501f4d842f2dc2380'
},
'payload': JSON.stringify({"text":text}),
'muteHttpExceptions': true
}
);
try {
summary_text = JSON.parse(response.getContentText())['summary_text'];
DocumentApp.getUi().alert(summary_text);
} catch (e) {
DocumentApp.getUi().alert('Something went wrong 🙁');
}
//////////////
var body = document.getBody();
var summaryParagraph = body.insertParagraph(insertPoint+1, summary_text);
summaryParagraph.setBold(true);
//////////////
} else {
DocumentApp.getUi().alert('You must select some text!');
}
}
Vamos testar a versão final:
A construção de uma aplicação que alarga a funcionalidade do Google Docs com base em APIs externas é uma alternativa interessante à construção de grandes sistemas para automatizar etapas de trabalho inconvenientes. Além disso, os componentes individuais podem ser substituídos, dependendo das necessidades e competências específicas. Por exemplo, a nossa solução pode ser alargada com detecção de emoções ou classificação de texto (também disponível em NLP Cloud). Também pode preparar a sua própria API ou funções simples directamente em Apps Script.

Obrigado pela sua leitura. Espero que tenha gostado tanto de ler como eu gostei de escrever isto para si.