コンテンツ分類チュートリアル

対象

このチュートリアルは、Cloud Natural Language API を使用するアプリケーションの調査と開発をすぐに開始できるように作られています。基本的なプログラミングについて理解されている方を対象としていますが、プログラミングの深い知識がなくても、チュートリアルに沿って学習できるようになっています。このチュートリアルを終了すると、リファレンス ドキュメントを使用して独自の基本的なアプリケーションを作成できるようになります。

このチュートリアルでは、Python コードを使用して Natural Language のアプリケーションを体験します。ここでの目的は、Python クライアント ライブラリについて説明することではなく、Natural Language API を呼び出す方法を説明することです。Java や Node.js のアプリケーションも基本的にはこれと同様です。その他の言語のサンプル(チュートリアル内で使用するこのサンプルを含む)については、Natural Language API のサンプルをご覧ください。

事前準備

このチュートリアルでは次の事前準備が必要です。

概要

このチュートリアルでは、classifyText リクエストを使用して、基本的な Natural Language アプリケーションについて説明します。このアプリケーションでは、次のようにコンテンツをカテゴリに分類するとともに、信頼スコアを割り当てます。

category: "/Internet & Telecom/Mobile & Wireless/Mobile Apps & Add-Ons"
confidence: 0.6499999761581421

使用可能なすべてのカテゴリラベルのリストについては、カテゴリをご覧ください。

このチュートリアルでは、次のタスクを実行するアプリケーションを作成します。

  • 複数のテキスト ファイルを分類し、その結果をインデックス ファイルに書き込みます。
  • 入力クエリのテキストを処理して同様のテキスト ファイルを見つけます。
  • 入力クエリのカテゴリラベルを処理して同様のテキスト ファイルを見つけます。

このチュートリアルでは、Wikipedia のコンテンツを使用します。同様のアプリケーションを作成して、ニュース記事やオンライン コメントなどを処理することもできます。

ソースファイル

チュートリアルのソースコードは GitHub 上の Python クライアント ライブラリ サンプルに含まれています。

このチュートリアルでは、Wikipedia から引用したサンプル ソース テキストを使用します。サンプル テキスト ファイルは、GitHub プロジェクトの resources/texts フォルダ内にあります。

ライブラリのインポート

Cloud Natural Language API を使用するには、google-cloud-language ライブラリから language モジュールをインポートする必要があります。language.types モジュールには、リクエストの作成に必要なクラスが含まれています。language.enums モジュールは、入力テキストのタイプを指定するために使用します。このチュートリアルではプレーン テキストのコンテンツ(language.enums.Document.Type.PLAIN_TEXT)を分類します。

コンテンツの分類結果に基づいてテキスト間の類似度を計算するために、このチュートリアルでは numpy を使用してベクトル計算を実行します。

Python

import argparse
import io
import json
import os

from google.cloud import language_v1
import numpy
import six

手順 1. コンテンツを分類する

Natural Language API に対してコンテンツの分類をリクエストするには、Python クライアント ライブラリを使用できます。Natural Language API へのリクエストとそのレスポンスの詳細は、Python クライアント ライブラリによりカプセル化されています。

このチュートリアルで使用する classify 関数は Natural Language API の classifyText メソッドを呼び出すために、まず、LanguageServiceClient クラスのインスタンスを作成します。その後、LanguageServiceClient インスタンスの classify_text メソッドを呼び出します。

チュートリアルの classify 関数で分類するのは、このサンプルのテキスト コンテンツだけです。ウェブページのコンテンツを分類する場合は、ウェブページのソース HTML を text として渡し、type パラメータを language.enums.Document.Type.HTML に設定します。

詳しくは、コンテンツの分類をご覧ください。Natural Language API に対するリクエストの構造についての詳細は、Natural Language リファレンスをご覧ください。

Python

def classify(text, verbose=True):
    """Classify the input text into categories. """

    language_client = language_v1.LanguageServiceClient()

    document = language_v1.Document(
        content=text, type_=language_v1.Document.Type.PLAIN_TEXT
    )
    response = language_client.classify_text(request={'document': document})
    categories = response.categories

    result = {}

    for category in categories:
        # Turn the categories into a dictionary of the form:
        # {category.name: category.confidence}, so that they can
        # be treated as a sparse vector.
        result[category.name] = category.confidence

    if verbose:
        print(text)
        for category in categories:
            print(u"=" * 20)
            print(u"{:<16}: {}".format("category", category.name))
            print(u"{:<16}: {}".format("confidence", category.confidence))

    return result

