4.3 答題驗證設計與實作
4.3.3 系統程式架構
系統程式架構圖如圖 19,其中GNU Aspell是在做拼字檢查的部份;Apple Pie Parser及Apple Pie Parser’s Parser 是在做詞性標記及解析句構的工作;利用
WordNet做出語義檢查的資料庫主要存在DataBase中;Module 大部份是在做文法 檢查的工作,其中一小部份負責與GNU Aspell及DataBase做溝通。各部份的工作 內容及動作詳述如下:
Apple Pie Parser Apple Pie Parser’s Parser
Interface
DataBase (WordNet、
vi、vt、nc、nu
). . . . . . .
Main
program
Module 1 Module 2 Module NModule 3
GNU Aspell
Apple Pie Parser Apple Pie Parser’s Parser
Interface
DataBase (WordNet、
vi、vt、nc、nu
). . . . . . .
Main
program
Module 1Module 1 Module 2Module 2 Module NModule NModule 3Module 3
GNU Aspell
圖 19:答題驗證系統程式架構圖
1. GNU Aspell:
我們利用 Kevin Atkinson 在 1998 年開始製作至今的 GNU Aspell,來為我們做 拼字檢查的工作,其最後一個版本是 2004 年 12 月 GNU Aspell 0.60.2 版。拼 字檢查主要是在做純粹單字拼字造成錯誤的檢查,例如:應該是 modern,就 有可能誤拼成 morden 的拼字錯誤。GNU Aspell 是一個免費而且又是 Open Source 的拼字檢查程式,他既可以單獨當做拼字檢查的軟體,也可以當做一 個函式庫供程式呼叫使用,所以在使用上非常的方便。並且提供了一個功 能,可以猜測拼錯字可能的結果,給予一些建議的單字,提供給我們使用者 更多的參考資訊。
以下幾個是常用到的函式庫:
(1) aspell_new
功用:載入一個新辭典。
語法:int aspell_new(string master, string personal);
說明:Aspell_new( )開放一個新辭典且傳回辭典連結 identifier 給其它拼字 函式使用
(2) aspell_check
功用:檢查一單字。
語法:boolean aspell_check(int dictionary_link, string word)。
說明:Aspell_check( )檢查一單字的拼法,若拼法是正確的則傳回 true,若 是錯誤的則傳回 false。
(3) aspell_check-raw
功用:檢查一單字不改變它的事實或試著去修改它。
語法:boolean aspell_check_raw (int dictionary_link, string word)。
說明:Aspell_check-raw( )檢查一個單字的拼法,不改變它的事實或試著去 修改它,若拼法是正確的則傳回 true,若是錯誤的則傳回 false。
(4) aspell_suggest
功用:建議單字的拼法 。
語法:array aspell_suggest (int dictionary_link, string word)。
說明:Aspell_suggest( )將單字可能的拼法放入陣列變數中傳回。
2. Apple Pie Parser:
此部份主要是 Apple Pie Parser (APP)的主程式,負責為答題句子做解析之用。
APP 是一個統計式的解析程式,其與傳統的 rule-based parser 所有不同,他解 析句子的文法規則是由語料庫中統計而得,並且統計出每個文法規則的權重 值。其在進行解析時,就是根據每個文法規則的權重值,來決定是增加或減 少總權重,最後得到一個適當的總權重值,對映到相關的文法規則,而解析 出最後的文法解析樹。由於 APP 使用這種統計權重值的特色,因此在解析句 子時,並沒有所謂的對與錯,無論如何都可以解析出來。
APP 主要做解析的動作,像是輸入一個句子「This apple pie looks good and is a real treat.」,可以得到以下的解析結果:(S (NP (NPL (DT This) (NN apple))
(NN pie)) (VP (VP (VBZ looks) (ADJP (JJ good))) (CC and) (VP (VBZ is) (NPL (DT a) (JJ real) (NN treat)))) (. -PERIOD-))
3. Apple Pie Parser’s Parser:
Apple Pie Parser’s Parser (APPP)此部份是將 APP 對一個句子解析完畢後的解析 樹,再做進一步的處理,把解析樹處理成我們想要的資料結構。APPP 的過程 中主要是利用 lex & yacc 來處理這個部份,把 APP 輸出的解析樹切成各別的 token,再依每個 token 之間的組合方式,建成我們希望的資料結構。
APPP 如此做法還可以達到一個好處,就是往後如果將解析的主程式 APP 換掉 後,所有的程式結構不須要重寫,而只要修改 APPP 這個部份,讓其輸出仍然 符合現在的資料結構,如此就可以讓整個系統繼續正常運作。
以下利用圖 3的解析樹來說明APPP切出token的結構:
(1) LEAF:為 tree 的最末端,左端是 tag,右端是單字,例如:(NN apple))、
(NN pie)、(CC and)皆是。
(2) NODE:可以是 LEAF 或(tag+NODE_LIST)的結構,例如:(NPL (DT This) (NN apple))就算一個符合(tag+NODE_LIST)的結構,而算是一個 NODE。
(3) NODE_LIST:可以是 NODE 或 NODE_LIST+NODE 的結構,例如:(DT This) (NN apple)就算一個符合 NODE_LIST+NODE 的結構,而算是一個 NODE_LIST。
(4) TREE:是最頂端的結構,例如:(S….)。
APP 的輸出結果經過 lex & yacc 用以上的規格,切出 token 後,就可以在 APPP 中自己建立出一個解析結果的樹狀結構,就如圖 20 所示的一個解析 樹,其結果和圖 3 說明中的解析樹一樣,如果一來,我們的程式就可以依此 樹結構去做許多的動作,另外,有了這個解析樹的顯示,在做程式時可以更 容易了解句子的結構,進而找出問題所在之處。
(NPL)
This apple pie looks good and is a real treat.
圖 20:Apple Pie Parser’s Parser 建立出解析樹
4. Interface:
建立出一些 class,做為上層程式與下層程式間的介面,讓上下層程式的工作 分開。而上層程式指的是 Main program 及 Moudle,下層程式指的是 GNU Aspell、APP、APPP 及 DataBase。其建立出的 class 介紹如下:
(1) class ConfirmingSentence
一個紀錄每次驗證資訊的容器,其實也就是 Message。可以讀取或新增程 式回傳的錯誤訊息,但無法修改已儲存的錯誤訊息資料,並提供許多模組 化許須的操作。各個模組與主程式間亦透過此物件來溝通。
(2) class Sentence
基本的一個句子,把一串句子切成 token,並產生出句構。此 class 無法被 同類以外初始化,必需透過 ConfirmingSentence::createSentence 產生 factory pattern。這麼做主要是為了模組化的考量。
(3) class Message
紀錄一次驗證失敗的結果,包函被驗證的句子,以及其出錯的 token 位 置,還有記錄錯誤訊息。
(4) class CNode
處理句子結構的 tree 中 node 的各項動作,例如:取得 tag、判斷目前 node 是否為 leaf、取得 node 所有的 children。
(5) class CLeaf:public CNode
繼承自 CNode。處理 leaf 中的各項動作,例如:取得 tag、取得 leaf 的單 字、得到 leaf 是在句子中第幾個字。
5. Main program:
依照動態連結方式,從設定檔中呼叫每個函式庫,依次序一一執行。
6. Module:
在做拼字檢查、文法檢查及語義檢查時,所須要做的程式動作,都各別放在 一個 Module 程式當中。一個 Module 程式是動態連結函式庫模組化程式的一 部份。因為採用動態連結方式,所以每一個 Module 程式都算單獨一個程式,
如果須要修改其中一個 Module 的程式內容時,則只須要對該 Module 程式重 新進行編譯。當日後有需要再新增 Module 時,只要在 Main program 的設定檔 增加此 Module 名稱的設定,整個程式即可新增出此 Module 程式的動作,大 大的增加日後擴充程式的方便性。
7. DataBase:
存放每個 Module 程式有可能用到的資料庫,主要有兩大類資料庫,一是 WrodNet 同義字的資料庫,另一個詞性輔助資料庫。其說明如下:
(1) WrodNet 同義字資料庫:
就如 2.4 節WrodNet相關說明資料中提到,WrodNet可以查到單字的同義 字,而且其資料是開放使用的,所以我們取其同義字的部份建成資料庫,
以方便程式在做語義檢查時直接查詢使用,其資料庫欄位資料如表 9及 表 10所示。
表 9 wordnet_index 資料庫結構一覽表
欄位 型態 校對 說明
word varchar(70) utf8_general_ci 單字
relate int(11) 單字語義代號
type enum('noun','verb','adj','adv') utf8_general_ci 單字詞性
表 10 wordnet_data 資料庫結構一覽表
欄位 型態 校對 說明
id int(11) 單字語義代號
word varchar(70) utf8_general_ci 同義字 type enum('noun','verb','adj','adv') utf8_general_ci 同義字詞性
其資料庫查詢的方式,首先在 wordnet_index 資料庫 word 欄位查出單字相 對映出單字語義的代號,再依此單字語義的代號,可以在 wordnet_data 資 料庫中查到此語義的同義字,所以我們就以利用以下的指令查詢出
「happy」的同義字。
SELECT `wordnet_index`.`type` , `wordnet_data`.`word`
FROM `wordnet_data`, `wordnet_index`
WHERE `wordnet_index`.`word` LIKE 'happy' AND `wordnet_index`.`relate` = `wordnet_data`.`id`
AND `wordnet_index`.`type` = `wordnet_data`.`type`
ORDER BY `wordnet_data`.`type`, `wordnet_data`.`word`
查詢「happy」的同義字的結果如表 11,其結果與圖 2 所示查詢結果一 致。查詢結果中有許多重覆的字,可以另外經過程式處理將其省略。
表 11 WrodNet 同義字資料庫查詢「happy」同義字結果一覽表 type(詞性) word(詞彙)
adj euphoric adj felicitous adj happy adj pleased adj well-chosen
(2) 詞性輔助資料庫:
C. 人稱代名詞(Personal Pronouns)資料庫:資料庫當中對動詞做更詳細的分 類標記,其分類標記包含有:第一二三人稱、單數、複數、主格、受 格、所有格。
其資料庫結構如表 12所示:
表 12 詞性輔助資料庫資料庫結構一覽表
欄位 型態 校對 說明
word binary(30) 單字
詞性代號 type varchar(4) utf8_general_ci