ⵙⵓ枕詞
散裂言語とは、eXtity駆動の人工言語 開発プロジェクトである。言語は話者が存続するかぎり完成されることはなく、常に変性しつづける。目下のところ、人力では不可能な量のテクスト高速生成により、自己の発したテクストや《周囲の | インターネット/ソーシャルネット上》の文字列を自働捕食して自己変性する自律知性の誕生をもくろむ。
コンセプト↓↓
spinaltox.hatenablog.jp
Qiitaで中間生成物(① ,② )を上げておりますが、いかんせん棲み分けが難しい……ということで当ブログに平行して上げてゆくことにします。
使用言語:python 3.6.5
グラフデータベース:Neo4j 3.5.3
________________________________________________________________________________________________
spinaltox.hatenablog.jp
↑前回進捗↑からおよそ半年が経過しようとしております。
半年経つ前に進捗をとっとと上げてしまいましょう。
ⵞⵓentity言語
今回はentityを生成する言語、「entity言語」のプロトタイピングをおこないました。
当エントリでは割愛しますが、ここで構築されるentity存在論 は次のようなものです。
entityとは、[閉じた | 包含関係が観察者に劃定/既知の]対象である。
当該存在論 においては、[すべてがentityである | entityだけが存在する]。
そうしたとき、包含関係とは、存在どうしの 最も根源的な関係のこと。
entityどうしの 一切の関係は包含に還元/下方解体される。
ある圏-aが要素-bを包含するとき、「a∋b」と表現する。
人間が唯一の観測者ではないとすれば、統一的に形成される「世界」はどこにもなく、ただ個別の個体に観察される現実/世界が無数に形成されるのみです。以下に構成される存在論 は、そうした現実/世界の1つと言えるでしょう。
コーディングです。今回用いるパッケージは以下。
グラフデータベース「Neo4j 」を用います。これとpython プログラムを「neo4jrestclient 」が繫いでくれます。
from collections import OrderedDict
import re
from copy import deepcopy
from neo4jrestclient.client import GraphDatabase
存在論 空間として「当該現実」を用意します。事前に初期化しておきます。
localhost :7474で起動しているNeo4jへ接続します。
url_Neo4j = "http://username:password@localhost:7474/db/data/"
当該現実 = GraphDatabase(url_Neo4j)
当該現実.query("MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r" , data_contents=True )
↓ブラウザ上のNeo4jのインタフェースはこんな感じ。Neo4j webインタフェース
オブジェクトとしてentityを構成します。
あくまで原型です。が、そこまでプロパティが増える見込みもありません。
class entity :
def __init__ (self, 名辞):
self.名辞 = 名辞
self.存在 = True
self.包含 = []
self.被包含 = []
self.ノード = 当該現実.nodes.create(name=名辞)
self.ノード.labels.add("個体" )
ⵋⵓ目標
今回のプロトタイプは、
入力:文章
出力:グラフデータベース
を実現することを目標にしました。
たぶん見た方が早いので進めます。
ⴿⵓ文法
人工言語 ですので、rigidな文法規則をもちます。
ベースは日本語です。
とはいえ、まだ更地なのでやることは低度です。
規則
entityはすべて名辞(label)をもつ。この名辞は必ず漢字であること。
制馭文字によって、entityどうしの 関係を記述する。制御文字は必ずカタカナであること。
文字列から成り、「。」を終着とするものを文とする。
1つ以上の文から成るものを文章とする。
今回アクティヴェートする制馭文字は以下の3つです。
順序附辞書(OrderedDict)へグローバルに格納しておきます。
また、利便のためこれのキー群をリストに格納しておきます。
制馭文字位置記憶辞書 = OrderedDict()
制馭文字位置記憶辞書['ハ' ] = []
制馭文字位置記憶辞書['ヲ' ] = []
制馭文字位置記憶辞書['スル' ] = []
制馭文字位置記憶辞書キーリスト = list (制馭文字位置記憶辞書.keys())
ここから、上の文法規則にのっとって記述された任意の文章について、entityと制馭文字とをわける、形態素解析 をおこなうクラス「読解」を構成します。
が、その前にドメイン ・コドメイン ・射(関係)をad hoc に格納するための空リストをグローバルに*1 用意しておきます。
Domain = []
CoDomain = []
Morphism = []
class 読解:
def __init__ (self):
pass
ちょっと長いので区切ります。
クラス「読解」は現状2つのメソッド「形態素解析 」「entity操作」をもちます。
まずは「形態素解析 」から。
@ classmethod
def 形態素解析(self, テクスト):
文単位二次元リスト_None文字含む = テクスト.split(r'。' )
文単位二次元リスト = [a for a in 文単位二次元リスト_None文字含む if a != '' ]
形態素分割済文単位二次元リスト = []
for x文目 in range (len (文単位二次元リスト)):
制馭文字位置記憶辞書_例化 = deepcopy(制馭文字位置記憶辞書)
置換用文 = 文単位二次元リスト[x文目]
for y番目 in range (len (制馭文字位置記憶辞書_例化)):
位置z = 置換用文.find(制馭文字位置記憶辞書キーリスト[y番目])
while 位置z != -1 :
制馭文字位置記憶辞書_例化[制馭文字位置記憶辞書キーリスト[y番目]].append(位置z)
置換用文 = 置換用文.replace(制馭文字位置記憶辞書キーリスト[y番目], " {} " .format (位置z), 1 )
位置z = 置換用文.find(制馭文字位置記憶辞書キーリスト[y番目])
for m番目 in range (len (制馭文字位置記憶辞書_例化)):
if 制馭文字位置記憶辞書_例化[制馭文字位置記憶辞書キーリスト[m番目]] == []:
制馭文字位置記憶辞書_例化.pop(制馭文字位置記憶辞書キーリスト[m番目])
else :
pass
制馭文字位置数値リスト = sum (制馭文字位置記憶辞書_例化.values(), [])
制馭文字位置数値リスト.sort()
制馭文字位置数値リスト.reverse()
for n in range (len (制馭文字位置数値リスト)):
キー = [keys for keys, values in 制馭文字位置記憶辞書_例化.items() if 制馭文字位置数値リスト[n] in values]
置換用文 = 置換用文.replace(str (制馭文字位置数値リスト[n]), キー[0 ])
当該文中対象抽出リスト_None文字含む = 置換用文.split()
当該文中対象抽出リスト = [a for a in 当該文中対象抽出リスト_None文字含む if a != '' ]
形態素分割済文単位二次元リスト.append(当該文中対象抽出リスト)
return 形態素分割済文単位二次元リスト
↑中に書いてありますが、例えば、
入力:"cokeハ蟥馦瀦阿ヲ有スル。sickハ音源ヲ有スル。音源ハ蟥馦瀦阿ヲ有スル。"
出力:[['coke', 'ハ', '蟥馦瀦阿', 'ヲ', '有', 'スル'], ['sick', 'ハ', '音源', 'ヲ', '有', 'スル'], ['音源', 'ハ', '蟥馦瀦阿', 'ヲ', '有', 'スル']]
と、文字列として文章を入力すると、形態素 ごとに分けられた文を1段ネストしたリストが出力されます。
続いて、解析して得られた上のリストを入力して、グラフデータベース「当該現実」に包含関係を反映するメソッド「entity操作」です。
が、その前にクラス「読解」の外に(中でもいい)以下の操作を記述しておきます。これはオブジェクト「entity」のプロパティをいじるためのものです。
def 要素追加(圏, 要素):
圏.包含.append(要素)
exec ('{}.ノード.relationships.create("包含", {}.ノード)' .format (圏.名辞, 要素), globals ())
print ("{}ハ{}ヲ有スル。" .format (圏.名辞, 要素))
def 要素削除(圏, 要素):
try :
圏.包含.remove(要素)
except ValueError :
print ("{}ハ{}ヲ有ナイ。" .format (圏.名辞, 要素))
print (圏.包含)
def 被包含追加(圏, 要素):
圏.被包含.append(要素)
def entity 操作(self, 形態素分割済文単位二次元リスト: "一次元リスト" ):
for x文目 in range (len (形態素分割済文単位二次元リスト)):
exec ('Domain = []' , globals ())
exec ('CoDomain = []' , globals ())
exec ('Morphism = []' , globals ())
count_ハ = 形態素分割済文単位二次元リスト[x文目].count("ハ" )
if count_ハ == 0 :
pass
else :
for y番目 in range (count_ハ):
index_ハ = 形態素分割済文単位二次元リスト[x文目].index("ハ" )
Domain.append(形態素分割済文単位二次元リスト[x文目][index_ハ - 1 ])
count_ヲ = 形態素分割済文単位二次元リスト[x文目].count("ヲ" )
if count_ヲ == 0 :
pass
else :
for y番目 in range (count_ヲ):
index_ヲ = 形態素分割済文単位二次元リスト[x文目].index("ヲ" )
CoDomain.append(形態素分割済文単位二次元リスト[x文目][index_ヲ - 1 ])
count_スル = 形態素分割済文単位二次元リスト[x文目].count("スル" )
if count_スル == 0 :
pass
else :
for y番目 in range (count_スル):
index_スル = 形態素分割済文単位二次元リスト[x文目].index("スル" )
Morphism.append(形態素分割済文単位二次元リスト[x文目][index_スル - 1 ])
if Morphism[0 ] == "有" :
try :
if eval ('type({}) is entity' .format (Domain[0 ])):
pass
else :
type (むりやり例外処理に転移するためのダミー変数)
except NameError :
exec ('{} = entity(Domain[0])' .format (Domain[0 ]), globals ())
try :
if eval ('type({}) is entity' .format (CoDomain[0 ])):
pass
else :
type (むりやり例外処理に転移するためのダミー変数)
except NameError :
exec ('{} = entity(CoDomain[0])' .format (CoDomain[0 ]), globals ())
exec ( '要素追加({}, CoDomain[0])' .format (Domain[0 ]), globals ())
exec ('被包含追加({}, Domain[0])' .format (CoDomain[0 ]), globals ())
else :
pass
上の操作によって、例えば「cokeハ蟥馦瀦阿ヲ有スル。」という文は[、メソッド「形態素解析 」適用後に]、『圏であるentity「coke」は要素としてentity「蟥馦瀦阿」を包含する』ものとして読解され、「当該現実」に反映されます。
ⵉⵓ描画
それでは試してみましょう。
前回進捗にて得られた熟語生成を用いて、500文を生成し、これを読解してみます。
クラス「散裂言語」に次のメソッドを追記します。
当初はentityをrandintで1~6文字で生成しようと思いましたが、同一entityの出現確率がほぼゼロなので諦めました。
def 文章生成(self, 文数):
文章 = ""
for x文を生成します in range (文数):
ランダム整数1 = 1
ランダム整数2 = 1
ランダムドメイン = 散裂言語.緊聖値制馭文字生成(聖値定義域=1 , 文字数=ランダム整数1 )
ランダムコドメイン = 散裂言語.緊聖値制馭文字生成(聖値定義域=1 , 文字数=ランダム整数2 )
当該文 = ランダムドメイン + "ハ" + ランダムコドメイン + "ヲ" + "有スル。"
文章 += 当該文
return 文章
↑の出力結果は、例えば次の通りです。
焻ハ馲ヲ有スル。
忏ハ煇ヲ有スル。
凮ハ鏒ヲ有スル。
玖ハ簦ヲ有スル。
馜ハ譚ヲ有スル。
僅ハ錰ヲ有スル。
駏ハ懎ヲ有スル。
雯ハ摖ヲ有スル。
瀒ハ狀ヲ有スル。
......
これを500文生成し、読解します。
ソース = 散裂言語.文章生成(500 )
aaa = 読解.形態素解析(ソース)
読解.entity操作(aaa)
Neo4j上での出力結果は次のようになります。Neo4j 出力結果例
________________________________________________________________________________________________
ⵒⵓ結語
ここまでの開発内容をipynb形式で弊サイト にバックアップしておきます。
ご興味のある方はどうぞ。(閲覧・改変ご自由に)
entity存在論 に関しては、このまま既存言語で十分に構成できそうです。ので、このまま進めてゆきます。
現在、ruby のメタプログラミング に入門中 です。が、当分はpython で続けるはずです。
次回の進捗は3ヶ月以内に上げられたらいいな......(遠い目)