我的雲端生活網 - Life+

Showing posts with label rule-based. Show all posts
Showing posts with label rule-based. Show all posts

Monday, April 6, 2009

規則式系統的系統描述

本篇來講一些規則系統(production system, rule-based sytem, or expert sytem)的系統描述(formulation)。規則系統是由工作空間(包含事實)、知識庫(包含規則)、以及推論引擎(包含推論及控制流程)等三樣東西構成。一般大學教科書中,很少明確說明規則系統的設計。而相關論文則都使用 Lisp 語言介紹系統架構,較近年代的程式人員根本看不懂。

1. 程序代數

所以,用一些形式語言說明規則系統的架構。推論引擎包含三個分開的程序,所以我們用到基本程序代數(Pi Calculus):令 p, q 是二個程序,二個程序的結構可能是下列其中一種樣子。

p, q ::=   a(c) . p                           (輸入)
           |   a! c . p                            (輸出)
           |     P  |  q                            (平行處理)
           |   if x = y then p else q   (條件控制)
           |   rec z . p                          (遞迴)
           |   stop                                (終止)

上述項目的意義是:
  1. a(c) . p 是程序 p 要從 a 通訊管道取得一些資料 c ;
  2. a! c . p 是程序 p 要對 a 通訊管道送出一些資料 p ;
  3. p | q 是二個程序 p, q 平行地執行;
  4. if x = y then p else q 是先比較二項資料 x 和 y ,如果 x = y 就執行程序 p ,否則執行程序 q ;
  5. rec z . p 是將程序 p 定義為一個遞迴程序,以 z 標示。在 p 中存在 z 符號,表示遞迴呼叫;
  6. stop 是一個終止程序。
我們說, P <= a(b) . p 是定義一個程序 P 的內容是, p 知道一 通訊管道 a 並 管道 a 取出資料
b 。為了方便,用 P(a) 表示此式,即程序 P 一開始就知道通訊管道 a ,並可以隨意使用。

2. 基本詞彙

另外,我們需要一些基本符號,列舉如下:

單元詞彙:要表示一個資料單位或一項物件,用小寫字母 a, b, ..., z 表示任何一個單元。

集合詞彙:用大寫字母 A, B, ..., Z 表示任何一個集合。每一個集合中包含了許多單元。所以,x < X 表示一個單元詞彙 x 屬於另一個集合 X 。

邏輯式敘述:用一些單元詞彙和一些邏輯運算符號 & , | , ~ ,  ->  等等,組合成另一些字串,這些字串稱為邏輯式、或稱為敘述:例如,有單元詞彙 x, y ,則 x & y 是一則敘述、 ~x 是一則敘述、並 (x & y -> x) | (x & y -> y) 也是一則敘述。在本篇文章,我們要用到許多  ->  運算符號。

隱含( -> ):是一種邏輯運算符號,用來表示符號的左項和右項之間有因果關係:例如,對單元詞彙 x, y 來說, x -> y 是一則敘述,其意義是

                  x           y                  x -> y
               true      true                true
               true      false               false
               false     true                true
               fase      false                true

只有當 x 有效但 y 無效時, x -> y 不能成立。這稱為「 x 隱含 y 」、「 x 代表 y 」。

例外詞彙:任何其他用途的詞彙,都用粗體大寫字母 A, B, ..., Z 表示:例如,用 M 表示一則程序。

Lambda函數:是一種匿名函數的表示法,以格式為「 入 a b c ...  .  p(a, b, c, ...) 」的字串表示一則函數。其中,「入」是希臘文字母,唸 lambda ;「入」之後是一些參數、之後是一點、之後是函數內容:例如, 入x y . x + y 是一則匿名函數,接受二項參數而計算總和。

3. 定義

事實:用一個單元詞彙表達一項事實:例如,用 x 表達「今天下雨」。

規則:用一則格式為「 a & b & ... -> a & b & ... 」的邏輯式,表示一條規則:例如 a & b -> c & d 。其中, ->  符號左邊稱為左手側,常用英文 LHS 表示;右邊稱為右手側,常用英文 RHS 表示。左手側就是規則條件,而右手側就是規則的結論。

