自然言語処理

Googleクラウド自然言語APIをPythonから叩いてMySQLに結果を保存してみた

Googleが自然言語処理を手軽に行えるAPIをベータ版として提供しています。日本語でも使用できて固有表現抽出と係り受け解析を簡単に実行できます。

Google Cloud Natural Language API(クラウド自然言語API)をPythonから叩いてMySQLに結果を保存してみた

Google Cloud PlatformでNatural Language APIを使うための設定をする

1. GCPのコンソールにて、既存のプロジェクトを選択するか新しいプロジェクトを作成

https://console.cloud.google.com/iam-admin/projects

2. 支払いの設定をする

GCNLは5,000リクエストを超えるとお金がかかるため、クレジット情報の登録が必須

3. Google Cloud Platform で Google Cloud Natural Language API を有効にするアプリケーションを登録

https://console.cloud.google.com/flows/enableapi?apiid=language.googleapis.com
にアクセスして、アプリケーションを登録するプロジェクトを選択する

4. 認証情報を追加しAPIキーを作成する

作成したAPIキーを保存しておく

5. 認証情報を作成する

サービスアカウントキーを生成
XXXX.jsonファイルをダウンロードして保存

6. 環境変数を追加する

$ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/your-project-credentials.json

GitHubからGCPのpython-docs-samplesをインストールして設定

Google Cloud Platform(GCP)が提供しているpython-docs-samplesレポジトリをベースに構築

$ git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
$ cd python-docs-samples/language/api

必要なライブラリをpipでインストール

$ pip3 install -r requirements.txt

Natural Language APIを叩いてみる

language/api/analyze.pyを実行しAPIを叩いてみる

$ python anlalyze.py <command> <text-string>

で叩けるとのこと。
今回は、

$ python analyze.py entities "約10分間にわたる、次期開催都市の東京をPRする映像やパフォーマンスでは、大トリに安倍晋三首相がサプライズで登場した。"

を叩いてみた。

{
  "entities": [
    {
      "type": "LOCATION",
      "metadata": {
        "wikipedia_url": "http://ja.wikipedia.org/wiki/%E6%9D%B1%E4%BA%AC"
      },
      "salience": 0,
      "mentions": [
        {
          "text": {
            "content": "\u6771\u4eac",
            "beginOffset": 17
          }
        }
      ],
      "name": "\u6771\u4eac"
    },
    {
      "type": "PERSON",
      "metadata": {
        "wikipedia_url": "http://ja.wikipedia.org/wiki/%E5%AE%89%E5%80%8D%E6%99%8B%E4%B8%89"
      },
      "salience": 0,
      "mentions": [
        {
          "text": {
            "content": "\u5b89\u500d\u664b\u4e09",
            "beginOffset": 41
          }
        }
      ],
      "name": "\u5b89\u500d\u664b\u4e09"
    }
  ],
  "language": "ja"
}

東京安倍晋三などの固有表現を抽出できる

APIを叩いた結果をMySQLに保存する

MySQLDBを使おうとしたがPython3系では動かないため、pymysqlをpipでインストール

pip3 install pymysql

MySQLにはpagesテーブルがあり、pagesテーブルのcontentカラムに文章が含まれているものとします
今回は、MySQLからcontentを取得してGCNL APIに投げ、結果をgcnl_entitiesに格納していきます
Google Cloud Platform(GCP)が提供しているpython-docs-samplesレポジトリをベースに構築しました

ところどころ関係のないところは省略しています

#!/usr/bin/env python

# Copyright 2016 Google, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Analyzes text using the Google Cloud Natural Language API."""

import argparse
import json
import sys
import pymysql

from googleapiclient import discovery
import httplib2
from oauth2client.client import GoogleCredentials


def get_service():
    credentials = GoogleCredentials.get_application_default()
    scoped_credentials = credentials.create_scoped(
        ['https://www.googleapis.com/auth/cloud-platform'])
    http = httplib2.Http()
    scoped_credentials.authorize(http)
    return discovery.build('language', 'v1beta1', http=http)

def get_page(page_id):
    con = pymysql.connect(host=HOST,
                          user=USER,
                          passwd=PASSWORD,
                          db=DB,
                          charset='utf8',
                          unix_socket=UNIX_SOCKET,
                          cursorclass=pymysql.cursors.DictCursor)
    try:
        with con.cursor() as cur:
            sql = "SELECT * FROM `pages` WHERE `id` = %s"
            cur.execute(sql, (page_id,))
            page = cur.fetchone()
    except Exception as e:
        print(e)
        sys.exit()
    finally:
        con.close()
    return page

def save_page_gcnl_entities(page_id, gcnl_entities):
    con = pymysql.connect(host=HOST,
                          user=USER,
                          passwd=PASSWORD,
                          db=DB,
                          charset='utf8',
                          unix_socket=UNIX_SOCKET,
                          cursorclass=pymysql.cursors.DictCursor)
    try:
        with con.cursor() as cur:
            sql = "UPDATE `pages` SET `gcnl_entities` = %s, `gcnl_updated` = %s WHERE `id` = %s"
            cur.execute(sql, (gcnl_entities, 1, page_id))
            con.commit()
    except Exception as e:
        print(e)
        sys.exit()
    finally:
        con.close()

...

def analyze_entities(text, encoding='UTF32'):
    body = {
        'document': {
            'type': 'PLAIN_TEXT',
            'content': text,
        },
        'encodingType': encoding,
    }

    service = get_service()

    request = service.documents().analyzeEntities(body=body)
    response = request.execute()

    return response

...

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('environment', choices=[
        'production', 'development'])
    parser.add_argument('command', choices=[
        'entities', 'sentiment', 'syntax'])
    parser.add_argument('page_id')
    args = parser.parse_args()

    if args.environment == 'production':
        HOST = "XX.XX.XX.XX"
        DB = 'database_name'
        USER = 'user_name'
        PASSWORD = 'password'
        UNIX_SOCKET = "/var/run/mysqld/mysqld.sock"
    elif args.environment == 'development':
        HOST = "127.0.0.1"
        DB = 'local_database'
        USER = 'local_user_name'
        PASSWORD = 'password'
        UNIX_SOCKET = "/Applications/MAMP/tmp/mysql/mysql.sock"

    page = get_page(args.page_id)
    text = page["content"]
    try:
        if args.command == 'entities':
            result = analyze_entities(text, get_native_encoding_type())
        elif args.command == 'sentiment':
            result = analyze_sentiment(text)
        elif args.command == 'syntax':
            result = analyze_syntax(text, get_native_encoding_type())
    except Exception as e:
        print(e)
        sys.exit()

    print(json.dumps(result, indent=2))
    save_page_gcnl_entities(args.page_id, json.dumps(result, ensure_ascii=False))

まとめ

おもった以上に簡単に自然言語APIを使うことができます。ただし、月間5000リクエストを超えるとお金がかかってしまうのでご注意ください。また、2016年9月6日現在、ベータ版なので仕様とか料金とか変更の可能性が今後あるとのことです。

参考

Authenticating to a Cloud API Service  |  Google Cloud Natural Language API Documentation  |  Google Cloud Platform


-自然言語処理
-