Help us understand the problem. What is going on with this article?

自然言語処理を簡単に扱えると噂のCOTOHA APIをPythonで使ってみた

More than 1 year has passed since last update.

これはなんの記事?

簡単に自然言語処理が行えるAPIサービス「COTOHA API」の紹介と実践記事です。

はじめに

皆さまはじめまして。
楽しいCOTOHA APIライフを送っていますか?
この記事をお読みの皆様の中にはCOTOHA APIを知らない方もいらっしゃるかもしれません。
今回は、そんな方々に向けてCOTOHA APIの使い方や解説などを行っていこうと思います。

COTOHA APIとは

記事のタイトルにも入っているCOTOHA APIですが、詳しい説明はこちらに譲るとして、概要だけ説明しておきます。
まず、COTOHA APIは2018年6月にサービスを開始したAPIサービスになります。
2018年9月時点では以下のAPI群を提供しています。

  • 構文解析
  • 固有表現抽出
  • 照応解析
  • キーワード抽出
  • 類似度算出
  • 文タイプ判定
  • ユーザ属性推定

上記ラインナップはいわゆる自然言語処理用途のものばかりですが、今後順次追加予定なので乞うご期待。
また、「こんなAPIが欲しい」というような要望もお待ちしております。
アカウント登録から入力できますので、とりあえず登録してみましょう。
そして使ってみてください。

Pythonで使ってみた

みなさんアカウント登録は終わりましたね。
登録時に聞かれるアンケート項目が多いかもしれないですが、今後の開発の参考にしますのでご協力お願いします。
さて、今回の記事はPythonでのCOTOHA APIの使い方です。
某アンケートによると、自然言語処理エンジニアの約2/3がPythonを利用しているらしいです。

機械学習系のライブラリが充実しているだけあって、AIエンジニアのPython率はすごいですね。
というわけでマジョリティに向けてCOTOHA APIの使い方を書いていこうと思います。
既にPython使ってる人には退屈な内容かもしれませんがご容赦を。
むしろ、アンケート時に開発言語「なし」を選んだ方々に読んでもらいたい記事かもしれないです。
これを読んだら今日からあなたもPythonista!

Pythonインストール

さて、まずはPythonのインストールからです。
既にインストールしてるよという方にはすみません。読み飛ばしてください。
インストール方法ですが、お使いのOSによって変わってきます。

Windows

こちらの記事とかを参考にインストールしてください。
今新しくインストールするならPython3系でいいと思います。

Mac

プリインストールされていると思います。
一応以下のコマンドでもインストールできます。

$ brew install python

Linux

Macと同様にプリインストールされていると思います。
一応以下のコマンドでもインストールできます。

  • Ubuntu
$ apt-get install python
  • CentOS
$ yum install python

上記以外のディストリビューションをお使いの方はググってください。

サンプルコード

早速ですが、PythonでCOTOHA APIの各APIを叩くサンプルコードがこちらになります。
見づらいだとか冗長だとか汚いとか色々あるとは思いますが、なんとか目をつぶってください。
移植性とコメントを重視した結果です。
全部標準ライブラリで動くはずです。

スクリプトファイル(Python3系をお使いの方)
cotoha_api_python3.py
# -*- coding:utf-8 -*-

import os
import urllib.request
import json
import configparser
import codecs


