Cloud Natural Language API によるエンティティ、感情、構文の分析

Cloud Natural Language API を使用すると、テキストからエンティティを抽出して感情分析や構文解析を行い、テキストをカテゴリに分類できます。

このラボでは、Natural Language API を使ってエンティティ、感情、構文を分析する方法について学びます。

ラボの内容

  • Natural Language API リクエストを作成し、curl で API を呼び出す
  • Natural Language API でテキストのエンティティ抽出と感情分析を行う
  • Natural Language API でテキストを言語学的に分析する
  • 別の言語のテキストを使って Natural Language API リクエストを作成する

必要なもの

  • Google Cloud Platform プロジェクト
  • ChromeFirefox などのブラウザ

このチュートリアルをどのように使用されますか?

通読するのみ 内容を読んで演習を完了する

Google Cloud Platform のご利用経験について、いずれに該当されますか?

初心者 中級者 上級者

セルフペース型の環境設定

Google アカウント(Gmail または Google Apps)をまだお持ちでない場合は、アカウントを作成する必要があります。Google Cloud Platform Console(console.cloud.google.com)にログインして、新しいプロジェクトを作成します。

2016-02-10 12:45:26.png のスクリーンショット

プロジェクト ID を忘れないようにしてください。プロジェクト ID はすべての Google Cloud プロジェクトを通じて一意の名前にする必要があります(上記の名前はすでに使用されているので使用できません)。以降、このコードラボでは PROJECT_ID と呼びます。

次に、Google Cloud リソースを使用するために、Cloud Console で課金を有効にする必要があります。

この Codelab を実施した場合、費用は数ドルを超えることはありませんが、より多くのリソースを使用する場合や、実行したままにしておくとさらにコストがかかる場合があります(このドキュメントの最後にある「クリーンアップ」セクションをご覧ください)。

Google Cloud Platform の新規ユーザーは 300 ドル分の無料トライアルをご利用いただけます。

画面の左上にあるメニュー アイコンをクリックします。

プルダウン メニューから [API とサービス] を選択し、[ダッシュボード] をクリックします

[API とサービスの有効化] をクリックします。

検索ボックスで「language」を検索します。[Google Cloud Natural Language API] をクリックします。

[有効にする] をクリックして、Cloud Natural Language API を有効にします。

有効になるまで数秒待ちます。有効にすると、次の画面が表示されます。

Google Cloud Shell は、Cloud 内で動作するコマンドライン環境です。この Debian ベースの仮想マシンには、必要な開発ツール(gcloudbqgit など)がすべて揃っており、永続的な 5 GB のホーム ディレクトリが用意されています。Cloud Shell を使用して Natural Language API へのリクエストを作成します。

Cloud Shell の使用を開始するには、ヘッダーバーの右上の [Google Cloud Shell をアクティブにする] スクリーンショット 2015-06-08 5.30.32 PM.png アイコンをクリックします。

コンソールの下部の新しいフレーム内で Cloud Shell セッションが開き、コマンドライン プロンプトが表示されます。user@project:~$ プロンプトが表示されるまで待ちます。

ここでは curl を使用して Natural Language API にリクエストを送信するため、リクエストの URL で渡す API キーを生成する必要があります。API キーを作成するには、Cloud Console の [API とサービス] の [認証情報] セクションに移動します。

プルダウン メニューで [API キー] を選択します。

生成された API キーをコピーし、このキーはラボの後半で必要になります。

これで API キーができました。各リクエストに API キーの値を挿入せずに済むように、環境変数に API キーを保存します。環境変数にキーを保存するには、Cloud Shell で次のように入力します。<your_api_key> は、コピーしたキーに置き換えてください。

export API_KEY=<YOUR_API_KEY>

最初に使用する Natural Language API メソッドは analyzeEntities です。このメソッドを使用すると、API によってテキストからエンティティ(人、場所、イベントなど)が抽出されます。API のエンティティ分析を試すには、次の文を使用します。

Joanne Rowling 氏は、J. K. Rowling と Robert Galbraith は、英国の小説家兼脚本家で、ファンタジー シリーズ「ハリー ポッター」を書きました。

