梁社會,陳小荷,劉 瀏
1.南京師范大學 國際文化教育學院,南京210097
2.南京師范大學 文學院,南京210097
作為儒家經(jīng)典的《孟子》,能廣為流傳,在一定程度上來說和它大量使用修辭格是有關的。據(jù)研究,《孟子》中出現(xiàn)較多、較為典型的修辭格有比喻、對偶、排比、對比、夸張、引用、反復等[1-6]。
《孟子》是一部政論性的著作[7],它很突出的一個特點是論述性的語言占有很大篇幅,而排比句是其中最具有特色的一類句型。《孟子》中很多重要的論述都是通過排比句的形式表達的。
通過排比來說明道理,顯得條理清晰,而且氣勢宏大,有說服力,使得孟子能更有力地向梁惠王等人闡述自己的政治主張?!睹献印分蓄愃频氖褂门疟染浔磉_自己政治意見的語句有許多,摘錄這些排比句并做專門研究,可以從一個新的角度去理解和學習《孟子》中的有關內(nèi)容。
現(xiàn)在,關于修辭格自動識別的文獻還不多見,其中,關于《孟子》中的修辭格和《孟子》中排比句自動識別的文獻還暫沒看到。本文研究旨在探討通過計算機來自動獲取《孟子》中的排比句,這樣不僅可以提供一個《孟子》排比句的可信數(shù)據(jù)庫,而且在處理其他體裁相同或相似文本時,也能夠提供一種有效的自動獲取排比句的方法,為以后更多的修辭格的自動識別提供參考。
如前所述,目前針對《孟子》或其他先秦文獻的排比句的自動識別或獲取的相關研究還沒有看到,現(xiàn)代漢語方面的相關研究也不多見。因此考慮自行設計一種有效的算法來獲取《孟子》中的排比句,并將在其他相關的先秦文獻中進行測試實驗,以檢驗該算法的可靠性和效率。
《孟子》全書總字數(shù)約為三萬五千字[8]。這個字數(shù)表明《孟子》規(guī)模較小,不適合使用統(tǒng)計的方法,因此,將采用規(guī)則的方法來自動識別排比句。
排比句中“句”的邊界并不嚴格,分隔排比句各個子句的標點符號可能是逗號、分號或者是句號(這里所謂的句號包含問號和感嘆號)。這幾種標點所分隔的子句長度,一般而言是從逗號到分號到句號依次遞增的,但是各個子句之間的長度一般是相當?shù)模虼瞬挥绊憣τ蛇@幾種標點分隔的子句采用同一種算法從中查找排比句。
為了保證查找的完整和準確,首先將經(jīng)過分詞和詞性標注處理并經(jīng)過人工校對后的《孟子》語料進行自動斷句處理,斷句的標準分為3 種,分別是對逗號、分號、句號斷句,對逗號、分號斷句和只對句號斷句。將從3 種標準斷句后得到的語料中,分別查找其中的排比句,最后合并得到的便是《孟子》中所查找到的全部排比句。
一般認為,排比是一種修辭手法,利用3 個或3 個以上意義相關或相近,結構相同或相似,語氣相同的詞組或句子并列排在一起,用以達到加強語勢的效果[9]。
于志忠[10]認為,用排比來說理,可收到條理分明的效果;用排比來抒情,節(jié)奏和諧,顯得感情洋溢……總之,排比的行文瑯瑯上口,有極強的說服力,能增強文章的表達效果。
概括起來,排比句的特征一般有以下3 點:
(1)各子句相連;
(2)結構相同或類似;
(3)各子句中部分詞語重復。
本文考慮從排比句所具有的這3 種特征分別入手,來設計查找排比句的算法。
2.2.1 最長公共子序列的求解
由于排比句自動識別算法中需要用到最長公共子序列,因此先簡單介紹一下最長公共子序列的求解。最長公共子序列的求解目前已有許多成熟高效的算法,其中最有效的是動態(tài)規(guī)劃算法[11]。動態(tài)規(guī)劃算法的思想是將待求解問題分解成若干子問題,通過自底向上地解決子問題來最終獲得所求問題的最優(yōu)解。由于將已解決的子問題的結果保存下來,這樣就能夠在再次遇到這些問題時避免重復計算,節(jié)約了大量的時間,提高了算法的效率。
動態(tài)規(guī)劃算法一般有以下4 個步驟[12]:找出最優(yōu)解的性質,并描述其結構特征;遞歸地定義最優(yōu)值;以自底向上的方式計算出最優(yōu)值;根據(jù)計算最優(yōu)值時得到的信息,構造最優(yōu)解。
由于用動態(tài)規(guī)劃算法求最長公共子序列只是實驗中一個較小的部分,這里不再贅述。
2.2.2 相連
排比句中的各個子句是前后相連的,因此須按順序依次查找各子句。根據(jù)已有的斷句語料,設計了一種簡單的遍歷算法。
算法1排比句的遍歷識別
i=0,j=0,P=null;
while(i+2 <resource.num){
if(P==null)P=Si+Si+1+Si+2;
elseP=P+Si;
if(functionP(Si,Si+1)!=null||functionP(Si,Si+2)!=null)i++ ;
elseResult=P,P=null,j++,i++ ;return result;
}
根據(jù)算法1,遍歷3 種標準得到的語料合并后,即可自動獲得需要的排比句。算法1 是進行排比句自動識別的核心算法。算法1 中包含有一個重要的子算法P(X,Y),用以判斷子句X、Y能否構成排比句的一部分,也就是說子句X和Y能否達到一定的相似程度,以滿足這兩個子句有可能是某一個排比句的一部分,該子算法請參見算法4。算法4 的實現(xiàn),即運用到了排比句另外兩個重要的性質,結構類似和部分詞語重復。
2.2.3 結構類似
結構類似說明排比句中各個子句在結構上具有相同或相近的結構關系,在無法對《孟子》全文做完全的句法結構分析的前提下,只能將句子結構的類似簡化為句子詞性序列的類似。詞性序列也就是句子中每個詞的詞性依次排列構成的一組序列,通過比較兩個子句詞性序列的相似程度來替代比較兩個子句的詞語結構的相似程度,這可以大大簡化算法的復雜程度,并提高算法的效率。以下是結構類似性算法的具體描述。
算法2結構類似性的計算
i=0,Score=0,POSi[t],POSj[n];
m=functionM(X,Y);
while(i<m.length){
if (t-POSi.Indexof(m.substr(i,1))<4&&n-
POSj.Indexof(m.substr(i,1))<4){
Score=Score+1;i++;
}
算法2 中有以下幾點值得注意:
算法最終得到一個Score評分,Score評分是用數(shù)值表示的兩個串S1、S2結構相似性的程度,這個值將用于算法1中P(X,Y)的求解,見算法4;M(X,Y)便是上文介紹的用動態(tài)規(guī)劃算法求解兩串X、Y的最長公共子序列;第四步中用于判斷的距離,是距串尾而不是串首的距離。其原因是在大部分的排比句中,子句靠右的部分(也就是靠近串尾的部分)相似程度要大于靠左的部分(也就是靠近串首的部分);第五步針對的是較長的詞性串,長度較大的詞性串之間的最長公共子串容易偏大,如果在此基礎上訓練算法,將會忽略掉大多數(shù)長度較小的詞性串,這是不希望看到的。因此對長度之和大于60 的情況進行評分的削減,以平衡長串和短串之間的差異。
2.2.4 部分詞語重復
結構類似是從詞性的角度模擬排比句結構類似的特征,部分詞語重復的特征則可以直接通過字符序列的比較來得到檢驗。以下是有關部分詞語重復程度計算算法的描述:
算法3部分詞語重復程度的計算
i=0,Score=0,Chari[t],Charj[n];
m=functionM(X,Y);
if(m.contain(”,”)||m.contain(”;”))
Score=Score+1;
else if(m.contain(”,”)||m.contain(”?!保?/p>
Score=Score+1;
while(i<m.length){
if(t-POSi.Indexof(m.substr(i,1))<4&&n-POSj.Indexof(m.substr(i,1))<4){
Score=Score+1;i++;
}
returnm-n>60:score=score-10?score;
算法3 與算法2 非常相似(實際上,算法2 是從子句詞性串的角度入手,而算法3 是從子句字串的角度入手)。有一點特殊的就是,字串中包含標點,因此,第三步的m中若同時包含逗號和分號,或同時包含逗號和句號,那么S1、S2結構相似的程度就會大一些,因此對score評分加1。
2.2.5 排比句的識別
上面介紹的算法1 中,有個重要的子算法P(X,Y)用以判斷子句X、Y能夠構成一個排比句的一部分,以下是這個算法的具體實現(xiàn):
算法4P(S1,S2)判斷S1、S2能否構造一個排比句
score1=functionS(S1,S2),score2=functionW(S1,S2);
L1=S1.Length,L2=S2.Length;
if (L1<15||L2<15) return false;
if (L1>2*L2||L2>2*L1) return false;
if (S1.findlastof(“。!?”)==S1.Length-1 &&
S2.findlastof(“,;”)==S2.Length-1) return false;
if (score1*P1+score2*P2>=P3) return true;
算法4 中,第四步到第六步均是可以排除S1、S2構成排比句可能性的特殊情況。通過調節(jié)P1、P2、P3參數(shù),可以調整判斷S1、S2能否構造一個排比句的標準,以調整最終識別獲取排比句的正確率和召回率。通過以上幾種算法的結合,就可以實現(xiàn)一個完整的用以識別《孟子》中所有排比句的算法。
算法5《孟子》排比句的自動識別
P1=0.1,P2=0.1,P3=0.2,R=0;
While(Read(file)){
functionFirst(file.lines);}
Calculate(p,r,f);
if (r>R)R=r;
if (P2<1){P2=P2+0.1,FuntionFive(P2);}
elseP2=0.1;
if (P1<1){P1=P1+0.1,FuntionFive(P1);}
elseP1=0.1,P2=0.1;
if (P3<1){P3=P3+0.1,FuntionFive(P3);}
else Output(parallelism sentences);
算法5 是對之前幾種算法的整合,并且對幾個參數(shù)進行了遍歷,以尋找出最優(yōu)的排比句識別效果。由于該算法較多地注重了召回率,所以找到的結果正確率稍低了一些。為改進這種情況,在算法5 之后又增加了一個過濾查找結果的過程。
根據(jù)排比句的特點,并仔細分析研究了自動識別結果中錯誤的句子,歸納、整理了以下7 條規(guī)則:
(1)如果某結果中有兩個句號、一個問號,則該結果不算排比句,刪除之。
(2)如果某結果中有兩個句號、一個分號,則該結果不算排比句,刪除之。
(3)如果某結果中只有兩個句號,也就是說,如果該結果只有兩句話,則該結果不算排比句,刪除之。
(4)如果某結果中有一個句號、兩個問號,則該結果不算排比句,刪除之。
(5)如果某結果中有前后兩個分號,中間一句為句號,則該結果不算排比句,刪除之。
(6)如果該結果只有一句話(以句號、問號或感嘆句結尾的為一句話),且前面的分句以逗號或分號結尾,最后一個標點為問號的,則該結果不算排比句,刪除之。
(7)如果某結果中只有逗號,沒有別的句號或問號,則該結果不算排比句,刪除之。
根據(jù)這些規(guī)則對算法5 找到的排比句進行篩選之后,就基本解決了正確率稍低的問題。
在《孟子》分詞和詞性標注的基礎上,花費了較多的精力進行了排比句的人工標注,來作為排比句自動獲取實驗的標準答案。
經(jīng)過人工標注后的《孟子》各篇的排比句共有74 個,分布情況如表1 所示。從這些數(shù)據(jù)可以看出,排比句的分布并不是很均勻,排比句最多的一篇比最少的要多出4 倍。
表1 《孟子》排比句分布情況
將《孟子》共14 篇文本按6∶4∶4 的比例分成訓練集、開發(fā)集和測試集,分別進行封閉測試和開放測試。其中,訓練集各篇分別為:梁惠王上、梁惠王下、公孫丑上、公孫丑下、滕文公上、滕文公下;開發(fā)集的各篇分別為:離婁上、離婁下、萬章上、萬章下;測試集的各篇分別為:告子上、告子下、盡心上、盡心下。
根據(jù)算法5 的參數(shù)調試以及排比句結果篩選規(guī)則的篩選,得到了比較理想的排比句實驗結果。實驗得到的最優(yōu)參數(shù)分別為:P1=0.1,P2=0.1,P3=0.5,最優(yōu)結果的具體性能詳見表2、表3、表4。
表2 《孟子》排比句自動識別封閉測試結果
表3 《孟子》排比句自動識別開放測試結果
表4 《孟子》排比句自動識別封閉、開放測試結果比較
根據(jù)以上各表中得到的統(tǒng)計結果可以發(fā)現(xiàn),《孟子》排比句識別的召回率總體來說還是很高的,大部分章節(jié)甚至達到了百分之百。正確率盡管經(jīng)過規(guī)則篩選,但仍難以達到更好的性能,原因可能有以下幾點:
首先,篇幅限制?!睹献印分腥斯俗⒌拇鸢敢还仓挥?4處,自動識別的排比句一共也只有127處,規(guī)模過小,統(tǒng)計意義上容易產(chǎn)生較大的誤差,比如《萬章上》一共只有6處排比句,找到了3 處,召回率就只有0.5 了,正確率也會比較低。
其次,算法限制。本文算法主要基于排比句形式上的特點,并主要根據(jù)標點符號的規(guī)則加以篩選,這樣有可能會產(chǎn)生一些問題。一個是有些排比句各子句雖然形式上關聯(lián)程度不大,但意義上聯(lián)系十分緊密,如《離婁上》中有一句排比如下:
得天下有道:得其民,斯得天下矣;
得其民有道:得其心,斯得民矣;
得其心有道:所欲與之聚之,所惡勿施,爾也。
其中第三個子句與前兩個子句在形式上的差別是遠大于相似之處的。因此,希望僅通過建立形式規(guī)則算法,是難以有效找全或找到這類排比句的。
另外,語料本身可能的錯誤也會造成結果的偏差,如《萬章上》有如下一個排比句:
天下之士悅之,人之所欲也,而不足以解憂;
好色、人之所欲,妻帝之二女,而不足以解憂,
富、人之所欲,富有天下,而不足以解憂;
貴、人之所欲,貴為天子,而不足以解憂。
通過觀察可以發(fā)現(xiàn)第二個子句的句末標點是逗號,與第一和第三個子句不同,根據(jù)本文算法,這種情況將被排除在排比句之外。當然通過修改這類錯誤,提高語料的質量可以有效改進這類錯誤造成的性能損失,但這也體現(xiàn)了本文方法對語料形式的依賴性較大。
當然,《孟子》中各個小句之間形式上非常相似,各小句的字數(shù)不太多且相差不大,干擾性較大,也是造成識別正確率相對較低的原因之一。
盡管識別結果尚有一些不太完善的地方,但提出的方法已經(jīng)很有效地做到了對《孟子》中排比句的自動識別,對先秦文獻排比句的自動識別進行了積極的探索。
為了測試該方法在其他類似文本中的通用性,又選取了先秦文獻《論語》[13],使用同樣的方法進行了排比句的識別實驗。值得注意的是,《論語》訓練并遍歷參數(shù)后,最終得到的最優(yōu)參數(shù)依然是:P1=0.1,P2=0.1,P3=0.5,具體性能見表5。
表5 《論語》排比句自動識別結果
《論語》中人工標注的排比句答案共有42 個,其中《論語》有4 篇是沒有人工標注的排比句答案的,也就是說,暫時認為這4 篇中是沒有符合所界定的排比句的。這4 篇分別為:里仁、先進、微子、子張,在表5 中,它們的正確率、召回率和F值顯示的均為0。
觀察可以發(fā)現(xiàn),《論語》排比句自動識別的效果稍微好于《孟子》中排比句的識別效果,這里認為可能是以下原因造成的:
(1)《論語》中的句子長度相比較《孟子》而言,不是很長,也比較適合查找?!睹献印啡钠骄渥泳溟L為21.8,平均小句句長為7.0,《論語》全篇的平均句子句長為11.4,平均小句句長為5.2。《孟子》、《論語》中具體各篇的平均句子長度和平均小句句長統(tǒng)計數(shù)據(jù)請見表6、表7。從表中可以看出,無論是平均句長,還是平均小句句長,《孟子》中的統(tǒng)計數(shù)據(jù)都遠高于《論語》中的統(tǒng)計數(shù)據(jù),這在一定程度上為《孟子》的排比句自動識別增加了難度。
表6 《孟子》各篇平均句長、平均小句句長統(tǒng)計數(shù)據(jù)
(2)《孟子》中的排比句類型較多,各排比句之間差異過大?!睹献印分械呐疟染溆芯渲信疟取⒕溟g排比,甚至段與段間的排比,而《論語》中的排比則相對比較單純。另外,《論語》中有4 篇是沒有排比句的。
可以看出,盡管是面對比較陌生且寫作風格不太相同的《論語》,本文的排比句自動識別算法依然保持了較好的性能。
從《孟子》單部文本出發(fā),通過總結《孟子》中排比句的特點,制定規(guī)則,設計算法,提出了一種有效的自動識別排比句的方法。將該方法用于先秦文獻中另一部重要文獻《論語》,進行了排比句的自動識別,同樣取得了較理想的效果。
表7 《論語》各篇平均句長、平均小句句長統(tǒng)計數(shù)據(jù)
但是本文方法也有不足之處,比如對語料的質量有較高的依賴性,忽視了語句的意義因素等。今后的工作重心將放在如何彌補這些問題,并在更大規(guī)模的語料中提供更可靠的統(tǒng)計信息。自動識別排比句的方法不僅要能適應先秦文獻的需求,還應該能有效地應用到其他古代漢語文獻,甚至現(xiàn)代漢語的語料中。
[1] 丁秀菊.先秦儒家修辭研究[D].濟南:山東大學,2007.
[2] 杜鵑.孟子辯論的語言藝術[J].新聞愛好者,2009(9):38-39.
[3] 黃必莊.孟子論辯的修辭藝術[J].廣西師范大學學報:哲學社會科學版,1992(S1):11-15.
[4] 劉斌.歷代《孟子》研究概觀[J].齊魯學刊,1987(2):8-15.
[5] 孔亞飛.《孟子》修辭研究[D].山東曲阜:曲阜師范大學,2011.
[6] 鄭子瑜.論先秦諸子的修辭技巧[J].社會科學戰(zhàn)線,1980(4):290-295.
[7] 董洪利.孟子研究[M].南京:江蘇古籍出版社,1997.
[8] 周文德,楊曉蓮.《孟子》數(shù)據(jù)庫[M].成都:巴蜀書社,2002.
[9] 李勝梅.排比的篇章特點[J].南昌大學學報:人文社會科學版,2005(5):127-133.
[10] 于志忠.蘇轍“記體散文”研究[D].內(nèi)蒙古通遼:內(nèi)蒙古民族大學,2011.
[11] 鄭翠玲.最長公共子序列算法的分析與實現(xiàn)[J].武夷學院學報,2010(2):44-48.
[12] 王軍祥.動態(tài)規(guī)劃算法原理及應用研究[J].電腦知識與技術,2006,36:150-151.
[13] 楊伯峻.論語譯注[M].北京:中華書局,1980.