# COTOHA API操作用クラス
class CotohaApi:
    # 初期化
    def __init__(self, client_id, client_secret, developer_api_base_url, access_token_publish_url):
        self.client_id = client_id
        self.client_secret = client_secret
        self.developer_api_base_url = developer_api_base_url
        self.access_token_publish_url = access_token_publish_url
        self.getAccessToken()

    # アクセストークン取得
    def getAccessToken(self):
        # アクセストークン取得URL指定
        url = self.access_token_publish_url

        # ヘッダ指定
        headers={
            "Content-Type": "application/json;charset=UTF-8"
        }

        # リクエストボディ指定
        data = {
            "grantType": "client_credentials",
            "clientId": self.client_id,
            "clientSecret": self.client_secret
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data).encode()

        # リクエスト生成
        req = urllib.request.Request(url, data, headers)

        # リクエストを送信し、レスポンスを受信
        res = urllib.request.urlopen(req)

        # レスポンスボディ取得
        res_body = res.read()

        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)

        # レスポンスボディからアクセストークンを取得
        self.access_token = res_body["access_token"]


    # 構文解析API
    def parse(self, sentence):
        # 構文解析API URL指定
        url = self.developer_api_base_url + "v1/parse"
        # ヘッダ指定
        headers={
            "Authorization": "Bearer " + self.access_token,
            "Content-Type": "application/json;charset=UTF-8",
        }
        # リクエストボディ指定
        data = {
            "sentence": sentence
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data).encode()
        # リクエスト生成
        req = urllib.request.Request(url, data, headers)
        # リクエストを送信し、レスポンスを受信
        try:
            res = urllib.request.urlopen(req)
        # リクエストでエラーが発生した場合の処理
        except urllib.request.HTTPError as e:
            # ステータスコードが401 Unauthorizedならアクセストークンを取得し直して再リクエスト
            if e.code == 401:
                print ("get access token")
                self.access_token = getAccessToken(self.client_id, self.client_secret)
                headers["Authorization"] = "Bearer " + self.access_token
                req = urllib.request.Request(url, data, headers)
                res = urllib.request.urlopen(req)
            # 401以外のエラーなら原因を表示
            else:
                print ("<Error> " + e.reason)

        # レスポンスボディ取得
        res_body = res.read()
        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)
        # レスポンスボディから解析結果を取得
        return res_body


    # 固有表現抽出API
    def ne(self, sentence):
        # 固有表現抽出API URL指定
        url = self.developer_api_base_url + "v1/ne"
        # ヘッダ指定
        headers={
            "Authorization": "Bearer " + self.access_token,
            "Content-Type": "application/json;charset=UTF-8",
        }
        # リクエストボディ指定
        data = {
            "sentence": sentence
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data).encode()
        # リクエスト生成
        req = urllib.request.Request(url, data, headers)
        # リクエストを送信し、レスポンスを受信
        try:
            res = urllib.request.urlopen(req)
        # リクエストでエラーが発生した場合の処理
        except urllib.request.HTTPError as e:
            # ステータスコードが401 Unauthorizedならアクセストークンを取得し直して再リクエスト
            if e.code == 401:
                print ("get access token")
                self.access_token = getAccessToken(self.client_id, self.client_secret)
                headers["Authorization"] = "Bearer " + self.access_token
                req = urllib.request.Request(url, data, headers)
                res = urllib.request.urlopen(req)
            # 401以外のエラーなら原因を表示
            else:
                print ("<Error> " + e.reason)

        # レスポンスボディ取得
        res_body = res.read()
        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)
        # レスポンスボディから解析結果を取得
        return res_body


    # 照応解析API
    def coreference(self, document):
        # 照応解析API 取得URL指定
        url = self.developer_api_base_url + "beta/coreference"
        # ヘッダ指定
        headers={
            "Authorization": "Bearer " + self.access_token,
            "Content-Type": "application/json;charset=UTF-8",
        }
        # リクエストボディ指定
        data = {
            "document": document
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data).encode()
        # リクエスト生成
        req = urllib.request.Request(url, data, headers)
        # リクエストを送信し、レスポンスを受信
        try:
            res = urllib.request.urlopen(req)
        # リクエストでエラーが発生した場合の処理
        except urllib.request.HTTPError as e:
            # ステータスコードが401 Unauthorizedならアクセストークンを取得し直して再リクエスト
            if e.code == 401:
                print ("get access token")
                self.access_token = getAccessToken(self.client_id, self.client_secret)
                headers["Authorization"] = "Bearer " + self.access_token
                req = urllib.request.Request(url, data, headers)
                res = urllib.request.urlopen(req)
            # 401以外のエラーなら原因を表示
            else:
                print ("<Error> " + e.reason)

        # レスポンスボディ取得
        res_body = res.read()
        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)
        # レスポンスボディから解析結果を取得
        return res_body


    # キーワード抽出API
    def keyword(self, document):
        # キーワード抽出API URL指定
        url = self.developer_api_base_url + "v1/keyword"
        # ヘッダ指定
        headers={
            "Authorization": "Bearer " + self.access_token,
            "Content-Type": "application/json;charset=UTF-8",
        }
        # リクエストボディ指定
        data = {
            "document": document
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data).encode()
        # リクエスト生成
        req = urllib.request.Request(url, data, headers)
        # リクエストを送信し、レスポンスを受信
        try:
            res = urllib.request.urlopen(req)
        # リクエストでエラーが発生した場合の処理
        except urllib.request.HTTPError as e:
            # ステータスコードが401 Unauthorizedならアクセストークンを取得し直して再リクエスト
            if e.code == 401:
                print ("get access token")
                self.access_token = getAccessToken(self.client_id, self.client_secret)
                headers["Authorization"] = "Bearer " + self.access_token
                req = urllib.request.Request(url, data, headers)
                res = urllib.request.urlopen(req)
            # 401以外のエラーなら原因を表示
            else:
                print ("<Error> " + e.reason)

        # レスポンスボディ取得
        res_body = res.read()
        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)
        # レスポンスボディから解析結果を取得
        return res_body


    # 類似度算出API
    def similarity(self, s1, s2):
        # 類似度算出API URL指定
        url = self.developer_api_base_url + "v1/similarity"
        # ヘッダ指定
        headers={
            "Authorization": "Bearer " + self.access_token,
            "Content-Type": "application/json;charset=UTF-8",
        }
        # リクエストボディ指定
        data = {
            "s1": s1,
            "s2": s2
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data).encode()
        # リクエスト生成
        req = urllib.request.Request(url, data, headers)
        # リクエストを送信し、レスポンスを受信
        try:
            res = urllib.request.urlopen(req)
        # リクエストでエラーが発生した場合の処理
        except urllib.request.HTTPError as e:
            # ステータスコードが401 Unauthorizedならアクセストークンを取得し直して再リクエスト
            if e.code == 401:
                print ("get access token")
                self.access_token = getAccessToken(self.client_id, self.client_secret)
                headers["Authorization"] = "Bearer " + self.access_token
                req = urllib.request.Request(url, data, headers)
                res = urllib.request.urlopen(req)
            # 401以外のエラーなら原因を表示
            else:
                print ("<Error> " + e.reason)

        # レスポンスボディ取得
        res_body = res.read()
        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)
        # レスポンスボディから解析結果を取得
        return res_body


    # 文タイプ判定API
    def sentenceType(self, sentence):
        # 文タイプ判定API URL指定
        url = self.developer_api_base_url + "v1/sentence_type"
        # ヘッダ指定
        headers={
            "Authorization": "Bearer " + self.access_token,
            "Content-Type": "application/json;charset=UTF-8",
        }
        # リクエストボディ指定
        data = {
            "sentence": sentence
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data).encode()
        # リクエスト生成
        req = urllib.request.Request(url, data, headers)
        # リクエストを送信し、レスポンスを受信
        try:
            res = urllib.request.urlopen(req)
        # リクエストでエラーが発生した場合の処理
        except urllib.request.HTTPError as e:
            # ステータスコードが401 Unauthorizedならアクセストークンを取得し直して再リクエスト
            if e.code == 401:
                print ("get access token")
                self.access_token = getAccessToken(self.client_id, self.client_secret)
                headers["Authorization"] = "Bearer " + self.access_token
                req = urllib.request.Request(url, data, headers)
                res = urllib.request.urlopen(req)
            # 401以外のエラーなら原因を表示
            else:
                print ("<Error> " + e.reason)

        # レスポンスボディ取得
        res_body = res.read()
        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)
        # レスポンスボディから解析結果を取得
        return res_body


    # ユーザ属性推定API
    def userAttribute(self, document):
        # ユーザ属性推定API URL指定
        url = self.developer_api_base_url + "beta/user_attribute"
        # ヘッダ指定
        headers={
            "Authorization": "Bearer " + self.access_token,
            "Content-Type": "application/json;charset=UTF-8",
        }
        # リクエストボディ指定
        data = {
            "document": document
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data).encode()
        # リクエスト生成
        req = urllib.request.Request(url, data, headers)
        # リクエストを送信し、レスポンスを受信
        try:
            res = urllib.request.urlopen(req)
        # リクエストでエラーが発生した場合の処理
        except urllib.request.HTTPError as e:
            # ステータスコードが401 Unauthorizedならアクセストークンを取得し直して再リクエスト
            if e.code == 401:
                print ("get access token")
                self.access_token = getAccessToken(self.client_id, self.client_secret)
                headers["Authorization"] = "Bearer " + self.access_token
                req = urllib.request.Request(url, data, headers)
                res = urllib.request.urlopen(req)
            # 401以外のエラーなら原因を表示
            else:
                print ("<Error> " + e.reason)

        # レスポンスボディ取得
        res_body = res.read()
        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)
        # レスポンスボディから解析結果を取得
        return res_body



