スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

大脳皮質っぽい構造を持つ自然言語パーザ

前回に引き続き、範疇文法(Categorial Grammar)のパーザを、
脳による実装を意識しならがら prolog で書いてみました。

範疇文法に基づく言語理論によれば、自然言語の意味はラムダ計算で表現されます。
一方で、最近の計算論的神経科学の知見によれば大脳皮質はベイジアンネットです。
しかし、ベイジアンネットで、どうやってラムダ計算が実行可能なのでしょうか?
今回作ったのは toy program ですが、
その問題の解決に向けて、かなり進んだかもしれません。

今回は、 applet として動く prolog インタープリタ上で実際に動かしました。
「W-Prolog」
http://waitaki.otago.ac.nz/~michael/wp/
「Prolog Guide - Test Zone」
http://ktiml.mff.cuni.cz/~bartak/prolog/testing.html

shift と reduce の書き方は、下記のページの "toy CCG parser" cg.pl を参考にしました。
http://www.ceng.metu.edu.tr/~bozsahin/nli/ceng563/link/index.html


解決のアイデアを説明するのは大変なので、今回は取り急ぎ、
プログラムと実行結果だけ貼っておきます。

一言で言うと、
「文の意味とは、言語野以外の領野の発火パターンである」と解釈し、
ラムダ式の関数本体を領野のIDで抽象化し、
ラムダ計算を有限のサイズの規則のデータベースで表現したところが
今回の一番のポイントです。

係り受けの対応関係が保存されるようにするのも苦労した点です。


未解決の課題もいくつかあります。
- 今回実装したのは範疇文法(CG)。組み合わせ範疇文法(CCG)に拡張可能か?
- 述語 parse で再帰呼び出しとローカル変数を使っているが、なくせるか?
- 統語範疇やラムダ式の表現を脳は本当に教師なし学習可能か?
- 文法規則のテーブルのサイズは爆発しないのか?うまく圧縮可能か?

しかし、他に優先度の高い仕事があるので、今回はここまでとします。

プログラム:

% Categorial Grammar Parser
% 2011-02-07 Yuuji Ichisugi

% 統語範疇・意味データベース。ウェルニッケ野?
% m(Word, C, M, Store)
% 単語と統語範疇・意味(ラムダ式)との対応表。
% C は統語範疇。 S/NP は sFnp, S\NP は sBnp と書くことにする。
% ラムダ式の body の「値」は Store の中に書き込み、
% M には値の場所の情報だけを入れる。
% o1o2a というのは、λo1.λo2.a というラムダ式を意味する。
m(wCat, np, o1, Store) :- access(Store, object1, cat).
m(wCat, np, o2, Store) :- access(Store, object2, cat).
m(wFish, np, o1, Store) :- access(Store, object1, fish).
m(wFish, np, o2, Store) :- access(Store, object2, fish).
m(wWhite, npFnp, o1o1, Store) :- access(Store, color1, white).
m(wWhite, npFnp, o2o2, Store) :- access(Store, color2, white).
m(wBlack, npFnp, o1o1, Store) :- access(Store, color1, black).
m(wBlack, npFnp, o2o2, Store) :- access(Store, color2, black).
m(wEat, sBnpFnp, o2o1a, Store) :- access(Store, action, eat12).
m(wEat, sBnpFnp, o1o2a, Store) :- access(Store, action, eat21).

% 意味を表現するメモリ。言語野以外の連合野。
% access(Store, Addr, Data).
% メモリ Store のアドレス Addr に値 Data を書き込む。
access([[Addr, Data] | Rest], Addr, Data).
access([Head | Rest], Addr, Data) :- access(Rest, Addr, Data).

% 構文・意味規則のデータベース。ブローカー野?
% apply(aFb, F1, b, F2, a, F3) は、 F1 に F2 を適用した結果が F3 、
% apply(b, F1, aBb, F2, a, F3) は、 F2 に F1 を適用した結果が F3 、
% ということを意味する。
apply(sBnpFnp, o1o2a, np, o1, sBnp, o2a).
apply(sBnpFnp, o2o1a, np, o2, sBnp, o1a).
apply(np, o1, sBnp, o1a, s, a).
apply(np, o2, sBnp, o2a, s, a).
apply(npFnp, o1o1, np, o1, np, o1).
apply(npFnp, o2o2, np, o2, np, o2).

% パーザ。

%parse([X],[], Store) :- print(X), nl.
parse([[s, M]],[], Store).
parse([[C2, M2], [C1, M1] | Stack], Buffer, Store) :- % reduce
apply(C1, M1, C2, M2, C3, M3),
parse([[C3, M3] | Stack], Buffer, Store).
parse(Stack, [W | Rest], Store):- % shift
m(W, C, M, Store),
parse([[C, M] | Stack], Rest, Store).

%
initialState([[action, A], [color1, C1], [object1, O1], [color2, C2], [object2, O2]]).
start(Buffer, Store) :- initialState(Store), parse([], Buffer, Store).


Query の例:

start([wCat], Store). % Not accepted.
start([wCat, wEat, wFish], Store).
start([wWhite, wCat, wEat, wFish], Store).
% 逆向き推論。
% 深さ優先探索なので単語の数を制限しておかないと無限ループになるみたい。
parse([], [W1, W2, W3], [[action,eat12],[object1,cat],[object2,fish]]).
parse([], [W1, W2, W3, W4], [[action,eat12],[object1,cat],[color2,white],[object2,fish]]).


実行例:

Query: start([wCat], Store).
No.
% 文じゃないので accept されない。

Query: start([wCat, wEat, wFish], Store).
Yes: start([wCat,wEat,wFish],[[action,eat12],[color1,_146],[object1,cat],[color2,_148],[object2,fish]])
Yes: start([wCat,wEat,wFish],[[action,eat21],[color1,_146],[object1,fish],[color2,_148],[object2,cat]])
% 文の意味が正しく理解され、結果が変数 Store の値として表現されている。
% cat と fish を object1 と object2 のどちらに割り当てるかで、
% 2通りの解釈がある。

Query: start([wWhite, wCat, wEat, wFish], Store).
Yes: start([wWhite,wCat,wEat,wFish],[[action,eat12],[color1,white],[object1,cat],[color2,_1044],[object2,fish]])
Yes: start([wWhite,wCat,wEat,wFish],[[action,eat21],[color1,_1042],[object1,fish],[color2,white],[object2,cat]])
% これも2通りの解釈がある。
% いずれの場合も、形容詞の係り受けは正しく理解されている。

Query: parse([], [W1, W2, W3], [[action,eat12],[object1,cat],[object2,fish]]).
Yes: parse([],[wCat,wEat,wFish],[[action,eat12],[object1,cat],[object2,fish]])
% 逆向き推論。意味を表現する単語の列が正しく推論されている。

Query: parse([], [W1, W2, W3, W4], [[action,eat12],[object1,cat],[color2,white],[object2,fish]]).
Yes: parse([],[wCat,wEat,wWhite,wFish],[[action,eat12],[object1,cat],[color2,white],[object2,fish]])
% これも逆向き推論。係り受けを正しく表現する単語の列が推論されている。

Query: start([W1, W2, W3, W4], Store).
Yes: start([wCat,wEat,wWhite,wCat],[[action,eat12],[color1,_54207],[object1,cat],[color2,white],[object2,cat]])
Yes: start([wCat,wEat,wWhite,wFish],[[action,eat12],[color1,_54207],[object1,cat],[color2,white],[object2,fish]])
Yes: start([wCat,wEat,wBlack,wCat],[[action,eat12],[color1,_54207],[object1,cat],[color2,black],[object2,cat]])
Yes: start([wCat,wEat,wBlack,wFish],[[action,eat12],[color1,_54207],[object1,cat],[color2,black],[object2,fish]])
...
% 単語4つからなる可能な文をすべて生成。たくさん生成される。


コメント

コメントの投稿

トラックバック


この記事にトラックバックする(FC2ブログユーザー)

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。