RareJob Tech Blog

レアジョブテクノロジーズのエンジニア・デザイナーによる技術ブログです

英会話の教材をCloud Natural Languageで解析してみた

はじめに

昼休みの1時間、会社近くのゴールドジムへ通ってベンチプレスが日課なのですが、最近胸の形が良くなったと定評のある35歳の男、塚田です。

ちなみに好きなプロテインはリッチミルクです。

さて、トレーニングと同じくコツコツやる系といえば英会話です。 我々の提供しているレアジョブ英会話の中で重要な構成要素の一つは教材です。

レアジョブ英会話が提供している教材は自社で開発しており、様々な国籍の方が働いているチームで品質チェックを行い、 厳しいチェックをパスしたものが世に出ます。 今回はその人気教材の一つ、Daily News Articleを使って、GCPのCloud Natural Languageで自然言語解析を行いたいと思います。 www.rarejob.com

解析対象コンテンツ

今回はコンテンツをそのまま機械的に翻訳をかけるのではなく、 作業端末内にテキストとして保存したところから解析を始めています。 ちなみに解析したコンテンツはこちら。

www.rarejob.com

A new robot created by a team of Toyota engineers set a Guinness World Record after demonstrating its impressive free-throw shooting skills.

という出だしからわかる通り、Guinness World Record を取得したToyota engineers チームの話しです。

解析エンジン

GCP では主に、2つの自然言語解析機能が提供されています。

  • AutoML Natural Language (最小限の労力と機械学習の専門知識で高品質な独自のカスタム機械学習モデルをトレーニングすることで、感情の分類、抽出、検出ができる)
  • Natural Language API (Natural Language API の強力な事前トレーニング済みモデルにより、デベロッパーは感情分析、エンティティ分析、エンティティ感情分析、コンテンツ分類、構文分析などの自然言語理解の機能を操作できる)

今回は既に学習済みのモデルであるNatural Language APIを活用することにします。 Natural Language APIが提供する機能は以下の通りです。

  • エンティティ分析(analyze-entities)... ドキュメント(領収書、請求書、契約書など)の中のエンティティを識別し、ラベル(日付、人、連絡先情報、組織、場所、イベント、商品、メディアなど)を付ける
  • 感情分析(analyze-sentiment) ... テキストのブロック内で示されている全体的な意見、感想、態度の感情を読み取る
  • コンテンツの分類(classifyText) ... 事前定義された 700 以上のカテゴリでドキュメントを分類
  • 構文解析(analyze-syntax) ... 文の抽出、品詞の特定、各文の係り受け解析ツリーの作成

全部試してみた

エンティティ分析(analyze-entities).

実施コマンド

gcloud ml language analyze-entities --content-file=/tmp/original > /tmp/analyze-entities

結果