規則系統:是一組結構 <F, R, M, C, A ,其中組成單元有:
  1. F :一些事實的集合。
  2. R :一些規則的集合。
  3. M :規則比對程序,負責將一些事實和一些規則彼此比對,然後選出符合比對的規則,當做結果。
  4. C :協調程序,負責將 M 的結果做衝突協議(Conflict Resolution)。衝突協議是在一些規則中,只挑選一些必須啟動的規則,當做結果;並排除彼此衝突或互相重覆的規則:例如,規則 A & B -> C 和規則 A -> C 重覆,因為前者的規則條件是後者的子集合。 Rete 演算法規定,對這二條規則,要選擇 A & B -> C ,因為規則條件比較嚴格。
  5. A :行動程序,負責將 C 的結果── 一些確定要啟動的規則 ──確實執行。 A 要將 C 結果的右手側取出並執行。
Rete 結構Rete 演算法是討論一些規則的集合應該如何組織、並組織一種有效的結構,使事實和規則彼此比對變的比較有效。令有一些規則為 R = { A & B -> C ,  B & C -> D } ,根據最初的 Rete 演算法論文, R 有一組對應的 rete 結構,令為 R(R) 。 R(R) 包含一些流程控制,定義為

        入 f  .   R(R)   ::=
                    入 f  .  if type(f) = A then assert(C(_^B)) ;
                               if type(f) = B then assert(C(A^_)); assert(D(_^C)) ;
                               if type(f) = C then assert(D(B^_)) ;
                               if assert(C(_^B)) and assert(C(A^_)) then match(A & B -> C) ;
                               if assert(D(_^C)) and assert(C(B^_)) then match(B & C -> D)

R(R) 中由三種節點構成,包括 type(f) = A 檢查輸入事實的 type 屬性、 assert(C(A^B)) 表示結果 C 是由 A & B 決定、以及 match(r) 指明條件 r 已經符合比對。而 C(_^B) 表示 C 的一則決定項已經接受、並等待另一則決定項 B 。

4. 推論引擎

推論引擎包含 M, C, A 三項程序,依序循環使用。我們用程序代數和上述符號標記法定義三項程序。

取比對程序 M

    M(a, b) <= rec z  .  a(f1, (f2, f*)) . ((入 f . R(R))  f1  |  a! f2, f*  .  z )

其中 (f1, (f2, f*)) = F = (f1, f2, ..., fn) ,並且 (入 f . R(R))  f1 是一則匿名函數代入參數而生效,計算方式是 R(R)[f1/f] 、即把函數主體 R(R) 中存在的 f 替換為 f1 。在 R(R) 中的 match 定義為

    match(b) <= b! r  .  stop

又取協調程序 C

    C(b, c) <= rec z . b(r1, (r2, r*))  .  ( if r1 = empty then stop
                                                                 else
                                                                     if forall r < R . r1 >= r then fire(r1)
                                                               | b! r2, r*  .  z )

其中, r1 > r 是一條規則對另一條規則的大於關係,定義為 LHS(r1) < LHS(r) 則 r1 > r ,並且 fire(LHS -> RHS) <= c! RHS  .  stop 。

又取行動程序 A

    A(c, d) <= rec z . c(rhs1, (rhs2, rhs*))  .  d! rhs1 . c! rhs2, rhs* .  z

於是,推論引擎取為

INF(a) <= rec z . a(F, R) . (M(a, b) | C(b, c) | A(c, d) | d(F') . a! (F+F'), R . z)

嗯?有點錯誤,管它的,只是個思考過程。

Tuesday, January 20, 2009

規則系統的發展

為了對規則系統陌生的人,必須有這項簡介。

規則系統, rule-based system ,以前稱為 production system ,是因為系統的構成有許多的 production rules 。後來稱為專家系統,特別叫做規則式專家系統。有名的案例是 MYCIN ,處理心理諮商及診斷。規則系統是運用規則表達知識並解決問題的系統。

