Natural Language Processing CloudのText Summarization APIを使って、Google Docsにテキストサマライザーを追加する。

Article by Rafał Rybnik, ソフトウェア開発部門責任者 Instytut Badań Pollster

ライターやデータサイエンティスト、あるいは仕事のために資料に目を通すだけの人であっても、長い文章を読んで情報の断片を拾い出すのは非常に疲れます。 長い文章を読んで情報の断片を取り出すのは、とても疲れます。このような作業を自動化することで そのような作業を自動化することで、クリエイティブな作業に集中することができます。

テキストサマリー
特に断りのない限り、記事中の写真はすべて著者によるものです。

テキストサマリー

テキストサマリーとは、膨大な量のテキストの中から重要な情報を抽出する技術です。マニュアル 手作業での要約は困難で時間もかかるため、それを自動化するために自然言語処理や機械学習のアルゴリズムが普及した。 自然言語処理や機械学習アルゴリズムが普及し、自動化された。

市場には、ライブラリの形でも、エンドユーザー向けの既製のツールでも、既製のソリューションがあります。

この記事では、データサイエンスの高度な知識を必要としない、独自のカスタマイズされたソリューションを用意しています。

NLP Cloud

NLPクラウドは、機械学習モデルを用いたテキスト処理のための複数のAPIを提供しています。その一つがテキストサマライザーで、簡単な実装という点では期待できそうです。

NLPクラウドが提供するサマライザーは抽象化されているため、新たな文章が生成されたり、情報量の少ない部分が削除されたりする可能性があります。

一例を見てみましょう。

テキストサマライズAPI

テキストのブロックを渡すと、モデルが要約を返してくれます。しかし、コンソールでの操作はあまり便利ではありません。そこで、この方法でGoogle Docsに選択されたテキストの断片を要約させてみましょう。

Google Docsの拡張

目標は、Google Docs上で自動的に文章の要約ができるような便利なメニューを作ることです。

Apps Scriptのプロジェクト構成

これが私たちのプロジェクトの構成です。Apps Scriptを使って、NLP Cloud APIと通信する関数をトリガーするボタンでGUIを拡張し、以下のような結果を挿入していきます。

まずは追加のメニューを用意することから始めます。

メイキングメニュー

Google Appsのスクリプトを使って、Google Docsにカスタム機能を追加するのはとても簡単です。新しいメニューやダイアログボックス、サイドバーなどでユーザーインターフェースをカスタマイズすることができます。スクリプトを作成するには、Google Docsを開いた後、「ツール」→「スクリプトエディタ」を選択します。

すべてのインターフェース要素は、この機能で追加される必要があります。 onOpen. ドキュメントを開いた後に実行され、メニューを追加することができます。

function onOpen() {
    var ui = DocumentApp.getUi();
    
    ui.createMenu('Text Summarizer')
        .addItem('Summarize selection', 'summarizeSelection')
        .addToUi();
    }
    
    function summarizeSelection() {
    // summarization function
}

スクリプトを保存してDocsを更新すると、新しいメニュー要素「Text Summarizer」が見つかるはずです。

Google Docs メニュー

選択されたテキストを取得して、次の関数を実装する必要があります。 summarizeSelection.

ゲットセレクション

厄介なのは、現在選択されているテキストを取得し、それを関数に渡すことです。この関数のおかげでそれが可能になりました。 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];
}

この関数は、単に段落全体を取得し、選択された断片だけに切り詰めるものです。また、段落のインデックスを返すので、どこに要約を挿入すればよいかがわかります。

では、そのテキストをAPIに送り、結果を解析してみましょう。

外部API

以下のサービスを利用して、直接APIリクエストを行うことにします。 UrlFetch. Text Summarization APIのリクエストには、トークンによる認証が必要です。トークンを取得するには、nlpcloud.comでサインアップしてください(無料プランで十分です)。

リクエストされたAPIは、リクエストに対する生のJSONレスポンスを返します。

このスクリプトで処理されたすべてのテキストは、外部の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!');
    }

}

この機能をテストするには、Docsでテキストの断片を選択し、Docsメニューから「テキストの要約」→「選択部分の要約」を選択するだけです。

処理が終わると、結果がポップアップで表示され、コピーすることもできます。

テキスト要約生成

ドキュメントへのレスポンスを書く

最後に、APIで生成されたサマリーをドキュメントに直接挿入します。見分けがつきやすいように、要約のテキストは太字にします。そのため、以下の関数では、選択されたテキストの段落インデックスも返しています。 getSelectedText.

こうすることで、Apps Scriptに新しいテキストを挿入するように指示する場所が正確にわかります。

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!');
    }
    
}

最終バージョンをテストしてみましょう。

テイクアウェイ

Google Docsの機能を外部APIに基づいて拡張するアプリケーションを構築することは、大規模なシステムを構築して不便な作業手順を自動化することに代わる興味深い方法です。さらに、ニーズや特定のスキルに応じて、個々のコンポーネントを交換することができます。例えば、私たちのソリューションは、感情検出やテキスト分類で拡張することができます(NLP Cloudでも利用可能)。また、独自のAPIや簡単な関数をApps Scriptで直接用意することもできます。

紙飛行機

お読みいただきありがとうございました。私があなたのためにこれを書くことを楽しんだように、あなたが読むことを楽しんでくれれば幸いです。