{
"entities": [
  {
    "mentions": [
      {
        "sentiment": {
          "magnitude": 0.1,
          "score": 0.1
        },
        "text": {
          "beginOffset": 6,
          "content": "robot"
        },
        "type": "COMMON"
      }
    ],
(中略)
  {
    "mentions": [
      {
        "sentiment": {
          "magnitude": 0.1,
          "score": 0.1
        },
        "text": {
          "beginOffset": 56,
          "content": "Guinness World Record"
        },
        "type": "PROPER"
      }
    ],
    "metadata": {},
    "name": "Guinness World Record",
    "salience": 0.03506625,
    "sentiment": {
      "magnitude": 0.1,
      "score": 0.1
    },
    "type": "EVENT"
  },

単語を取ってくれるようです。 特筆すべきは、Gusiness, World, Recordのように認識されてもおかしくないのに、 Guinness World Recordのようなワード(複合名詞)を1つの単語として扱ってくれます。

これについて調べてみると、 mentions には PROPER と COMMON の 2 つのタイプがあります。 PROPERの場合は、固有名詞。COMMONの場合は普通名詞という風に区別されています。

cloud.google.com

ちなみに、エンティティ分析は、学術的には固有表現認識(Named Entity Recognition )と呼ばれています。 機関名や人物名などを文章の中から識別する問題を解いており、以下のようなマスク処理(データの匿名化)で使われることがあるそうです。

固有表現認識を使って文書を黒塗りする - Qiita

感情分析(analyze-sentiment)

実施コマンド

gcloud ml language analyze-entity-sentiment --content-file=/tmp/original > /tmp/analyze-entity-sentiment

結果

{
"documentSentiment": {
  "magnitude": 5.2,
  "score": 0.3
},
"language": "en",
"sentences": [
  {
    "sentiment": {
      "magnitude": 0.9,
      "score": 0.9
    },
    "text": {
      "beginOffset": 0,
      "content": "A new robot created by a team of Toyota engineers set a Guinness World Record after demonstrating its impressive free-throw shooting skills."
    }
  },

各センテンス毎に全体的な態度(ポジティブかネガティブか)を特定する分析。 score と magnitude の数値によって表されるようです。

コンテンツの分類(classifyText)

実施コマンド

gcloud ml language analyze-entity-sentiment --content-file=/tmp/original > /tmp/analyze-entity-sentiment

結果

{
"categories": [
  {
    "confidence": 0.59,
    "name": "/Sports"
  }
]
}

文章全部を読んで、Sports ですね。というカテゴリーに分類されました。 自動でタグを打ちたい時とか便利かもしれません。

構文解析(analyze-syntax)

実施コマンド

gcloud ml language analyze-syntax --content-file=/tmp/original > /tmp/analyze-syntax

結果

{
  "language": "en",
  "sentences": [
    {
      "text": {
        "beginOffset": 0,
        "content": "A new robot created by a team of Toyota engineers set a Guinness World Record after demonstrating its impressive free-throw shooting skills."
      }
    },
    {
      "text": {
        "beginOffset": 142,
        "content": "Toyota Motor Corporation\u2019s robot, CUE3, completed 2,020 consecutive basketball free throws in a demonstration last May."
      }
    },
(中略)
    {
      "text": {
        "beginOffset": 970,
        "content": "In a separate demonstration meant to test CUE3\u2019s ability to make three-point shots, the robot was able to score 62.5% of the time."
      }
    },
    {
      "text": {
        "beginOffset": 1103,
        "content": "This figure beats NBA player Kyle Korver\u2019s single season record of 53.6% and two-time NBA MVP Stephen Curry\u2019s average of 43.6%."
      }
    },

(中略)
    {
      "dependencyEdge": {
        "headTokenIndex": 23,
        "label": "AMOD"
      },
      "lemma": "impressive",
      "partOfSpeech": {
        "aspect": "ASPECT_UNKNOWN",
        "case": "CASE_UNKNOWN",
        "form": "FORM_UNKNOWN",
        "gender": "GENDER_UNKNOWN",
        "mood": "MOOD_UNKNOWN",
        "number": "NUMBER_UNKNOWN",
        "person": "PERSON_UNKNOWN",
        "proper": "PROPER_UNKNOWN",
        "reciprocity": "RECIPROCITY_UNKNOWN",
        "tag": "ADJ",
        "tense": "TENSE_UNKNOWN",
        "voice": "VOICE_UNKNOWN"
      },
      "text": {
        "beginOffset": 102,
        "content": "impressive"
      }
    },

センテンスがキリのいいところで区切られます。 改行が \u になってしまうので、そのまま使うわけにはいかないので、ちょっと工夫が必要なようです。

単語も拾えます。 特に "tag": "ADJ", "content": "impressive" という情報はいろいろ流用できそうです。

We're hiring!

レアジョブは右肩上がりで成長している英会話事業会社です。 その中でも、完全自社コンテンツを持っているのは強みの一つで、 例えば今回の自動解析、自動分類によって、単語アプリを新しく世に出す事も選択肢になるでしょう。 我々は全方位で仲間を募集しています。 https://appeal.rarejob.co.jp/recruit/

興味ある人がいましたら、ぜひ一緒にランチでも食べながら「こんなことできそうだよね」って話しができたら嬉しいです。