1. Qiita
  2. 投稿
  3. TensorFlow

Googleクラウド自然言語APIを使ってみた

  • 465
    いいね
  • 0
    コメント

Googleがクラウド自然言語API(WebAPI)を公開しました。

ニュース記事
Google、クラウド自然言語APIを公開―英語、日本語、スペイン語に対応
Google、日本語もサポートのクラウド自然言語APIとスピーチAPIを一般向けにβ公開
グーグル、自然言語処理APIと音声認識APIをオープンベータに

公式Blogのアナウンス
Introducing Cloud Natural Language API, Speech API open beta and our West Coast region expansion

本記事ではどのようなAPIが実装されたのかの紹介と、今後このような変更があるんじゃないのかなという筆者の想像を記載しています。
なお筆者はGoogleAPIは詳しいですが自然言語や機械学習は詳しくないのでおかしいこと書いていたらご指摘ください。

デモが用意されているので試してみよう

公式のリファレンスページを開いてページの一番下までスクロールしてください。

image

image

対象の画像を選んでください。(毎回違います。微妙に難しい時があります。。)
※ヘッドホンアイコン押すと画像じゃない奴で選択できます
image

なんか色々出てきますね。
Sentimentは日本語に対応してないのですが他の2つは対応しているので適当に動かしてみましょう。
image

APIの種類と対応言語

APIの種類としては3種類あります。

  • Entities(固有表現抽出)
  • Sentiment(感情解析)
  • Syntax(形態素解析、係り受け解析)

言語も現在(2016/07/21時点)は3種類あります。
ここに日本語が入るのがすごいですよね。

  • 英語
  • 日本語
  • スペイン語

対応のマトリクスです。
上に書いたようにSentimentは英語onlyです。

API 英語 日本語 スペイン語
Entities(固有表現抽出)
Sentiment(感情解析) × ×
Syntax(形態素解析、係り受け解析)

APIに関する全体的な話

API発行に必要なプロジェクトの作成等は本記事では省略します。
以下のリファレンスページを見たり「プロジェクトの作成 google API」などで検索すればたくさん出てきます。
Authenticating to a Cloud API Service

※それでも詰まったらここのコメントでもhowdy39宛にリプライでもいいので送ってください。

注意点

Beta版なのでは非後方互換な変更をされる可能性や、APIが確実に使えなかったりすることもありえます。
5000リクエスト超えるとお金かかるようなので注意です。

その他

クラウド自然言語APIもGoogleWebAPIの一種です。
実際に使用する際はこちらの記事
GoogleのWebAPI設計とWebAPI設計のベストプラクティスを比較してみるも見てみてください。

Entities(固有表現抽出)

Method: documents.analyzeEntities

以下がリクエスト・レスポンスの例です。

POST https://language.googleapis.com/v1beta1/documents:analyzeEntities
{
  "document": {
    "type": "PLAIN_TEXT",
    "language": "JA",
    "content": "Google、クラウド自然言語APIを公開―英語、日本語、スペイン語に対応"
  },
  "encodingType": "UTF8"
}

{
  "entities": [
    {
      "salience": 0, 
      "mentions": [
        {
          "text": {
            "content": "Google", 
            "beginOffset": 0
          }
        }
      ], 
      "type": "ORGANIZATION", 
      "name": "Google", 
      "metadata": {
        "wikipedia_url": "http://ja.wikipedia.org/wiki/Google"
      }
    }, 
    {
      "salience": 0, 
      "mentions": [
        {
          "text": {
            "content": "日本", 
            "beginOffset": 57
          }
        }
      ], 
      "type": "LOCATION", 
      "name": "日本", 
      "metadata": {
        "wikipedia_url": "http://ja.wikipedia.org/wiki/%E6%97%A5%E6%9C%AC"
      }
    }, 
    {
      "salience": 0, 
      "mentions": [
        {
          "text": {
            "content": "スペイン", 
            "beginOffset": 69
          }
        }
      ], 
      "type": "LOCATION", 
      "name": "スペイン", 
      "metadata": {
        "wikipedia_url": "http://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%9A%E3%82%A4%E3%83%B3"
      }
    }
  ], 
  "language": "ja"
}

entities内のEntityが抽出できた固有表現ですね。
ポイントだけ記載しておきます。

Entity.mentions

抽出出来た文字列の位置とか種類を表します。

Entity.salience

顕著性?というらしい。
文書全体に対する重要度みたいな項目らしいです。
上の例だと0〜1.0の範囲で全部0なので重要じゃないってことですかねぇ。

Entity.type

