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

yasuokaの日記: UDPipe APIのpython3ラッパー

日記 by yasuoka

昨日の日記を読みながら、LINDAT/CLARINのUDPipe API向けpython3ラッパー「UDPipe2UD.py」を書いてみた。Universal Dependenciesのid、form、lemma、upos、xpos、feats、head、deprel、deps、miscを全部格納するようにしたため、ちょっと長くなってしまった。

#! /usr/bin/python3 -i

class UDPipeEntry:
  def __init__(self,result):
    self.result=result
    if "\n" in result:
      t=[]
      for r in result.split("\n"):
        w=UDPipeEntry(r)
        if w.id>0:
          t.append(w)
      for i,w in enumerate(t):
        w.head=w if w.head==0 else t[i+w.head-w.id]
      self.tokens=t
    else:
      w=result.split("\t")
      try:
        w[0],w[6]=int(w[0]),int(w[6])
      except:
        w=[0]*10
      self.id,self.form,self.lemma,self.upos,self.xpos,self.feats,self.head,self.deprel,self.deps,self.misc=w if len(w)==10 else [0]*10
  def __repr__(self):
    return self.result
  def __getitem__(self,item):
    return self.tokens[item]
  def __len__(self):
    return len(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 UDPipe2UD:
  def __init__(self,lang="ja",option="tokenizer&tagger&parser"):
    self.parseURL="http://lindat.mff.cuni.cz/services/udpipe/api/process?model="+lang+"&"+option
  def __call__(self,sentence):
    import urllib.request,urllib.parse,json
    with urllib.request.urlopen(self.parseURL+"&data="+urllib.parse.quote(sentence)) as r:
      q=r.read()
    return UDPipeEntry(json.loads(q)["result"])

上のプログラムを「UDPipe2UD.py」に保存したら、とりあえず「望遠鏡で泳ぐ彼女を見た」をUDPipe2UDで係り受け解析してみよう。

% python3 -i UDPipe2UD.py
>>> ja=UDPipe2UD(lang="ja")
>>> s=ja("望遠鏡で泳ぐ彼女を見た")
>>> s.browse()
>>> print(s)
# newdoc
# newpar
# sent_id = 1
# text = 望遠鏡で泳ぐ彼女を見た
1    望遠鏡    望遠鏡    NOUN    NN    _    3    obl    _    SpaceAfter=No
2    で    で    ADP    PS    _    1    case    _    SpaceAfter=No
3    泳ぐ    泳ぐ    VERB    VV    _    4    acl    _    SpaceAfter=No
4    彼女    彼女    PRON    NP    _    6    obj    _    SpaceAfter=No
5    を    を    ADP    PS    _    4    case    _    SpaceAfter=No
6    見    見る    VERB    VV    _    0    root    _    SpaceAfter=No
7    た    た    AUX    AV    _    6    aux    _    SpaceAfter=No

うまく行けば、こんな感じのブラウザが立ち上がってきて、↑のUniversal Dependenciesが出力される。本来「望遠鏡←obl─見」となるべきところ、この出力結果では「望遠鏡←obl─泳ぐ」となってしまっているが、現時点ではUDPipeの解析性能が足りない、ということだろう。

>>> print(s[0])
1    望遠鏡    望遠鏡    NOUN    NN    _    3    obl    _    SpaceAfter=No
>>> print(s[0].lemma)
望遠鏡
>>> print(s[2])
3    泳ぐ    泳ぐ    VERB    VV    _    4    acl    _    SpaceAfter=No
>>> print(s[2].upos)
VERB
>>> print(s[2].head)
4    彼女    彼女    PRON    NP    _    6    obj    _    SpaceAfter=No
>>> print(s[2].head.head)
6    見    見る    VERB    VV    _    0    root    _    SpaceAfter=No

なお、この「UDPipe2UD.py」は、他の言語にも対応している。英語なら

>>> en=UDPipe2UD(lang="en")
>>> s=en("He sat down with smiling face")
>>> s.browse()
>>> print(s)

で、古典中国語(漢文)なら

>>> lzh=UDPipe2UD(lang="lzh",option="tokenizer=presegmented&tagger&parser")
>>> s=lzh("不入虎穴不得虎子")
>>> s.browse()
>>> print(s)

で、それぞれ動作するはずである。ぜひ試してみてほしい。

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

人生unstable -- あるハッカー

読み込み中...