if __name__ == '__main__':
    # ソースファイルの場所取得
    APP_ROOT = os.path.dirname(os.path.abspath( __file__)) + "/"

    # 設定値取得
    config = configparser.ConfigParser()
    config.read(APP_ROOT + "config.ini")
    CLIENT_ID = config.get("COTOHA API", "Developer Client id")
    CLIENT_SECRET = config.get("COTOHA API", "Developer Client secret")
    DEVELOPER_API_BASE_URL = config.get("COTOHA API", "Developer API Base URL")
    ACCESS_TOKEN_PUBLISH_URL = config.get("COTOHA API", "Access Token Publish URL")

    # COTOHA APIインスタンス生成
    cotoha_api = CotohaApi(CLIENT_ID, CLIENT_SECRET, DEVELOPER_API_BASE_URL, ACCESS_TOKEN_PUBLISH_URL)

    # 解析対象文
    sentence = "すもももももももものうち"

    # 構文解析API実行
    result = cotoha_api.parse(sentence)

    # 出力結果を見やすく整形
    result_formated = json.dumps(result, indent=4, separators=(',', ': '))
    print (codecs.decode(result_formated, 'unicode-escape'))

スクリプトファイル(Python2系をお使いの方)
cotoha_api_python2.py
# -*- coding:utf-8 -*-