LOCATION(場所)やORGANIZATION(組織)として抽出されています。
※他にも人やイベントなんかもあるようです。type一覧

Entity.metadata

これが固有表現抽出した結果のデータですね。
今はWikipediaのURLしか出せないみたいです。

所感

Wikipediaしか出せないので は微妙な気がします。
ただEntity.mentionsはsが付いているようにこれから拡張される気がします。

今後どのように拡張されるかはわからないのですが、たとえば
「私はマクドナルドやモスバーガーやフレッシュネスバーガーによく行きます」
みたいなのを入れると、「ハンバーガー」「飲食店」みたいなのが出てくると可能性がすごく拡がりそうですよね。
検索エンジン作ってるGoogleさんならできるはず?期待しています。

Sentiment(感情解析)

Method: documents.analyzeSentiment

これは英語しか使えません。

以下がリクエスト・レスポンスの例です。

POST https://language.googleapis.com/v1beta1/documents:analyzeSentiment 
{
  "document": {
    "type": "PLAIN_TEXT",
    "content": "Tokyo is a big city."
  }
}
{
  "documentSentiment": {
    "polarity": -1, 
    "magnitude": 0.29999999999999999
  }, 
  "language": "en"
}

Sentiment.polarity / Sentiment.magnitude

polarityが感情の極性です。つまりマイナスなら負の感情。
magnitudeが絶対値です。
つまり「東京は大都市です」ちょっとだけ負の感情らしいです。

「Tokyo is a beautiful city.」なんかにするとちゃんと正の感情になります。

所感

良いか悪いかだけはなく、もうちょい分類できた方がうれしいかもですね。
悲しいと怒りは負の方向でしょうけど全然違うものですし。

Syntax(形態素解析、係り受け解析)

Method: documents.annotateText

以下がリクエスト・レスポンスの例です。

POST https://language.googleapis.com/v1beta1/documents:annotateText
{
  "document": {
    "type": "PLAIN_TEXT",
    "language": "JA",
    "content": "Google、クラウド自然言語APIを公開―英語、日本語、スペイン語に対応"
  },
  "features": {
    "extractSyntax": true,
    "extractEntities": false,
    "extractDocumentSentiment": false
  },
  "encodingType": "UTF8"
}

featuresはどれを取得対象にするかの指定です。
extractEntities、extractDocumentSentimentにfalseを指定していますがこれは今までに出てきた、Entities(固有表現抽出)、Sentiment(感情解析)と同じものが出てくるだけなので除外しました。
つまりdocuments.annotateText命令はすべての情報が一度に取得できます。