Natural Language API へのリクエストを request.json ファイルに作成します。Cloud Shell 環境で、次のコードを含む request.json ファイルを作成します。このファイルは、任意のコマンドライン エディタ(nano、vim、emacs)のいずれかを使用して作成するか、Cloud Shell の組み込みの Orion エディタを使用できます。

request.json

{
  "document":{
    "type":"PLAIN_TEXT",
    "content":"Joanne Rowling, who writes under the pen names J. K. Rowling and Robert Galbraith, is a British novelist and screenwriter who wrote the Harry Potter fantasy series."
  },
  "encodingType":"UTF8"
}

このリクエストでは、送信するテキストを Natural Language API に伝えます。指定できる型の値は PLAIN_TEXT または HTML です。content には、分析のために Natural Language API に送信するテキストを指定します。Natural Language API では、Cloud Storage に保存されているファイルをテキスト処理用に送信することもできます。Cloud Storage からファイルを送信する場合は、contentgcsContentUri に置き換えて、Cloud Storage 内のテキスト ファイルの URI を指定します。encodingType は、テキストの処理時に使用するテキスト エンコードの種類を API に指示します。API はこの情報を使って、特定のエンティティがテキストのどこに出現するかを調べます。

リクエストの本文に、先ほど保存した API キー環境変数と、次の curl コマンド(1 つのコマンドラインですべて指定)を使用して Natural Language API を渡せるようになりました。

curl "https://language.googleapis.com/v1/documents:analyzeEntities?key=${API_KEY}" \
  -s -X POST -H "Content-Type: application/json" --data-binary @request.json

レスポンスの先頭は、次のようになります。

{
  "entities": [
     {
      "name": "Robert Galbraith",
      "type": "PERSON",
      "metadata": {
        "mid": "/m/042xh",
        "wikipedia_url": "https://en.wikipedia.org/wiki/J._K._Rowling"
      },
      "salience": 0.7980405,
      "mentions": [
        {
          "text": {
            "content": "Joanne Rowling",
            "beginOffset": 0
          },
          "type": "PROPER"
        },
        {
          "text": {
            "content": "Rowling",
            "beginOffset": 53
          },
          "type": "PROPER"
        },
        {
          "text": {
            "content": "novelist",
            "beginOffset": 96
          },
          "type": "COMMON"
        },
        {
          "text": {
            "content": "Robert Galbraith",
            "beginOffset": 65
          },
          "type": "PROPER"
        }
      ]
    },

    ...
  ]
}

レスポンス内の各エンティティについて、エンティティ type、関連する Wikipedia URL(存在する場合)、salience、テキスト内でこのエンティティが出現する位置のインデックスを取得します。salience(顕著性)は、[0,1] の範囲の数値です。これは、そのエンティティがテキスト全体でどの程度重要かを表します。Natural Language API では、同じエンティティの別の表現も認識されます。レスポンスの mentions リストを見てみましょう。API は「Joanne Rowling」と「Rowling」が「Robert Galbriath」を指していることがわかります。

Natural Language API では、エンティティの抽出に加えて、テキスト ブロックの感情分析を行うこともできます。JSON リクエストには、上記のリクエストと同じパラメータが含まれていますが、今回はテキストを変更してより感情の強いものを含めるようにします。request.json ファイルを次のように置き換えます。以下の content は独自のテキストに置き換えてください。

request.json

 {
  "document":{
    "type":"PLAIN_TEXT",
    "content":"Harry Potter is the best book. I think everyone should read it."
  },
  "encodingType": "UTF8"
}

次に、API の analyzeSentiment エンドポイントにリクエストを送信します。

curl "https://language.googleapis.com/v1/documents:analyzeSentiment?key=${API_KEY}" \
  -s -X POST -H "Content-Type: application/json" --data-binary @request.json

レスポンスは次のようになります。

{
  "documentSentiment": {
    "magnitude": 0.8,
    "score": 0.4
  },
  "language": "en",
  "sentences": [
    {
      "text": {
        "content": "Harry Potter is the best book.",
        "beginOffset": 0
      },
      "sentiment": {
        "magnitude": 0.7,
        "score": 0.7
      }
    },
    {
      "text": {
        "content": "I think everyone should read it.",
        "beginOffset": 31
      },
      "sentiment": {
        "magnitude": 0.1,
        "score": 0.1
      }
    }
  ]
}