import os
import urllib2
import json
import ConfigParser


# COTOHA API操作用クラス
class CotohaApi:
    # 初期化
    def __init__(self, client_id, client_secret, developer_api_base_url, access_token_publish_url):
        self.client_id = client_id
        self.client_secret = client_secret
        self.developer_api_base_url = developer_api_base_url
        self.access_token_publish_url = access_token_publish_url
        self.getAccessToken()

    # アクセストークン取得
    def getAccessToken(self):
        # アクセストークン取得URL指定
        url = self.access_token_publish_url

        # ヘッダ指定
        headers={
            "Content-Type": "application/json;charset=UTF-8"
        }

        # リクエストボディ指定
        data = {
            "grantType": "client_credentials",
            "clientId": self.client_id,
            "clientSecret": self.client_secret
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data)

        # リクエスト生成
        req = urllib2.Request(url, data, headers)

        # リクエストを送信し、レスポンスを受信
        res = urllib2.urlopen(req)

        # レスポンスボディ取得
        res_body = res.read()

        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)

        # レスポンスボディからアクセストークンを取得
        self.access_token = res_body["access_token"]


    # 構文解析API
    def parse(self, sentence):
        # 構文解析API URL指定
        url = self.developer_api_base_url + "v1/parse"
        # ヘッダ指定
        headers={
            "Authorization": "Bearer " + self.access_token,
            "Content-Type": "application/json;charset=UTF-8",
        }
        # リクエストボディ指定
        data = {
            "sentence": sentence
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data)
        # リクエスト生成
        req = urllib2.Request(url, data, headers)
        # リクエストを送信し、レスポンスを受信
        try:
            res = urllib2.urlopen(req)
        # リクエストでエラーが発生した場合の処理
        except urllib2.HTTPError as e:
            # ステータスコードが401 Unauthorizedならアクセストークンを取得し直して再リクエスト
            if e.code == 401:
                print "get access token"
                self.getAccessToken()
                headers["Authorization"] = "Bearer " + self.access_token
                req = urllib2.Request(url, data, headers)
                res = urllib2.urlopen(req)
            # 401以外のエラーなら原因を表示
            else:
                print "<Error> " + e.reason

        # レスポンスボディ取得
        res_body = res.read()
        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)
        # レスポンスボディから解析結果を取得
        return res_body


    # 固有表現抽出API
    def ne(self, sentence):
        # 固有表現抽出API URL指定
        url = self.developer_api_base_url + "v1/ne"
        # ヘッダ指定
        headers={
            "Authorization": "Bearer " + self.access_token,
            "Content-Type": "application/json;charset=UTF-8",
        }
        # リクエストボディ指定
        data = {
            "sentence": sentence
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data)
        # リクエスト生成
        req = urllib2.Request(url, data, headers)
        # リクエストを送信し、レスポンスを受信
        try:
            res = urllib2.urlopen(req)
        # リクエストでエラーが発生した場合の処理
        except urllib2.HTTPError as e:
            # ステータスコードが401 Unauthorizedならアクセストークンを取得し直して再リクエスト
            if e.code == 401:
                print "get access token"
                self.getAccessToken()
                headers["Authorization"] = "Bearer " + self.access_token
                req = urllib2.Request(url, data, headers)
                res = urllib2.urlopen(req)
            # 401以外のエラーなら原因を表示
            else:
                print "<Error> " + e.reason

        # レスポンスボディ取得
        res_body = res.read()
        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)
        # レスポンスボディから解析結果を取得
        return res_body


    # 照応解析API
    def coreference(self, document):
        # 照応解析API 取得URL指定
        url = self.developer_api_base_url + "beta/coreference"
        # ヘッダ指定
        headers={
            "Authorization": "Bearer " + self.access_token,
            "Content-Type": "application/json;charset=UTF-8",
        }
        # リクエストボディ指定
        data = {
            "document": document
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data)
        # リクエスト生成
        req = urllib2.Request(url, data, headers)
        # リクエストを送信し、レスポンスを受信
        try:
            res = urllib2.urlopen(req)
        # リクエストでエラーが発生した場合の処理
        except urllib2.HTTPError as e:
            # ステータスコードが401 Unauthorizedならアクセストークンを取得し直して再リクエスト
            if e.code == 401:
                print "get access token"
                self.getAccessToken()
                headers["Authorization"] = "Bearer " + self.access_token
                req = urllib2.Request(url, data, headers)
                res = urllib2.urlopen(req)
            # 401以外のエラーなら原因を表示
            else:
                print "<Error> " + e.reason

        # レスポンスボディ取得
        res_body = res.read()
        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)
        # レスポンスボディから解析結果を取得
        return res_body


    # キーワード抽出API
    def keyword(self, document):
        # キーワード抽出API URL指定
        url = self.developer_api_base_url + "v1/keyword"
        # ヘッダ指定
        headers={
            "Authorization": "Bearer " + self.access_token,
            "Content-Type": "application/json;charset=UTF-8",
        }
        # リクエストボディ指定
        data = {
            "document": document
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data)
        # リクエスト生成
        req = urllib2.Request(url, data, headers)
        # リクエストを送信し、レスポンスを受信
        try:
            res = urllib2.urlopen(req)
        # リクエストでエラーが発生した場合の処理
        except urllib2.HTTPError as e:
            # ステータスコードが401 Unauthorizedならアクセストークンを取得し直して再リクエスト
            if e.code == 401:
                print "get access token"
                self.access_token = getAccessToken(self.client_id, self.client_secret)
                headers["Authorization"] = "Bearer " + self.access_token
                req = urllib2.Request(url, data, headers)
                res = urllib2.urlopen(req)
            # 401以外のエラーなら原因を表示
            else:
                print "<Error> " + e.reason

        # レスポンスボディ取得
        res_body = res.read()
        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)
        # レスポンスボディから解析結果を取得
        return res_body


    # 類似度算出API
    def similarity(self, s1, s2):
        # 類似度算出API URL指定
        url = self.developer_api_base_url + "v1/similarity"
        # ヘッダ指定
        headers={
            "Authorization": "Bearer " + self.access_token,
            "Content-Type": "application/json;charset=UTF-8",
        }
        # リクエストボディ指定
        data = {
            "s1": s1,
            "s2": s2
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data)
        # リクエスト生成
        req = urllib2.Request(url, data, headers)
        # リクエストを送信し、レスポンスを受信
        try:
            res = urllib2.urlopen(req)
        # リクエストでエラーが発生した場合の処理
        except urllib2.HTTPError as e:
            # ステータスコードが401 Unauthorizedならアクセストークンを取得し直して再リクエスト
            if e.code == 401:
                print "get access token"
                self.access_token = getAccessToken(self.client_id, self.client_secret)
                headers["Authorization"] = "Bearer " + self.access_token
                req = urllib2.Request(url, data, headers)
                res = urllib2.urlopen(req)
            # 401以外のエラーなら原因を表示
            else:
                print "<Error> " + e.reason

        # レスポンスボディ取得
        res_body = res.read()
        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)
        # レスポンスボディから解析結果を取得
        return res_body


    # 文タイプ判定API
    def sentenceType(self, sentence):
        # 文タイプ判定API URL指定
        url = self.developer_api_base_url + "v1/sentence_type"
        # ヘッダ指定
        headers={
            "Authorization": "Bearer " + self.access_token,
            "Content-Type": "application/json;charset=UTF-8",
        }
        # リクエストボディ指定
        data = {
            "sentence": sentence
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data)
        # リクエスト生成
        req = urllib2.Request(url, data, headers)
        # リクエストを送信し、レスポンスを受信
        try:
            res = urllib2.urlopen(req)
        # リクエストでエラーが発生した場合の処理
        except urllib2.HTTPError as e:
            # ステータスコードが401 Unauthorizedならアクセストークンを取得し直して再リクエスト
            if e.code == 401:
                print "get access token"
                self.access_token = getAccessToken(self.client_id, self.client_secret)
                headers["Authorization"] = "Bearer " + self.access_token
                req = urllib2.Request(url, data, headers)
                res = urllib2.urlopen(req)
            # 401以外のエラーなら原因を表示
            else:
                print "<Error> " + e.reason

        # レスポンスボディ取得
        res_body = res.read()
        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)
        # レスポンスボディから解析結果を取得
        return res_body


    # ユーザ属性推定API
    def userAttribute(self, document):
        # ユーザ属性推定API URL指定
        url = self.developer_api_base_url + "beta/user_attribute"
        # ヘッダ指定
        headers={
            "Authorization": "Bearer " + self.access_token,
            "Content-Type": "application/json;charset=UTF-8",
        }
        # リクエストボディ指定
        data = {
            "document": document
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data)
        # リクエスト生成
        req = urllib2.Request(url, data, headers)
        # リクエストを送信し、レスポンスを受信
        try:
            res = urllib2.urlopen(req)
        # リクエストでエラーが発生した場合の処理
        except urllib2.HTTPError as e:
            # ステータスコードが401 Unauthorizedならアクセストークンを取得し直して再リクエスト
            if e.code == 401:
                print "get access token"
                self.access_token = getAccessToken(self.client_id, self.client_secret)
                headers["Authorization"] = "Bearer " + self.access_token
                req = urllib2.Request(url, data, headers)
                res = urllib2.urlopen(req)
            # 401以外のエラーなら原因を表示
            else:
                print "<Error> " + e.reason

        # レスポンスボディ取得
        res_body = res.read()
        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)
        # レスポンスボディから解析結果を取得
        return res_body