{
  "tokens": [
    {
      "text": {
        "content": "Google", 
        "beginOffset": 0
      }, 
      "dependencyEdge": {
        "headTokenIndex": 17, 
        "label": "NN"
      }, 
      "partOfSpeech": {
        "tag": "NOUN"
      }, 
      "lemma": "Google"
    }, 
    {
      "text": {
        "content": "、", 
        "beginOffset": 6
      }, 
      "dependencyEdge": {
        "headTokenIndex": 0, 
        "label": "P"
      }, 
      "partOfSpeech": {
        "tag": "PUNCT"
      }, 
      "lemma": "、"
    }, 
    {
      "text": {
        "content": "クラウド", 
        "beginOffset": 9
      }, 
      "dependencyEdge": {
        "headTokenIndex": 3, 
        "label": "NN"
      }, 
      "partOfSpeech": {
        "tag": "NOUN"
      }, 
      "lemma": "クラウド"
    }, 
    {
      "text": {
        "content": "自然", 
        "beginOffset": 21
      }, 
      "dependencyEdge": {
        "headTokenIndex": 4, 
        "label": "NN"
      }, 
      "partOfSpeech": {
        "tag": "NOUN"
      }, 
      "lemma": "自然だ"
    }, 
    {
      "text": {
        "content": "言語", 
        "beginOffset": 27
      }, 
      "dependencyEdge": {
        "headTokenIndex": 5, 
        "label": "NN"
      }, 
      "partOfSpeech": {
        "tag": "NOUN"
      }, 
      "lemma": "言語"
    }, 
    {
      "text": {
        "content": "API", 
        "beginOffset": 33
      }, 
      "dependencyEdge": {
        "headTokenIndex": 9, 
        "label": "NN"
      }, 
      "partOfSpeech": {
        "tag": "NOUN"
      }, 
      "lemma": "API"
    }, 
    {
      "text": {
        "content": "を", 
        "beginOffset": 36
      }, 
      "dependencyEdge": {
        "headTokenIndex": 5, 
        "label": "PRT"
      }, 
      "partOfSpeech": {
        "tag": "PRT"
      }, 
      "lemma": "を"
    }, 
    {
      "text": {
        "content": "公開", 
        "beginOffset": 39
      }, 
      "dependencyEdge": {
        "headTokenIndex": 9, 
        "label": "NN"
      }, 
      "partOfSpeech": {
        "tag": "NOUN"
      }, 
      "lemma": "公開"
    }, 
    {
      "text": {
        "content": "―", 
        "beginOffset": 45
      }, 
      "dependencyEdge": {
        "headTokenIndex": 9, 
        "label": "P"
      }, 
      "partOfSpeech": {
        "tag": "PUNCT"
      }, 
      "lemma": "―"
    }, 
    {
      "text": {
        "content": "英語", 
        "beginOffset": 48
      }, 
      "dependencyEdge": {
        "headTokenIndex": 0, 
        "label": "CONJ"
      }, 
      "partOfSpeech": {
        "tag": "NOUN"
      }, 
      "lemma": "英語"
    }, 
    {
      "text": {
        "content": "、", 
        "beginOffset": 54
      }, 
      "dependencyEdge": {
        "headTokenIndex": 0, 
        "label": "P"
      }, 
      "partOfSpeech": {
        "tag": "PUNCT"
      }, 
      "lemma": "、"
    }, 
    {
      "text": {
        "content": "日本", 
        "beginOffset": 57
      }, 
      "dependencyEdge": {
        "headTokenIndex": 0, 
        "label": "CONJ"
      }, 
      "partOfSpeech": {
        "tag": "NOUN"
      }, 
      "lemma": "日本"
    }, 
    {
      "text": {
        "content": "語", 
        "beginOffset": 63
      }, 
      "dependencyEdge": {
        "headTokenIndex": 11, 
        "label": "SUFF"
      }, 
      "partOfSpeech": {
        "tag": "AFFIX"
      }, 
      "lemma": "語"
    }, 
    {
      "text": {
        "content": "、", 
        "beginOffset": 66
      }, 
      "dependencyEdge": {
        "headTokenIndex": 0, 
        "label": "P"
      }, 
      "partOfSpeech": {
        "tag": "PUNCT"
      }, 
      "lemma": "、"
    }, 
    {
      "text": {
        "content": "スペイン", 
        "beginOffset": 69
      }, 
      "dependencyEdge": {
        "headTokenIndex": 0, 
        "label": "CONJ"
      }, 
      "partOfSpeech": {
        "tag": "NOUN"
      }, 
      "lemma": "スペイン"
    }, 
    {
      "text": {
        "content": "語", 
        "beginOffset": 81
      }, 
      "dependencyEdge": {
        "headTokenIndex": 14, 
        "label": "SUFF"
      }, 
      "partOfSpeech": {
        "tag": "AFFIX"
      }, 
      "lemma": "語"
    }, 
    {
      "text": {
        "content": "に", 
        "beginOffset": 84
      }, 
      "dependencyEdge": {
        "headTokenIndex": 0, 
        "label": "PRT"
      }, 
      "partOfSpeech": {
        "tag": "PRT"
      }, 
      "lemma": "に"
    }, 
    {
      "text": {
        "content": "対応", 
        "beginOffset": 87
      }, 
      "dependencyEdge": {
        "headTokenIndex": 17, 
        "label": "ROOT"
      }, 
      "partOfSpeech": {
        "tag": "NOUN"
      }, 
      "lemma": "対応"
    }
  ], 
  "entities": [], 
  "language": "ja", 
  "sentences": [
    {
      "text": {
        "content": "Google、クラウド自然言語APIを公開―英語、日本語、スペイン語に対応", 
        "beginOffset": 0
      }
    }
  ]
}

DependencyEdge

係り受け解析をあらわしている模様。
labelの一覧

PartOfSpeech

形態素解析をあらわしている模様。
tagの一覧

所感

これは自然言語素人にはほとんどわからないですね。なので何も言えない。。。
口語が弱いとかはてブで見ましたが実際どうなんでしょう。良いかどうかすら判別できないorz

あとがき

この分野はやっぱり面白そうですよね。
Qiitaには機械学習関連のよさ気な記事がいっぱいあるので勉強を始めてみようと思います。

このへんですかね。
数学を避けてきた社会人プログラマが機械学習の勉強を始める際の最短経路
機械学習はじめの一歩に役立つ記事のまとめ
画像処理の数式を見て石になった時のための、金の針