感情には、ドキュメント全体の感情と文ごとの感情の 2 種類があります。感情メソッドは scoremagnitude の 2 つの値を返します。score は、ステートメントがどの程度ポジティブまたはネガティブであるかを示す -1.0 から 1.0 までの数値です。magnitude は 0 から無限大の範囲の数値で、ポジティブかネガティブかにかかわらず、ステートメントで表される感情の重みを表します。重みの大きい主張を含むテキスト ブロックが長くなるほど magnitude の値が大きくなります。最初の文章のスコアは正(0.7)ですが、2 番目の文のスコアは中立(0.1)です。

Google では、NL API に送信するテキスト ドキュメント全体のセンチメントの詳細を提供するだけでなく、テキスト内のエンティティによってセンチメントを分類することもできます。次の文を例として使用します。

I liked the sushi but the service was terrible.

この場合、前述のようにセンテンス全体の感情スコアを取得するのは、それほど役に立ちません。あるレストランのクチコミで、同じレストランに関する何百件ものクチコミがあった場合、ユーザーのレビューにあった点と気に入らない点を正確に把握したいと考えました。幸いなことに、NL API には analyzeEntitySentiment と呼ばれるテキスト内のエンティティごとの感情を取得するメソッドがあります。request.json を上記の文で更新して試してみてください。

request.json

 {
  "document":{
    "type":"PLAIN_TEXT",
    "content":"I liked the sushi but the service was terrible."
  },
  "encodingType": "UTF8"
}

次に、次の curl コマンドを使用して analyzeEntitySentiment エンドポイントを呼び出します。

curl "https://language.googleapis.com/v1/documents:analyzeEntitySentiment?key=${API_KEY}" \
  -s -X POST -H "Content-Type: application/json" --data-binary @request.json

レスポンスで 2 つのエンティティ オブジェクトが返されます。1 つは「s 寿司」用で、もう 1 つは「service.」用です。完全な JSON レスポンスは次のとおりです。

{
  "entities": [
    {
      "name": "sushi",
      "type": "CONSUMER_GOOD",
      "metadata": {},
      "salience": 0.52716845,
      "mentions": [
        {
          "text": {
            "content": "sushi",
            "beginOffset": 12
          },
          "type": "COMMON",
          "sentiment": {
            "magnitude": 0.9,
            "score": 0.9
          }
        }
      ],
      "sentiment": {
        "magnitude": 0.9,
        "score": 0.9
      }
    },
    {
      "name": "service",
      "type": "OTHER",
      "metadata": {},
      "salience": 0.47283158,
      "mentions": [
        {
          "text": {
            "content": "service",
            "beginOffset": 26
          },
          "type": "COMMON",
          "sentiment": {
            "magnitude": 0.9,
            "score": -0.9
          }
        }
      ],
      "sentiment": {
        "magnitude": 0.9,
        "score": -0.9
      }
    }
  ],
  "language": "en"
}

「sushi」について返されたスコアは 0.9 でしたが、「service」では -0.9 でした。とても簡単に実行できました。また、sentiment オブジェクトがエンティティごとに 2 つ返されていますが、これは特定の出現箇所の値と、エンティティ全体の集計値を表しています。これらの言葉が複数回出てきた場合は、それぞれに別の score と magnitude の値が返されます。

Natural Language API の 3 つ目の方法である構文アノテーションを使用すると、テキストの言語学的詳細について掘り下げることができます。analyzeSyntax は、テキストのセマンティック要素と構文要素に関する詳細を提供するメソッドです。テキストの各単語について、品詞(名詞、動詞、形容詞など)と、文中の他の単語との関係を示します(これがルート動詞かどうか。修飾語かなど)を調べることができます。

簡単な文で試してみましょう。JSON リクエストは上記のリクエストと同様で、機能キーが追加されています。これにより、構文アノテーションを実行するよう API に指示できます。request.json を次のコードに置き換えます。

request.json

{
  "document":{
    "type":"PLAIN_TEXT",
    "content": "Hermione often uses her quick wit, deft recall, and encyclopaedic knowledge to help Harry and Ron."
  },
  "encodingType": "UTF8"
}

次に、API の analyzeSyntax メソッドを呼び出します。

curl "https://language.googleapis.com/v1/documents:analyzeSyntax?key=${API_KEY}" \
  -s -X POST -H "Content-Type: application/json" --data-binary @request.json

レスポンスでは、センテンス内の各トークンについて、次のようなオブジェクトが返されます。ここで、「uses」という単語に対するレスポンスを見てみましょう。

{
  "text": {
    "content": "uses",
    "beginOffset": 15
  },
  "partOfSpeech": {
    "tag": "VERB",
    "aspect": "ASPECT_UNKNOWN",
    "case": "CASE_UNKNOWN",
    "form": "FORM_UNKNOWN",
    "gender": "GENDER_UNKNOWN",
    "mood": "INDICATIVE",
    "number": "SINGULAR",
    "person": "THIRD",
    "proper": "PROPER_UNKNOWN",
    "reciprocity": "RECIPROCITY_UNKNOWN",
    "tense": "PRESENT",
    "voice": "VOICE_UNKNOWN"
  },
    "dependencyEdge": {
      "headTokenIndex": 2,
      "label": "ROOT"
    },
    "lemma": "use"
}

レスポンスを細かく見てみましょう。partOfSpeech は、各単語に関する言語情報を提供します(多くの単語は英語やこの特定の単語には該当しないため、不明です)。tag: この単語の品詞(この例では動詞)を示します。さらに、時制、モダリティ、単語が単数形と複数形のどちらであるかについての情報も取得します。lemma は単語の正規形式です。「それするために」たとえば、runrunsranrunning という単語はすべて、run の 1 つの要素があります。lemma の値は、大きなテキスト ブロックで単語の出現回数の推移を追跡するのに便利です。

dependencyEdge には、テキストの依存関係解析ツリーの作成に使用できるデータが含まれています。これは、各単語が互いにどのように関連しているかを示す図です。たとえば、上の文の係り受け解析ツリーは次のようになります。

上記のレスポンスの headTokenIndex は、トークンが「uses」を指しているトークンのインデックスです。文中の各トークンは、配列内の単語と考えることができ、headTokenIndex の「2」は「しばしば」という単語を指し、ツリー内で接続されているものです。

Natural Language API は、英語以外の言語もサポートしています(詳しくはこちらをご覧ください)。次のエンティティ リクエストを日本語の文で試してみましょう。

request.json

{
  "document":{
    "type":"PLAIN_TEXT",
    "content":"日本のグーグルのオフィスは、東京の六本木ヒルズにあります"
  },
  "encodingType": "UTF8"
}

テキストの言語を API に指定していないため、自動的に検出されます。次に、これを analyzeEntities エンドポイントに送信します。

curl "https://language.googleapis.com/v1/documents:analyzeEntities?key=${API_KEY}" \
  -s -X POST -H "Content-Type: application/json" --data-binary @request.json

レスポンスの最初の 2 つのエンティティは次のとおりです。

{
  "entities": [
    {
      "name": "日本",
      "type": "LOCATION",
      "metadata": {
        "mid": "/m/03_3d",
        "wikipedia_url": "https://en.wikipedia.org/wiki/Japan"
      },
      "salience": 0.23854347,
      "mentions": [
        {
          "text": {
            "content": "日本",
            "beginOffset": 0
          },
          "type": "PROPER"
        }
      ]
    },
    {
      "name": "グーグル",
      "type": "ORGANIZATION",
      "metadata": {
        "mid": "/m/045c7b",
        "wikipedia_url": "https://en.wikipedia.org/wiki/Google"
      },
      "salience": 0.21155767,
      "mentions": [
        {
          "text": {
            "content": "グーグル",
            "beginOffset": 9
          },
          "type": "PROPER"
        }
      ]
    },
    ...
  ]
  "language": "ja"
}

この API により、日本が場所として、Google が組織として、それぞれに対応する Wikipedia ページが取得されます。

ここでは、Cloud Natural Language API によるテキスト分析の方法を学ぶために、エンティティ抽出、感情分析、構文アノテーションを行いました。

学習した内容

  • Natural Language API リクエストを作成し、curl で API を呼び出す
  • Natural Language API でテキストのエンティティ抽出と感情分析を行う
  • テキストを言語学的に分析して係り受け解析ツリーを作成する
  • 日本語のテキストを使って Natural Language API リクエストを作成する

次のステップ