パスワードを忘れた? アカウント作成
13929635 journal
人工知能

yasuokaの日記: COTOHA APIのUniversal Dependencies向けpython3ラッパー 1

日記 by yasuoka

一昨昨日の日記で、私(安岡孝一)は書いた。

せめてCOTOHA APIも、ちゃんとUniversal Dependencies v2対応してくれないかなぁ。

『自然言語処理のためにMeCabを入れるのに疲れたのでCOTOHA APIを使った』を横目に見つつ、私なりにあれこれ考えてみて、COTOHA API構文解析v1のUniversal Dependencies v2向けpython3ラッパー「Cotoha2UD.py」を書いてみた。UPOSへの変換を、ある程度ちゃんとしようとしたら、思ったより長くなってしまった。

#! /usr/bin/python3 -i

class CotohaEntry:
  def __init__(self,response):
    import json
    self.response=response
    self.result=json.loads(response)["result"]
    self.tokens=[]
    for b in self.result:
      for w in b["tokens"]:
        w["xpos"]=w["pos"] if w["features"]==[] else w["pos"]+"["+",".join(w["features"])+"]"
        w["feats"]="_"
        w["head"]=w
        w["deprel"]="root"
        w["deps"]="_"
        w["misc"]="SpaceAfter=No"
        self.tokens.insert(w["id"],w)
    for w in self.tokens:
      if "dependency_labels" in w:
        for r in w["dependency_labels"]:
          t=self.tokens[r["token_id"]]
          t["head"]=w
          if r["label"]=="neg":
            t["deprel"]="aux"
            t["feats"]="Polarity=Neg"
          else:
            t["deprel"]=r["label"].replace("dobj","obj").replace("name","flat").replace("pass",":pass")
    p={ "名詞接尾辞":"NOUN", "冠名詞":"NOUN", "補助名詞":"NOUN",
        "動詞語幹": "VERB",
        "冠動詞":"ADV", "冠形容詞":"ADV", "連用詞":"ADV",
        "形容詞語幹":"ADJ",
        "連体詞":"DET",
        "接続詞":"CCONJ",
        "独立詞":"INTJ",
        "括弧":"PUNCT", "句点":"PUNCT", "読点":"PUNCT", "空白":"PUNCT",
        "Symbol":"SYM",
        "Number":"NUM" }
    for w in self.tokens:
      if w["pos"]=="名詞":
        w["upos"]="NOUN"
        if "代名詞" in w["xpos"] or "指示" in w["xpos"]:
          w["upos"]="PRON"
        if "固有" in w["xpos"]:
          w["upos"]="PROPN"
      else:
        w["upos"]=p[w["pos"]] if w["pos"] in p else "PART"
      if w["deprel"]=="case":
        w["upos"]="ADP"
      elif w["deprel"]=="cop" or w["deprel"].startswith("aux"):
        w["upos"]="AUX"
  def __repr__(self):
    return "".join("\t".join([str(t["id"]+1),t["form"],t["lemma"],t["upos"],t["xpos"],t["feats"],str(0 if t["head"] is t else t["head"]["id"]+1),t["deprel"],t["deps"],t["misc"]])+"\n" for t in self.tokens)
  def browse(self):
    import webbrowser,urllib.parse
    h="http://kanji.zinbun.kyoto-u.ac.jp/~yasuoka/kyodokenkyu/ud-kanbun/conllusvg/viewer.svg"
    webbrowser.open(h+"#"+urllib.parse.quote(str(self)))

class Cotoha2UD:
  def __init__(self,accessToken):
    self.parseURL="https://api.ce-cotoha.com/api/dev/nlp/v1/parse"
    self.accessToken=accessToken
  def __call__(self,sentence):
    import urllib.request,json
    h={ "Content-Type":"application/json;charset=UTF-8",
        "Authorization":"Bearer "+self.accessToken }
    d={ "sentence":sentence }
    u=urllib.request.Request(self.parseURL,json.dumps(d).encode(),h)
    with urllib.request.urlopen(u) as r:
      q=r.read()
    return CotohaEntry(q)

上のプログラムを「Cotoha2UD.py」に保存したら、ちょっと面倒くさい手順で「アクセストークン」を取得する。そこまでが出来たら、とりあえず「望遠鏡で泳ぐ彼女をみた」を、Cotoha2UDで係り受け解析してみよう。

% python3 -i Cotoha2UD.py
>>> ja=Cotoha2UD(accessToken="アクセストークン")
>>> s=ja("望遠鏡で泳ぐ彼女を見た")
>>> s.browse()
>>> print(s)
1    望遠鏡    望遠鏡    NOUN    名詞    _    3    nmod    _    SpaceAfter=No
2    で    で    ADP    格助詞[連用]    _    1    case    _    SpaceAfter=No
3    泳    泳ぐ    VERB    動詞語幹[G]    _    5    amod    _    SpaceAfter=No
4    ぐ    ぐ    AUX    動詞接尾辞[連体]    _    3    aux    _    SpaceAfter=No
5    彼女    彼女    PRON    名詞[代名詞]    _    7    obj    _    SpaceAfter=No
6    を    を    ADP    格助詞[連用]    _    5    case    _    SpaceAfter=No
7    見    見る    VERB    動詞語幹[A]    _    0    root    _    SpaceAfter=No
8    た    た    AUX    動詞接尾辞[終止]    _    7    aux    _    SpaceAfter=No

うまく行けば、こんな感じのブラウザが立ち上がってきて、↑のUniversal Dependenciesが出力される。本来「望遠鏡←obl─見」となるべきところ、この出力結果では「望遠鏡←nmod─泳」となってしまっているが、これはCOTOHA APIが解析をミスっているためなので、私としてはどうにもならない。うーん、COTOHA APIは「アクセストークン」が手間だし、1日1000回の制限があるし、やっぱりUDPipe APIの方が楽かなぁ…。

この議論は、yasuoka (21275)によって ログインユーザだけとして作成されたが、今となっては 新たにコメントを付けることはできません。
typodupeerror

物事のやり方は一つではない -- Perlな人

読み込み中...