アイヌ民族財団アイヌ語教材テキストの単語リスト(千歳・美幌・幌別・静内・十勝・沙流・石狩川・カラフト)をもとに、アイヌ語の「方言間距離」を単語リストのbinary word vectorのハミング距離だとみなして、networkxのspectral_layoutで3D可視化してみた。Google Colaboratoryだと、こんな感じ。
!pip install pdfminer networkx plotly
import os,re,numpy,networkx
from plotly.express import scatter_3d
d=[("千歳","chitose.txt","chitose_tyukyu.pdf"),
("美幌","bihoro.txt","bihoro_tyukyu.pdf"),
("幌別","horobetsu.txt","horobetsu_tyukyu.pdf"),
("静内","shizunai.txt","shizunai_tango.pdf"),
("十勝","tokachi.txt","tokachi_tango.pdf"),
("沙流","saru.txt","saru_tango.pdf"),
("石狩川","ishikari.txt","ishikari_tango.pdf"),
("カラフト","karahuto.txt","karahuto_tango.pdf")]
v=[]
for h,t,p in d:
os.system(f"test -f {p} || curl --ciphers DEFAULT@SECLEVEL=1 -LO https://www.ff-ainu.or.jp/teach/files/{p}")
k="sed -e 1,/単語リスト$/d -e /発行年月/q" if p.endswith("tyukyu.pdf") else "fgrep -v indd"
os.system(f"test -s {t} || ( pdf2txt.py {p} | {k} > {t} )")
with open(t,"r",encoding="utf-8") as r:
v.append(re.findall(r"[a-z=]+",r.read()))
w={j:i for i,j in enumerate(set(sum(v,[])))}
m=numpy.zeros((len(d),len(w)))
for i,k in enumerate(v):
for j in k:
m[i,w[j]]=1.0
e=numpy.array([numpy.sum(numpy.abs(m-m[i]),axis=1) for i in range(len(d))])
g=networkx.Graph()
for i in range(len(d)):
g.add_node(i)
for j in range(i):
g.add_edge(i,j,weight=1/max(e[i,j],0.5))
c=networkx.spectral_layout(g,dim=3)
p=numpy.array([c[i] for i in range(len(d))])
f=scatter_3d(x=p[:,0],y=p[:,1],z=p[:,2],text=[h for h,_,_ in d],opacity=0.5,labels={"x":"","y":"","z":""},width=1600,height=1600)
q={"tickfont":{"color":"white"}}
f.update_scenes(xaxis=q,yaxis=q,zaxis=q)
f.show()
私(安岡孝一)の手元では、以下の3D図が出力された。
一昨々日の記事では単語ベクトル間のユークリッド距離を主成分分析して3D可視化したが、この記事ではハミング距離をグラフラプラシアンで3D可視化しているわけだ。まあ、3D図とは言っても2次元画像だったりするし、実際にマウス操作してもらった方がいいのだが、私の見たところ、ユークリッド距離よりハミング距離の方がスジが良さそうだ。さて、この手法を、服部四郎・知里真志保『アイヌ語諸方言の基礎語彙統計学的研究』(民族學硏究, Vol.24, No.4 (1960年11月), pp.307-342)の19方言に適用するには、どこをどうしたらいいのかな。