結果には、カテゴリラベル(キー)と信頼スコア(値)を含む辞書が返されます。

{
    "/Computers & Electronics": 0.800000011920929,
    "/Internet & Telecom/Mobile & Wireless/Mobile Apps & Add-Ons": 0.6499999761581421
}

チュートリアルで使用する Python スクリプトは、容易にテストするためにコマンドラインから実行できるように構成されています。たとえば、次のように実行できます。

python classify_text_tutorial.py classify "Google Home enables users to speak voice commands to interact with services through the Home's intelligent personal assistant called Google Assistant. A large number of services, both in-house and third-party, are integrated, allowing users to listen to music, look at videos or photos, or receive news updates entirely by voice. "

手順 2. 複数のテキスト ファイルにインデックスを付ける

チュートリアルのスクリプトにある index 関数は、複数のテキスト ファイルを含むディレクトリと、インデックスが付けられた出力を保存するファイルへのパス(デフォルトのファイル名は index.json)を、入力に取ります。index 関数は、入力ディレクトリ内にある各テキスト ファイルの内容を読み取ってから、それらのテキスト ファイルをコンテンツ カテゴリの分類対象として Google Cloud Natural Language API に渡します。

Python

def index(path, index_file):
    """Classify each text file in a directory and write
    the results to the index_file.
    """

    result = {}
    for filename in os.listdir(path):
        file_path = os.path.join(path, filename)

        if not os.path.isfile(file_path):
            continue

        try:
            with io.open(file_path, "r") as f:
                text = f.read()
                categories = classify(text, verbose=False)

                result[filename] = categories
        except Exception:
            print("Failed to process {}".format(file_path))

    with io.open(index_file, "w", encoding="utf-8") as f:
        f.write(json.dumps(result, ensure_ascii=False))

    print("Texts indexed in file: {}".format(index_file))
    return result

Cloud Natural Language API によるファイルごとの結果は 1 つの辞書に編成され、JSON 文字列としてシリアル化された後、ファイルに書き込まれます。次に例を示します。

{
    "android.txt": {
        "/Computers & Electronics": 0.800000011920929,
        "/Internet & Telecom/Mobile & Wireless/Mobile Apps & Add-Ons": 0.6499999761581421
    },
    "google.txt": {
        "/Internet & Telecom": 0.5799999833106995,
        "/Business & Industrial": 0.5400000214576721
    }
}

テキスト ファイルにインデックスを付け、デフォルトのファイル名 index.json による出力をコマンドラインから行うには、次のコマンドを実行します。

python classify_text_tutorial.py index resources/texts

手順 3. インデックスを照会する

カテゴリラベルを使用したクエリ

インデックス ファイル(デフォルト ファイル名は index.json)が作成されたら、インデックスに対するクエリを実行して、ファイル名とその信頼スコアの一部を取得できます。

これを行う 1 つの方法は、クエリとしてカテゴリラベルを使用することです。このチュートリアルではそのために query_category 関数を使用します。similarity などのヘルパー関数の実装は、classify_text_tutorial.py ファイルの中で確認できます。実際のアプリケーションでは、類似度のスコア付けとランク付けを実際のユースケースに基づいて注意深く設計する必要があります。

Python

def query_category(index_file, category_string, n_top=3):
    """Find the indexed files that are the most similar to
    the query label.

    The list of all available labels:
    https://cloud.google.com/natural-language/docs/categories
    """

    with io.open(index_file, "r") as f:
        index = json.load(f)

    # Make the category_string into a dictionary so that it is
    # of the same format as what we get by calling classify.
    query_categories = {category_string: 1.0}

    similarities = []
    for filename, categories in six.iteritems(index):
        similarities.append((filename, similarity(query_categories, categories)))

    similarities = sorted(similarities, key=lambda p: p[1], reverse=True)

    print("=" * 20)
    print("Query: {}\n".format(category_string))
    print("\nMost similar {} indexed texts:".format(n_top))
    for filename, sim in similarities[:n_top]:
        print("\tFilename: {}".format(filename))
        print("\tSimilarity: {}".format(sim))
        print("\n")

    return similarities