if __name__ == '__main__':
    # ソースファイルの場所取得
    APP_ROOT = os.path.dirname(os.path.abspath( __file__)) + "/"

    # 設定値取得
    config = ConfigParser.SafeConfigParser()
    config.read(APP_ROOT + "config.ini")
    CLIENT_ID = config.get("COTOHA API", "Developer Client id")
    CLIENT_SECRET = config.get("COTOHA API", "Developer Client secret")
    DEVELOPER_API_BASE_URL = config.get("COTOHA API", "Developer API Base URL")
    ACCESS_TOKEN_PUBLISH_URL = config.get("COTOHA API", "Access Token Publish URL")

    # COTOHA APIインスタンス生成
    cotoha_api = CotohaApi(CLIENT_ID, CLIENT_SECRET, DEVELOPER_API_BASE_URL, ACCESS_TOKEN_PUBLISH_URL)

    # 解析対象文
    sentence = "すもももももももものうち"

    # 構文解析API実行
    result = cotoha_api.parse(sentence)

    # 出力結果を見やすく整形
    result_formated = json.dumps(result, indent=4, separators=(',', ': '))
    # Unicodeエスケープされたバイト列から文字列に変換
    print result_formated.decode('unicode-escape')

設定ファイル
config.ini
[COTOHA API]
Developer API Base URL: https://api.ce-cotoha.com/api/dev/nlp/
Developer Client id: AAAAAAAAAAAAAAAAAAAAAAAAAA
Developer Client secret: aaaaaaaaaaaaaaaaaaaaaaaaaa
Access Token Publish URL: https://api.ce-cotoha.com/v1/oauth/accesstokens

