Article by Rafał Rybnik, Leder af softwareudvikling hos Instytut Badań Pollster
Uanset om du er forfatter, datalog eller bare skimmer igennem kilder for at få et arbejde gjort, er det vigtigt at læse længere tekster for at plukke krummer af information ud kan være ret udmattende. Automatisering af sådanne elementer af dit arbejde giver dig mulighed for at fokusere på den kreative side af tingene.

Medmindre andet er angivet, er alle billeder i artiklen taget af forfatteren selv.
Tekstresuméer er en teknik til at udtrække de vigtigste informationselementer af en omfattende tekst. Manuel tekstresuméer er en vanskelig og tidskrævende opgave, så Natural Language Processing og maskinlæringsalgoritmer blev populære for at automatisere den.
Der findes færdige løsninger på markedet, enten i form af biblioteker eller færdige værktøjer til slutbrugerne.
I denne artikel vil vi udarbejde vores egen skræddersyede løsning, som samtidig ikke kræver avanceret viden om datalogi.
NLP Cloud er en leverandør af flere API'er til tekstbehandling ved hjælp af maskinlæringsmodeller. En af disse er tekstresuméren, som ser lovende ud med hensyn til enkel implementering.
NLP Clouds opsummeringsværktøj er abstrakt, hvilket betyder, at der kan genereres nye sætninger, og at dele med et lavt informations-støjforhold fjernes.
Lad os se et eksempel:

Vi sender en tekstblok, og modellen returnerer et resumé. Men det er ikke særlig praktisk at arbejde i en konsol. Så lad os få Google Docs til at opsummere det valgte tekstfragment på denne måde.
Vores mål er at skabe en praktisk menu, så tekstresumeet sker automatisk fra Google Docs.

Sådan er vores projekt opbygget. Ved hjælp af Apps Script udvider vi GUI'en med en knap, der udløser funktioner, som kommunikerer med NLP Cloud API'et og derefter indsætter resultatet nedenfor.
Vi starter med at forberede en tilføjelse til menuen.
Det er ret nemt at bruge Google Apps-scripts til at tilføje brugerdefinerede funktioner til Google Docs. Du kan tilpasse brugergrænsefladen med nye menuer, dialogbokse og sidebjælker. For at oprette et script skal du efter at have åbnet Google Docs vælge Værktøjer -> Script editor.
Alle grænsefladeelementer skal tilføjes i denne funktion: onOpen. Den køres efter åbning af dokumentet og giver os mulighed for at tilføje menuen.
function onOpen() {
var ui = DocumentApp.getUi();
ui.createMenu('Text Summarizer')
.addItem('Summarize selection', 'summarizeSelection')
.addToUi();
}
function summarizeSelection() {
// summarization function
}
Når du har gemt scriptet og opdateret Docs, bør du finde et nyt menuelement "Text Summarizer".

Vi skal hente den valgte tekst og derefter implementere følgende funktion: summarizeSelection.
Den vanskelige del er at få den aktuelt valgte tekst og sende den til funktioner. Det er muligt takket være denne funktion: 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];
}
Funktionen tager simpelthen hele afsnittet og skærer det ned til kun det valgte fragment. Den returnerer også afsnittets indeks, så du ved, hvor du skal indsætte resuméet.
Lad os nu sende teksten til API'et og analysere resultatet.
Vi bruger følgende tjeneste til at foretage API-forespørgsler direkte: UrlFetch. API-anmodning til tekstresuméer kræver godkendelse via token. Du kan få den ved at tilmelde dig på nlpcloud.com (det gratis abonnement er fint nok).
Den API, der anmodes om, returnerer et råt JSON-svar for en anmodning.
Husk, at al tekst, der behandles af dette script, sendes til ekstern API.
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!');
}
}
For at teste funktionaliteten skal du blot vælge et tekstfragment i Docs og vælge Text Summarization -> Summarize selection fra Docs-menuen.
Efter et øjebliks behandling bør du se en pop-up med resultatet, som du endda kan kopiere.

Endelig kan vi indsætte et API-genereret resumé direkte i dokumentet. For at gøre det nemmere at skelne mellem teksterne i resuméet er teksten i fed. Derfor returnerer den følgende funktion også den valgte teksts paragrafindeks: getSelectedText.
På denne måde ved vi præcis, hvor vi skal fortælle Apps Script, at den nye tekst skal indsættes.
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!');
}
}
Lad os teste den endelige version:
At opbygge en applikation, der udvider Google Docs-funktionaliteten baseret på eksterne API'er, er et interessant alternativ til at opbygge store systemer til automatisering af besværlige arbejdsgange. Desuden kan de enkelte komponenter udskiftes afhængigt af behov og specifikke færdigheder. Vores løsning kan f.eks. udvides med følelsesdetektion eller tekstklassificering (også tilgængelig i NLP Cloud). Du kan også forberede din egen API eller enkle funktioner direkte i Apps Script.

Tak fordi du læste med. Jeg håber, at du har nydt at læse lige så meget, som jeg har nydt at skrive dette til dig.