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

yasuokaの日記: esuparのセルビア語係り受け解析モデルroberta-base-serbian-uposリリース

日記 by yasuoka

多言語係り受け解析ツールesupar向けに、セルビア語係り受けモデルroberta-base-serbian-uposを作成してみた。セルビア語はキリル文字とラテン文字の両方の書写法があるため、そのあたりの「渡り」をつけるべく、私(安岡孝一)なりに手こずった。最新版のesuparとともに試してみよう。

$ pip3 install -U esupar --user
$ python3
>>> import esupar
>>> nlp=esupar.load("KoichiYasuoka/roberta-base-serbian-upos")
>>> doc=nlp("Да има сира и масла и моја би мати знала гибати гибаницу.")
>>> import deplacy
>>> deplacy.render(doc,WordRight=True)
 mark       ╔══════> SCONJ Да
 root ╔═════╚═╔═════ VERB  има
  obj ║       ╚>╔═══ NOUN  сира
   cc ║         ║ ╔> CCONJ и
 conj ║         ╚>╚═ NOUN  масла
   cc ║   ╔════════> CCONJ и
  det ║   ║       ╔> DET   моја
  aux ║   ║ ╔════>║  AUX   би
nsubj ║   ║ ║ ╔══>╚═ NOUN  мати
 conj ╚>╔═╚═╚═╚═╔═══ VERB  знала
xcomp   ║       ╚>╔═ VERB  гибати
  obj   ║         ╚> NOUN  гибаницу
punct   ╚══════════> PUNCT .

「има」=conj⇒「знала」は、逆方向の「има」⇐advcl=「знала」の方がいいのではないか、と思うものの「Да има сира и масла и моја би мати знала гибати гибаницу.」をだいたい読めているようだ。続いて、同じ文をラテン文字で試してみよう。

>>> doc=nlp("Da ima sira i masla i moja bi mati znala gibati gibanicu.")
>>> deplacy.render(doc,WordRight=True)
 mark       ╔══════> SCONJ Da
advcl   ╔>╔═╚═╔═════ VERB  ima
  obj   ║ ║   ╚>╔═══ NOUN  sira
   cc   ║ ║     ║ ╔> CCONJ i
 conj   ║ ║     ╚>╚═ NOUN  masla
punct   ║ ╚════════> CCONJ i
  det   ║         ╔> DET   moja
  aux   ║   ╔════>║  AUX   bi
nsubj   ║   ║ ╔══>╚═ NOUN  mati
 root ╔═╚═══╚═╚═╔═══ VERB  znala
xcomp ║         ╚>╔═ VERB  gibati
  obj ║           ╚> NOUN  gibanicu
punct ╚════════════> PUNCT .

「i」にpunctが刺さってしまっている部分は、どうも解析ミスだが、そこを除いて「Da ima sira i masla i moja bi mati znala gibati gibanicu.」も読めているようだ。実を言えば、内部トークンの入力ベクトルは、キリル文字であってもラテン文字であっても、出来る限り同じになるよう学習していたりする。コサイン類似度で比較してみよう。

>>> import torch
>>> cos=torch.nn.CosineSimilarity()
>>> e=nlp.tagger.get_input_embeddings()
>>> t1=nlp.tokenizer.encode("Да има сира и масла и моја би мати знала гибати гибаницу.")
>>> t2=nlp.tokenizer.encode("Da ima sira i masla i moja bi mati znala gibati gibanicu.")
>>> v1=e.weight[t1]
>>> v2=e.weight[t2]
>>> print(cos(v1,v2))
tensor([1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 0.8652, 1.0000, 1.0000, 0.8652, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 0.9378, 1.0000, 1.0000, 1.0000], grad_fn=<DivBackward0>)

コサイン類似度が1.0000となっているトークンがほとんどだが、多少、類似度が低いトークンもある。もう少し細かく見てみよう。

>>> for i,j,k in zip(cos(v1,v2).tolist(),nlp.tokenizer.convert_ids_to_tokens(t1),nlp.tokenizer.convert_ids_to_tokens(t2)):
...   print(i,j,k)
...
1.0 [CLS] [CLS]
0.9999539852142334 да da
0.9999720454216003 има ima
0.9999790787696838 си si
0.9999566078186035 ##ра ##ra
0.8652070164680481 и i
0.9999816417694092 ма ma
0.9999814033508301 ##сла ##sla
0.8652070164680481 и i
0.9999930262565613 моја moja
0.9999709725379944 би bi
0.9999893307685852 мати mati
0.9999563694000244 зна zna
0.9999685883522034 ##ла ##la
0.9999815225601196 ги gi
0.9999806880950928 ##ба ##ba
0.999969482421875 ##ти ##ti
0.9999815225601196 ги gi
0.9999728798866272 ##бан ##ban
0.9378101825714111 ##и ##i
0.999963641166687 ##цу ##cu
1.0 . .
1.0 [SEP] [SEP]

つまり「и」と「i」のコサイン類似度が0.8652、「##и」と「##i」のコサイン類似度が0.9378で、残りはほぼ1である。あと一歩というところだが、さて、どういう風に改良したらいいかなぁ。

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

「科学者は100%安全だと保証できないものは動かしてはならない」、科学者「えっ」、プログラマ「えっ」

読み込み中...