まずは、ご利用のPythonのバージョンに応じたファイルを同一のフォルダ(ディレクトリ)に保存してください。
Python3系をお使いの場合はcotoha_api_python3.pyを、Python2系をお使いの場合はcotoha_api_python2.pyが今回使うスクリプトファイルとなります。
config.iniは設定ファイルで、いずれのPythonバージョンにおいても必要となります。
ちなみにPythonのバージョンは以下のコマンドで確認できます。

$ python --version
Python 3.7.0
$ python --version
Python 2.7.15

正常にPythonがインストールされている環境で上記コマンドを実行すると、上の例のような結果が返ってきます。
Pythonの後に続く数字が3ならばPython3系が、数字が2ならばPython2系がインストールされているということになります。
簡単ですね。

さて、本題に戻りましょう。
先程保存したconfig.ini 中のDeveloper Client idDeveloper Client secretはダミーの値が入っているので、ご自分のものに書き換えてください。
Developer Client idDeveloper Client secretは、アカウントホームで確認できます。
書き換えたら後は実行するだけです。
コマンドプロンプト、もしくはターミナルでファイルを保存したディレクトリに移動し、下記コマンドを実行!

$ python cotoha_api.py

以下のような結果が出力されたら成功です。
ここでは試しに「すもももももももものうち」という文章を解析してみました。
解析結果の意味はこちらをご参考ください。