使用可能なカテゴリの一覧については、カテゴリをご覧ください。

前と同じように、コマンドラインから query_category 関数を呼び出せます。

python classify_text_tutorial.py query-category index.json "/Internet & Telecom/Mobile & Wireless"

結果は次のような形で出力されます。

Query: /Internet & Telecom/Mobile & Wireless

Most similar 3 indexed texts:
  Filename: android.txt
  Similarity: 0.665573579045

  Filename: google.txt
  Similarity: 0.517527175966

  Filename: gcp.txt
  Similarity: 0.5

テキストを使用したクエリ

別の方法として、テキストを使用してクエリを実行することもできます。使用するテキストは、インデックス付けされたテキストに含まれていないものでも構いません。チュートリアルの query 関数は query_category 関数と同様ですが、テキスト入力に対して classifyText リクエストを実行し、その結果を使用してインデックス ファイルのクエリを実行するステップが追加されています。

Python

def query(index_file, text, n_top=3):
    """Find the indexed files that are the most similar to
    the query text.
    """

    with io.open(index_file, "r") as f:
        index = json.load(f)

    # Get the categories of the query text.
    query_categories = classify(text, verbose=False)

    similarities = []
    for filename, categories in six.iteritems(index):
        similarities.append((filename, similarity(query_categories, categories)))

    similarities = sorted(similarities, key=lambda p: p[1], reverse=True)

    print("=" * 20)
    print("Query: {}\n".format(text))
    for category, confidence in six.iteritems(query_categories):
        print("\tCategory: {}, confidence: {}".format(category, confidence))
    print("\nMost similar {} indexed texts:".format(n_top))
    for filename, sim in similarities[:n_top]:
        print("\tFilename: {}".format(filename))
        print("\tSimilarity: {}".format(sim))
        print("\n")

    return similarities

これをコマンドラインから実行するには、次のコマンドを実行します。

python classify_text_tutorial.py query index.json "Google Home enables users to speak voice commands to interact with services through the Home's intelligent personal assistant called Google Assistant. A large number of services, both in-house and third-party, are integrated, allowing users to listen to music, look at videos or photos, or receive news updates entirely by voice. "

次のような結果が出力されます。

Query: Google Home enables users to speak voice commands to interact with services through the Home's intelligent personal assistant called Google Assistant. A large number of services, both in-house and third-party, are integrated, allowing users to listen to music, look at videos or photos, or receive news updates entirely by voice.

  Category: /Internet & Telecom, confidence: 0.509999990463
  Category: /Computers & Electronics/Software, confidence: 0.550000011921

Most similar 3 indexed texts:
  Filename: android.txt
  Similarity: 0.600579500049

  Filename: google.txt
  Similarity: 0.401314790229

  Filename: gcp.txt
  Similarity: 0.38772339779

次のステップ

コンテンツ分類 API を使用して、他のアプリケーションを作成できます。次に例を示します。

  • 記事のすべての段落を分類し、トピックの遷移を確認する。

  • タイムスタンプ付きのコンテンツを分類し、時系列でトピックの傾向を分析する。

  • analyzeSentiment メソッドを使用して、コンテンツ カテゴリとコンテンツの感情を比較する。

  • コンテンツ カテゴリとテキストに記載されているエンティティを比較する。

また、他の GCP プロダクトを使用してワークフローを簡素化することもできます。

  • このチュートリアルのサンプル アプリケーションでは、ローカルのテキスト ファイルを処理しましたが、Google Cloud Storage バケットに保存されているテキスト ファイルを処理することもできます。それには、classify_text メソッドに Google Cloud Storage URI を渡すようにコードを変更します。

  • このチュートリアルのサンプル アプリケーションでは、インデックス ファイルをローカルに保存し、インデックス ファイル全体を読み取ることによって各クエリを処理しています。この方法では、大量のインデックス付きデータがある場合や多数のクエリを処理しなければならない場合に、レイテンシが高くなります。したがって、インデックス データの保存には Datastore を利用するのが実用的で便利です。