左圖為專家系統的內外構成。外部結構基本有規則庫、推論引擎及工作空間,依序比照為人腦的長程記憶區、推論邏輯、以及短程記憶區。推論引擎內的運作方法大致是接受若干輸入事實,就將事實與規則庫中每項規則比對,其中,有些規則會符合事實、而有些不會符合。這些符合的規則構成 conflict set ,爭議集合。如果都沒有符合的規則, conflict set 是空的,沒有任何規則可以選擇,表示推論過程可以結束了。但如果至少有一條規則符合比對,就要從 conflict set 中選取若干應該觸發、啟動的規則,這個動作稱為 conflict resolution ,衝突決議。 Conflict resolution 選擇了一些規則,執行規則中所規定的動作,這個步驟稱為 act 。啟動一些規則,使推論的過程與狀態有一些改變,這些狀態儲存在 working memory 中。然後,回到 Pattern Match 步驟再進行下一次循環。以上,推論循環工作的過程,以三大步驟稱呼稱為 match-resolution-act ,比對、決議、行動。每一循環的 act 步驟可能送出一些解答。推論循環工作的終點,是在 match 之後、 resolution 之前,發現 conflict set 沒有任何規則存在,就結束推論流程。

規則系統的研究領域,站在中流砥柱的一位是 Charles L. Forgy ,他在 1979 年卡耐基美隆大學的電腦科學系博士學位論文中,提出有效處理 Pattern Match 與 conflict resolution 的幾項方法。他的指導老師是 Allen Newell ,在 1956 年與同事發表第一支人工智慧程式,稱為「邏輯解題者」。他們師徒的另外一位同事, Anoop Gupta ,他在 1989 年取得博士學位,則處理了在 message-passing computer 用平行架構實作規則系統。

Forgy 在 1974 到 1979 年的研究,發表了第一代 Rete 演算法,做有效處理 Pattern Match 。 Rete 演算法在這個領域從當時紅到現在。 1983 年,他開創稱為 Production System Technology 的公司,屬於研究及顧問性質的機構,同時也賣了許多 OPS 的產品 ( OPS2 、 OPS5 等等)。這時候 Forgy 也發表了第二代 Rete 演算法,聲稱它不只能夠表達知識,還能夠做資料處理。又後來,他在 RulesPower 公司的時代發表了第三代 Rete 演算法,這個技術在 2005 年被 Fair Issac 公司取得了。據 Rete III 的聲明,有 300% 的效能。 2006 年 11 月,據 JavaRule 部落格訊息指出, Forgy 在參加 Business Rule 論壇的時候發生心臟疾病,希望他身體健康。

目前我們知道的規則系統研究走向, Rete 演算法是公開的資訊, Rete II 與 III 是企業不公開的技術,而且 production system 及專家系統在 70 、 80 年代發展、 90 年代成熟之後,已經走向商業規則領域。所以,今後可以多參考 business rules 方面的資訊,幫助我們的系統開發。

規則系統的運作方式

規則系統是使用許多規則作為專家知識,處理輸入問題而產生解答。規則系統的架構本來有講究,但國內學習環境很容易將規則誤解為一般程式語言中的 if-then-else 程式流程。所以,在此來看看一套規則系統如何處理「猴子與香蕉」問題。

「猴子與香蕉」是人工智慧與生物知能領域喜歡討論的例子,在一組空間中,有香蕉、猴子及其他物品散置各處,問猴子如何取得香蕉。假設我們有一套規則系統,系統中建立規則如下: (=W =C =P =O 為變數, = 為萬用變數, #P 為 =P 的否定變數,帶負號項目為否定條件。)

(以上資料摘自 Charles L. Forgy 於 1979 年發表的博士論文,第 11 到 13 頁。)
勘誤: MB8 規則的右手側誤植為 Near ,完整正確規則應為 ((Want =O Near =P)) (Light =O)(=O Near #P) --> (Want (Monkey Holds =O)))

指定問題如左:目標為想要猴子取得香蕉,而各項物件的位置及情況列在下方。
(左列資料摘自 Charles L. Forgy 於 1979 年發表的博士論文,第 13 頁。)

參考以上規則,規則系統的處理過程如下圖所示: (WMEs 為 Working Memory Elements ,工作空間項目。規則啟動 (fire) 的原則為,若曾經啟動過此規則則不啟動,否則,由多項符合比對的同一類規則中,啟動規則條件(左手側)較嚴格的規則。任何一項 WME 右側標有 X n(X 右接一個數),表示此項是在進入 WMEs n 之前的一條規則啟動時被刪除。)

(以上資料為本文所整理。)

規則系統應該做下列工作:

  1. 做好幾次的循環,每次都要做規則比對、判斷哪條規則該啟動、並執行啟動的規則。
  2. 每一次循環,有多條規則同時符合比對,有多條規則可以被啟動,多條啟動規則改變了工作空間。
  3. 循環工作的終點,是當沒有一條規則符合比對的時候,才可以結束規則判斷工作。

規則系統的使用者,在此指知識專家或知識工程師,所做的事情有下列的情形:

  1. 使用者只要撰寫簡單的規則;簡單的規則不需要有巢狀的構成,即不必寫一條規則中包含另一條規則。
  2. 使用者必須撰寫完整、能夠解題的規則集合;解題的完成仰賴於規則知識,甚於仰賴程式演算法。
  3. 使用者可能沒把解題規則寫得完整;規則的部份不完整,會導致解題完成到一半。
  4. 使用者必須小心處理遞迴規則。
  5. 為了完成解題工作,使用者除了提供一般解題規則之外,有時還要增添輔助規則。例如上例的第十條規則 MB10 是輔助規則,避免有些已達成目標、卻沒有清除目標的情況。
  6. 知識規則可提供非知識專家手寫做解題,但是人力操作解題可能犯錯,例如將規則或符號看錯及謄寫錯誤;由規則系統操作知識規則,則不容易犯錯。

Tuesday, December 30, 2008

以 Prolog 示範規則推論系統

規則推論系統,須由規則推論引擎、知識庫、以及輸入事實三者構成。推理方法有向前鏈接 (forward chaining) 和向後鏈接 (backward chaining) 方式,分別對應二種不同的需要。向前鏈接是由規則的前提向規則的結論方向串連可用的規則,由原因導出結果。向後鏈接是由規則的結論向規則的前提方向串連可用的規則,由結果導出原因。於是,前者適用於預測和決策,而後者適用於診斷和歸納。
Prolog 是法文 programmation en logique ,即英文 programming in logic 的合併詞,是個以邏輯操作為主的程式語言。 Prolog 的推理方法是向後鏈接,而且,將 Prolog 系統比擬為推論引擎,是使用 Markov 演算法作為規則歸納策略。說「比擬為推論引擎」,指 Prolog 並不是完整的專家系統框架。不過, Prolog 提供了足夠的基礎架構,可能做出小型、甚至大型的規則推論系統。
本篇以一份小、且不完整的規則知識庫,解決學術界一項著名的小問題「猴子取香蕉」 (the monkey and bananas problem) ,作為對於規則推論系統的展示。
問題描述:
在空間中有猴子,和香蕉、梯子、躺椅等物品,散置於各處。猴子窩在躺椅上,香蕉懸在高處,而且躺椅、香蕉和梯子彼此相隔特定距離。猴子必須站在夠高的位置,並靠近夠近的距離,才能取得香蕉。於是,問題是:猴子該如何取得香蕉?
猴子取香蕉的問題在學術界有各面的討論,例如,研究心理與認知的人關心動物如何操作心理的機能以達成學習。我們對於規則推論系統的討論,則關心要解決這件問題,該建立哪些知識,以及該如何使用這些知識來推理。以下是我的程式。須注意這份程式只是示範,並是知識未建置完整。所示範的重點是:可建立足夠的知識以取得解答,以及掌握 Prolog 向後鏈接推理方法的原則撰寫規則。
% The monkey and bananas problem

% Naming principle:
% 1. Adjectives: for checking properties.
% 2. Verbs: for goals with two members, i.e., a subjective and a objective.
% 3. Past Participles: for goals with two members, i.e., two objectives.

% facts
:-
assert(near(monkey, position(3, 4))),
assert(near(bananas, position(5, 2))),
assert(near(ladder, position(1, 1))),
assert(near(couch, position(3, 4))),
assert(on(monkey, couch)),
assert(light(bananas)),
assert(light(ladder)),
assert(high(bananas)).

% backward chaining rules
holds(monkey, W) :-
not(high(W)),
light(W),
made_neared(monkey, W),
format('Monkey holds ~w.~n', W)
;
high(W),
light(W),
made_neared(ladder, W),
not(on(monkey, ladder)),
climbs(monkey, ladder),
holds(monkey, W)
;
high(W),
light(W),
made_neared(ladder, W),
on(monkey, ladder),
holds(monkey, W)
.
made_neared(O1, O2) :-
near(O1, P1),
near(O2, P2),
moves(O1, P2),
format('Now ~w is near ~w at ~w.~n', [O1, O2, P2])
;
near(O1, P),
near(O2, P),
format('~w and ~w are at the same position.~n', [O1, O2])
.
moves(S, P) :-
retractall(near(S, _)),
assert(near(S, P)),
format('Action performed: moving ~w to ~w.~n', [S, P])
.
climbs(S, O) :-
retractall(high(_)),
assert(on(S, O)),
format('~w climbs on ~w.~n', [S, O])
.
Prolog 的基本符號有:小寫開頭符號為詞彙 (term),大寫開頭符號為變數,帶有參數的詞彙為描述詞 (predicate)。 ":-" 是規則的中介符號,其左邊項是規則的結論,右邊項是規則的前提。句點是一則完整描述的結尾,逗點是 and 連接詞,分號是 or 連接詞。一則完整描述若只帶有左邊項(沒有右邊項和 ":-" 符號),是單元詞彙,代表既存在的事實。一則完整描述若只有右邊項和 ":-" 符號,代表一則查詢。以上程式撰寫了事實與規則。程式的啟動狀態為:
near(monkey, position(3, 4))
near(bananas, position(5, 2))
near(ladder, position(1, 1))
near(couch, position(3, 4))
on(monkey, couch)
light(bananas)
light(ladder)
high(bananas)
以上描述詞彙,使用 assert 描述詞和逗號組合成查詢句型,使程式被載入時能動態地建立這些詞彙。( Prolog 中,只有動態建立的描述詞才能被動態地刪除。)這些詞彙稱為事實,構成推論系統的工作空間及狀態。
規則的組成結構,以第一條規則為例,是:
holds(monkey, W) :-
not(high(W)),
light(W),
made_neared(monkey, W),
format('Monkey holds ~w.~n', W).
要找到一項目標 holds(monkey, W) ,「要猴子抓住某物品W」,附帶若干條件例如「物品W位置不高」、「物品W很輕」,則必須找到一項前置目標 made_neared(monkey, W) ,「要讓猴子與物品W是位置接近的」。最後一項 format('Monkey holds ~w.~n', W) 是將物品W放進字串 "Monkey holds ~w.~n" 的 ~w 位置,作為結果輸出。最後一項輸出存在的意義是,引用的這一項規則之後,狀態為「猴子抓住了香蕉」。其他規則比照於此,都包含了一項目標 (goal)、必要的前置目標 (subgoal)、相關的條件、以及引用規則之後的狀態。將程式存檔為 .pl 副檔名,用 Prolog 載入這份程式,並輸入查詢:
?- holds(monkey, bananas).
以上查詢是問「猴子抓住香蕉,怎麼做?」結果輸出為:
Action performed: to move ladder to position(5, 2).
Now ladder is near bananas at position(5, 2).
monkey climbs on ladder.
Action performed: to move monkey to position(5, 2).
Now monkey is near bananas at position(5, 2).
Monkey holds bananas.
true
換個查詢:
?- holds(monkey, ladder).
「猴子怎麼取梯子?」結果輸出為:
Action performed: to move monkey to position(1, 1).
Now monkey is near ladder at position(1, 1).
Monkey holds ladder.
true
以上例子要展示,對於一些有多個解決方向的問題,也許不適合直接寫一條演算法,或者不適合強制決定一項結果。而使用了規則推論系統,只要寫了適合的規則知識,就能夠取得可接受的答案。雖然答案的正確程度取決於規則的正確程度,不過,此系統的優勢是對於取得解答的要求與限制是寬鬆的、軟性的。
備註: Prolog 的規則格式,左邊項幾乎只能有一項描述詞,而缺乏 and 或 or 連接詞的寫法。因應於此限制,規則的四項構成物件:目標、前置目標、相關條件、以及引用規則的描述,只有目標寫在左邊項。其他使用向前鏈接推理的系統,例如 OPS ,規則格式寫成 "if ... then ..." 格式,能夠容許左邊項和右邊項都有 and 或 or 連接詞的寫法,則是在左邊項寫了前置目標和相關條件,並在右邊項則寫了目標和引用描述。

Monday, December 29, 2008

推論引擎

最近在閱讀有關規則推論引擎 (rule-based inference engine) 的書和資料。這方面的研究知識早在九零年代結束之前就成熟了,但在國內技術應用看起來像是冷門技術項目。有人說專家系統是沒落的東西。然而,放眼看過去技術應用趨勢,八零年代時 LISP 的使用也相當熱門,九零年代初期 Prolog 已取得成功應用,而專家系統 (expert system) 的規則推論引擎和框架系統 (frame-based system) 是二項成功產物。資訊領域並不是只有命令式程式 (imperative programming) 計算模型,並不是要會寫 C 或 Java ,或者要會雕刻組合語言,才佔領全局。還有其他的聰明、高產能的選項可挑選!
推論引擎的產生,來自於解決問題的需要 --- 許多問題並不只是寫一則演算法就能解決。有些問題的思考空間太龐大,而且對於那些問題,經常只有一部分的解題規則,這些規則可能來自於專家的知識或經驗。於是生成系統 (Production System) 出現,後來此系統類型稱為專家系統。規則式生成系統的構成,有一組以具體表達的規則所組成的知識庫、知識輸入介面、推論引擎、以及工作空間。系統接受一些事實作為輸入,由推論引擎將輸入事實與知識庫中的解題規則互相比對,藉由邏輯的歸納推理產生解決方案。此系統的好處是,答案是由專家知識所導出,而且導出答案的那些規則可以直接作為解釋。缺點是,系統所容納的知識庫不能太大,若規則太多則耗費計算時間,以及知識規則的建置花費工夫。
推論引擎的效能問題,在於輸入的事實與知識庫的規則比對所消耗的時間。 Markov 演算法提出順序式的比對,帶來直接的毛病是:有多少規則,就要比對多少時間以上。而且,規則的比對經常花費 O(n2) 級的成本,因為推論引擎必須做到衝突決議 (conflict-resolution) 的處理程序,意即經過眾多層次不同且可能有彼此矛盾的規則,綜合評判之後,取得一致的正確結果。為了適應規則推論引擎的特殊計算環境, Rete 演算法提出以網狀資料結構 (rete 是拉丁文,意思是 net ) 處理衝突決議。推論引擎總是進行循環工作,進行步驟有:1. 接受輸入事實並啟動; 2. 比對規則; 3. 衝突決議:若沒有比對到任何規則,則關閉,否則由比對到的規則中挑選一條規則,認定為生效; 4. 將生效的規則啟動,改變工作空間的狀態; 5. 回到步驟 (2) 。
推論引擎雖然不好寫,卻也可以用組合語言或 C 撰寫。 2003 年, Lynwood Wilson 在 Dr. Dobb's 雜誌發表的文章 ”Rule-Based Programming in C” 示範了二項注意事項: 1. 要做衝突決議; 2. 將專家系統劃分為模組使計算時間減少。因為是簡單的示範,他使用 Markov 演算法比對規則。
參考文獻
1. Joseph C. Giarratano & Gary D. Riley. Expert Systems: Principles and Programming. (4 ed.) Course Technology, Thomson Learning, 2005.
2. Charles L. Forgy. Rete: a fast match algorithm. AI Expert, vol. 2, issue 1, 1987.
3. Lynwood Wilson. Rule-Based Programming in C. Dr. Dobb's Portal. Available online: http://www.ddj.com/184405245.

Blog Archive