構文解析API出力結果
{
    "status": 0,
    "message": "",
    "result": [
        {
            "chunk_info": {
                "head": 1,
                "links": [],
                "dep": "P",
                "chunk_func": 1,
                "chunk_head": 0,
                "id": 0
            },
            "tokens": [
                {
                    "features": [],
                    "form": "すもも",
                    "pos": "名詞",
                    "kana": "スモモ",
                    "lemma": "李",
                    "dependency_labels": [
                        {
                            "token_id": 1,
                            "label": "case"
                        }
                    ],
                    "attributes": {},
                    "id": 0
                },
                {
                    "features": [],
                    "form": "も",
                    "pos": "連用助詞",
                    "kana": "モ",
                    "lemma": "も",
                    "attributes": {},
                    "id": 1
                }
            ]
        },
        {
            "chunk_info": {
                "head": 3,
                "links": [
                    {
                        "link": 0,
                        "label": "other"
                    }
                ],
                "dep": "D",
                "chunk_func": 1,
                "chunk_head": 0,
                "id": 1
            },
            "tokens": [
                {
                    "features": [],
                    "form": "もも",
                    "pos": "名詞",
                    "kana": "モモ",
                    "lemma": "桃",
                    "dependency_labels": [
                        {
                            "token_id": 0,
                            "label": "nmod"
                        },
                        {
                            "token_id": 3,
                            "label": "case"
                        }
                    ],
                    "attributes": {},
                    "id": 2
                },
                {
                    "features": [],
                    "form": "も",
                    "pos": "連用助詞",
                    "kana": "モ",
                    "lemma": "も",
                    "attributes": {},
                    "id": 3
                }
            ]
        },
        {
            "chunk_info": {
                "head": 3,
                "links": [],
                "dep": "D",
                "chunk_func": 1,
                "chunk_head": 0,
                "id": 2
            },
            "tokens": [
                {
                    "features": [],
                    "form": "もも",
                    "pos": "名詞",
                    "kana": "モモ",
                    "lemma": "桃",
                    "dependency_labels": [
                        {
                            "token_id": 5,
                            "label": "case"
                        }
                    ],
                    "attributes": {},
                    "id": 4
                },
                {
                    "features": [
                        "連体"
                    ],
                    "form": "の",
                    "pos": "格助詞",
                    "kana": "ノ",
                    "lemma": "の",
                    "attributes": {},
                    "id": 5
                }
            ]
        },
        {
            "chunk_info": {
                "head": -1,
                "links": [
                    {
                        "link": 1,
                        "label": "other"
                    },
                    {
                        "link": 2,
                        "label": "adjectivals"
                    }
                ],
                "dep": "O",
                "chunk_func": 0,
                "chunk_head": 0,
                "id": 3
            },
            "tokens": [
                {
                    "features": [
                        "連用"
                    ],
                    "form": "うち",
                    "pos": "名詞",
                    "kana": "ウチ",
                    "lemma": "内",
                    "dependency_labels": [
                        {
                            "token_id": 2,
                            "label": "nmod"
                        },
                        {
                            "token_id": 4,
                            "label": "nmod"
                        }
                    ],
                    "attributes": {},
                    "id": 6
                }
            ]
        }
    ]
}

スクリプトファイル(cotoha_api_python3.pyorcotoha_api_python2.py)の359行目で構文解析対象文字列を指定しているので、ここを書き換えれば好きな文字列を解析できます。
また、構文解析以外のAPIを使う場合は、スクリプトファイル362行目で呼び出すメソッドを好きなものに変えていただければOKです。
各APIの情報はこちらに色々書いてあります。

まとめ

Pythonから簡単に言語処理ができた!!!!

COTOHA APIすごい!!!

nttcommunications
NTTコミュニケーションズは、お客さまのデジタルトランスフォーメーション実現に貢献する「DX Enabler™」として、ICTの活用によるお客さまの経営課題の解決やスマートな社会の実現に取り組みます。
https://www.ntt.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした