您的位置:首頁 >文化 >

用人工智能研究了《紅樓夢》,發(fā)現(xiàn)了賈府的興衰中的秘密

沒讀過《紅樓夢》也能知道前后四十回是不是一個作者寫的?很久以前,數(shù)據(jù)俠黎晨,用機器學習的算法分析了《紅樓夢》,認為后四十回和前八十回內(nèi)容上有明顯差距。不過,數(shù)據(jù)俠樓宇卻不這么認為,他覺得原先的判定方法不夠嚴謹,于是他使用了無字典分詞的方式,剔除了情節(jié)對分析的影響,再次用機器學習的算法分析了這部文學名著。

構(gòu)建全文索引與全文字典

兩個月以來,我通過互聯(lián)網(wǎng)自學了一些文本處理的知識,用自然語言處理和機器學習算法對《紅樓夢》進行了一些分析。這個過程中我找到了一些有趣的發(fā)現(xiàn)。

我開始做這件事情是因為之前看到了一篇挺好玩的文章,大概內(nèi)容是,作者用“結(jié)巴分詞”這個開源軟件統(tǒng)計了紅樓夢中各詞匯的出現(xiàn)次數(shù)(也就是詞頻),然后用詞頻作為每個章回的特征,最終用“主成份分析”算法把每個章回映射到三維空間中,從而比較各個章回的用詞有多么相似。(DT君注:數(shù)據(jù)俠黎晨原文《從沒看過紅樓夢,如何用機器學習判定后40回并非曹雪芹所寫》)作者的結(jié)論是后四十回的用詞和前八十回有明顯的差距。

我覺得文章有兩個小問題:首先,作者用的結(jié)巴分詞里的詞典是根據(jù)現(xiàn)代文的語料獲得的,而《紅樓夢》是半文半白的,這樣的分詞方法準確性存疑;其次,雖然作者用《三國演義》做了對比,但是依然沒有有力地證明用詞差異沒有受到情節(jié)變化的影響。于是我決定自己做一遍實驗,用無字典分詞的方法來分詞,并且嘗試剔除情節(jié)對分析的影響,看看結(jié)果會不會有所不同。

在處理文章之前,我需要建立一個全文索引。這樣是為了快速地查找原文內(nèi)容,加速后面的計算。我使用了后綴樹這個結(jié)構(gòu)作為索引,用了Ukkonen算法快速地創(chuàng)建了整篇《紅樓夢》的后綴樹(Ukkonen 算法的速度非??欤脤I(yè)的語言描述,它的時間復雜度是 O(n))。這樣我們就有了全文索引了。

接下來我們就要構(gòu)建一個字典了。

等等,我們不是要無字典分詞嗎,為什么還要制作字典?其實無字典分詞并不是完全不用字典,只是說字典是根據(jù)原文生成的,而不是提前制作的。為了進行分詞,我們還是需要先找出文章中哪些內(nèi)容像是單詞,才能確定如何進行切分。

那么怎么確定哪些內(nèi)容像單詞呢?最容易想到的方法就是:把所有出現(xiàn)次數(shù)高的片段都當成單詞。聽上去很有道理,所以我們可以試一試,用后綴樹查詢紅樓夢中的所有重復的片段,然后按出現(xiàn)次數(shù)排個序:

寶玉(3983)、笑道(2458)、太太(1982)、什么(1836)、鳳姐(1741)、了一(1697)、賈母(1675)、一個(1520)、也不(1448)、夫人(1437)、黛玉(1370)、我們(1233)、那里(1182)、襲人(1144)、姑娘(1142)、去了(1090)、寶釵(1079)、不知(1074)、王夫人(1061)、起來(1059)

上面是出現(xiàn)頻率前20的片段,括號內(nèi)是出現(xiàn)次數(shù)。可以看到效果還不錯,很多片段都是單詞。然而,排在第六名的“了一”明明不是個單詞,出現(xiàn)次數(shù)卻比賈母還要高。可見這樣的篩選方法還是有一定問題的。而且,這樣被誤當成單詞的片段還有很多,例如“了的”、“的一”之類的。

為了排除這樣的組合,我們可以用“凝固度”來進行進一步地篩選。凝固度可以排除單字的頻率對組合頻率的影響。經(jīng)過實驗,我發(fā)現(xiàn)整體效果還是不錯

的。

DT君注:凝固度指的是,一個片段出現(xiàn)的頻率比左右兩部分分別出現(xiàn)的頻率的乘積高出多少倍。值得注意的是,頻率表示的是出現(xiàn)的比例,而頻數(shù)表示的是出現(xiàn)的次數(shù)。凝固度的思想是,如果片段實際出現(xiàn)的概率比被隨機組合出來的概率高出很多倍,就說明這樣的組合應該不是意外產(chǎn)生的,而是有一些關聯(lián)的。這個關聯(lián)很可能就是因為這個片段是一個不可分割的整體,也就是單詞。

然而凝固度也有一定的問題。我們會發(fā)現(xiàn)還是有很多片段是半個詞,且也具有很高的凝固度。例如:“香院”(完整的詞應該是“梨香院”)、“太太太太”(完整的詞應該是“老太太太太”)。

想想也有道理,這些片段雖然是半個詞,但是它們確實也跟完整的單詞一樣是“凝固”在一起的。所以,光看凝固度是不夠的,還要通過上下文判斷這個詞是否完整。

為了排除掉不完整的單詞,我們可以使用自由度來繼續(xù)過濾,自由度描述的是一個片段相鄰的字有多么的不固定,一個真正的詞應該相互之間的聯(lián)系應

該是獨特的,不太會出現(xiàn)上文說的情況。也就是說如果片段的自由度比較高,就說明這個詞應該是完整的。

DT君注:自由度的思想是,如果一個組合是一個不完整的單詞,那么它總是作為完整單詞的一部分出現(xiàn),所以相鄰的字就會比較固定。比如說,“香院”在原文中出現(xiàn)了 23 次,而“梨香院”出現(xiàn)了 22 次,也就是說“梨”在“香院”的左邊一起出現(xiàn)的頻率高達 95.7%,所以我們有把握認為”香院”不是完整的單詞。而自由度描述的就是一個片段的相鄰字有多么的多樣、不固定。

有了這些明確的評判標準,我們就可以把單詞篩選出來了。我最終選擇的判斷標準是:出現(xiàn)次數(shù)大于等于5,且凝固度、左側(cè)自由度、右側(cè)自由度都大于1。然而這個標準還是太寬松了。于是,我又設計了一個公式,把這些數(shù)據(jù)綜合起來:

也就是說,我簡單粗暴地把凝固度和自由度乘了起來,作為每個片段的分數(shù)。這樣只要其中一個標準的值比較低,總分就會比較低。于是我的判斷標準里又多了一條:總分還要大于等于100。

經(jīng)過層層遴選之后,單詞表初步成型了。我從最終結(jié)果中隨機抽取了100個條目,其中有47個是希望得到的單詞:這意味單詞表的正確率只有一半左右。不過,在錯誤的條目里,很多條目的切分其實是正確的,只是有好幾個詞粘到了一起。所以其實我們沒有必要通過調(diào)高篩選標準的方法來進行更嚴格的過濾了。隨后分詞算法將會解決單詞沒有被切開的問題。

此外,根據(jù)字典的正確率和字典的大小,我計算出紅樓夢的詞匯量大概是 1.6 萬。

維特比算法找出最具效率的分詞方案

之前在篩選單詞的時候,思路就是用各種各樣的數(shù)值標準進行判斷。而對于“分詞”這個看似更加困難的問題,思路也是類似的:制定一個評價切分方案的評分標準,然后找出評分最高的切分方案。

評分標準是什么呢?最簡單的標準就是,把切分之后每個片段是單詞的概率都乘起來,作為這個切分方案正確的概率,也就是評分標準。我們假設,一個片段是單詞的概率,就是這個片段在原文中的出現(xiàn)頻率。

有了評分標準之后,還有一個問題:如何找出分數(shù)最高的切分方案呢?肯定不能一個一個地嘗試每一種方案,不然速度實在是太慢了。我們可以用一個數(shù)學方法來簡化計算:維特比算法。

維特比算法本質(zhì)上就是一個動態(tài)規(guī)劃算法。它的想法是這樣的:對于句子的某個局部來說,這一部分的最佳切分方案是固定的,不隨上下文的變化而變化;如果把這個最佳切分方案保存起來,就能減少很多重復的計算。我們可以從第一個字開始,計算前兩個字,前三個字,前四個字……的最佳切分方案,并且把這些方案保存起來。

因為我們是依次計算的,所以每當增加一個字的時候,我們只要嘗試切分最后一個單詞的位置就可以了。這個位置前面的內(nèi)容一定是已經(jīng)計算過的,所以通過查詢之前的切分方案即可計算出分數(shù)。

在構(gòu)造單詞表的時候,我計算了每個片段有多么像單詞,也就是分數(shù)。然而,后面的分詞算法只考慮了片段出現(xiàn)的頻率,而沒有用到片段的分數(shù)。于是,我簡單粗暴地把片段的分數(shù)加入到了算法中:把片段的頻率乘上片段的分數(shù),作為加權了的頻率。這樣那些更像單詞的片段具有更高的權重,就更容易被切分出來了。

還有一個小優(yōu)化。我們知道,一般中文單詞的長度不會超過四個字,因此在程序枚舉切分方法的時候,只需要嘗試最后四個切分位置就可以了。這樣就把最長的切分片段限制在了四個字以內(nèi),而且對于長句子來說也減少了很多不必要的嘗試。

抽查程序運行結(jié)果后發(fā)現(xiàn),最終程序分詞算法的準確率是85.71%(意義是程序切開的位置有多少是應該切開的),召回率是75.00%(意義是應該切開的位置有多少被程序切開了)。這個結(jié)果看上去不是很高,因為大部分開源的分詞軟件準確率都能達到90%以上,甚至能達到97%以上。不過,畢竟我用的是無字典的分詞,而且算法也比較簡單,所以我還是比較滿意的。

但是其中詩詞的分詞更難一些,準確率相比其他部分低了10%左右。這也在情理之中,因為詩詞中有很多不常用詞,有些詞甚至只出現(xiàn)過一次,所以電腦很難從統(tǒng)計數(shù)據(jù)中發(fā)掘信息。

統(tǒng)計結(jié)果說:賈府的人很愛“笑”

完成分詞以后,詞頻統(tǒng)計就非常簡單了。我們只需要根據(jù)分詞結(jié)果把片段切分開,去掉長度為一的片段(也就是單字),然后數(shù)一下每一種片段的個數(shù)就可以了。

這是出現(xiàn)次數(shù)排名前20的單詞:

寶玉(3940)、笑道(2314)、鳳姐(1521)、什么(1432)、賈母(1308)、襲人(1144)、一個(1111)、黛玉(1102)、我們(1068)、王夫人(1059)、如今(1016)、寶釵(1014)、聽了(938)、出來(934)、老太太(908)、你們(890)、去了(879)、怎么(867)、太太(856)、姑娘(856)

通過分詞后的詞頻,我們發(fā)現(xiàn)《紅樓夢》中的人物戲份由多到少依次是寶玉、鳳姐、賈母、襲人、黛玉、王夫人和寶釵。然而,這個排名是有問題的,因為”林黛玉”這個詞的出現(xiàn)次數(shù)還有267次,需要加到黛玉的戲份里,所以其實黛玉的戲份比襲人多。

同理,“老太太”一般是指賈母,所以賈母的戲份加起來應該比鳳姐多。正確的排名應該是寶玉、賈母、鳳姐、黛玉、襲人、王夫人和寶釵。

此外,我們還發(fā)現(xiàn)《紅樓夢》中的人物很愛笑,因為除了人名以外出現(xiàn)次數(shù)最多的單詞就是“笑道” : )

我把完整的詞頻表做成了一個網(wǎng)頁,感興趣的話可以去看一下:紅樓詞表。

終于做完了分詞,又離目標靠近了一大步。現(xiàn)在,我可以用之前看到的那篇文章里提到的PCA算法來分析章回之間的差異了。不過在此之前,我想先反思一下,到底應該用哪些詞的詞頻來進行分析?

在很多用PCA分析《紅樓夢》的博文里,大家都是用出現(xiàn)頻率最高的詞來分析的。然而問題是,萬一頻率最高的詞是和情節(jié)變化相關的呢?為了剔除情節(jié)變化的影響,我決定選出詞頻隨情節(jié)變化最小的單詞來作為每一章的特征。而我衡量詞頻變化的方法就是統(tǒng)計單詞在每一回的詞頻,然后計算標準方差。為了消除單詞的常用程度對標準方差的影響,我把標準方差除以該單詞在每一回的平均頻數(shù),得到修正后的方差,然后利用這個標準來篩選特征詞。

最終,我選擇了詞頻變化最小的50個詞作為特征,每個詞的修正后標準方差都小于0.85。理論上,有了特征之后,我們就可以比較各個章節(jié)的相似性了。然而問題是,現(xiàn)在我們有50個特征,也就是說現(xiàn)在的數(shù)據(jù)空間是 50 維的,這對于想象四維空間都難的人類來說是很難可視化的。對于高維數(shù)據(jù)的可視化問題來說,PCA是一個很好用的數(shù)學工具。

我利用PCA,把五十個詞的詞頻所構(gòu)成的五十個維度壓縮到二維平面上。把壓縮后的數(shù)據(jù)點畫出來,發(fā)現(xiàn)是這個樣子:

(圖片說明:圖中每個圓圈代表一個回目。圓圈內(nèi)是回目編號,從 1 開始計數(shù)。紅色圓圈是 1-40 回,綠色圓圈是 41-80回,藍色圓圈是 81-120 回。)

八十回以后的內(nèi)容(藍色)大部分都集中在左下角的一條狹長的區(qū)域內(nèi),很明顯地和其他章回區(qū)分開來了!莫非《紅樓夢》的最后 40 回真的不是同一個作者寫的?!

別著急,分析還沒結(jié)束。PCA的一個很重要的優(yōu)點就是,它的分析結(jié)果具有很強的可解釋性,因為我們可以知道每一個原始特征在壓縮后的特征中的權重。從上圖中可以看到,后40回的主要區(qū)別在于成分二(component 2)的數(shù)值。因此我們可以看一看每一個詞的詞頻在成分2中的權重排名(括號內(nèi)為權重):

笑道(0.883)、我們(0.141)、一個(0.133)、你們(0.128)、兩個(0.113)、說著(0.079)、咱們(0.076)、這個(0.063)、聽了(0.052)、還有(0.046)、一面(0.045)、來了(0.037)、都是(0.032)、不過(0.028)、去了(0.027)、又不(0.025)、出去(0.021)、這樣(0.018)、如今(0.016)、這里(0.016)、還不(0.011)、見他(0.011)、出來(0.010)、就是(0.010)、一時(0.008)、起來(0.005)、只見(0.002)、不是(0.002)、下回分解(0.000)、不得(-0.001)、也不(-0.001)、話說(-0.002)、的人(-0.005)、不知(-0.007)、那里(-0.009)、叫他(-0.011)、不敢(-0.011)、自己(-0.011)、不能(-0.017)、什么(-0.019)、所以(-0.020)、只是(-0.023)、知道(-0.026)、進來(-0.036)、說道(-0.046)、怎么(-0.050)、只得(-0.056)、沒有(-0.077)、聽見(-0.092)、寶玉(-0.312)

我發(fā)現(xiàn),“笑道”這個詞不僅是除了人名以外出現(xiàn)次數(shù)最多的單詞,而且在PCA結(jié)果中的權重也異常地高(0.88),甚至超過了“寶玉”的權重的絕對值(0.31)!為了搞明白這個詞為什么有這么大的權重,我把“笑道”的詞頻變化畫了出來:

(圖片說明:圖中橫坐標是章回編號,縱坐標是“笑道”的詞頻)

可以發(fā)現(xiàn),“笑道”的詞頻是先增加再減少的,這不禁讓我聯(lián)想到了賈府興衰的過程。莫非“笑道”的詞頻和賈府的發(fā)展狀況有關?

有趣的是,“笑道”的詞頻頂峰出現(xiàn)在第50回左右,而有些人從劇情的角度分析認為賈府的鼎盛時期開始于第48、49回,恰好重合。

也許“笑道”這一看似平常的詞匯確實側(cè)面反應了賈府的興衰史呢。雖然因果關系有待考證,不過想想也有一點道理,畢竟只有日子過的好的時候人們才會愛笑。

“笑道”這個詞似乎和情節(jié)的關系比較大,并且嚴重影響到了我們的分析。此外,“寶玉”作為一個人名,它的權重的絕對值也比較大,也可能是受到了情節(jié)的影響。因此,我決定把這兩個詞“拉黑”,用剩下的48個詞的詞頻做特征,再次進行PCA分析。

我發(fā)現(xiàn)這樣修改特征之后,后40回確實已經(jīng)不像之前那么聚集了,不過還是可以看出一點聚集的趨勢。這說明之前PCA結(jié)果確實因為“笑道”而受到了劇情的干擾。

而去掉“笑道以后四十回依然有聚集的趨勢,說明去掉干擾后這些章回還是有一定的相似性的。所以,我有點把握認為《紅樓夢》前八十回和后四十回的用詞是有一些差異的。不過因為難以完全排除劇情的影響,所以我也還不敢下定論。

雖然沒有完全解決紅樓夢的作者是不是同一個人的問題,不過這個過程中誤打誤撞產(chǎn)生的發(fā)現(xiàn)也是挺有意思的,比如“笑道”的詞頻變化和賈府興衰史的有趣重合。更重要的是,看似枯燥的數(shù)學公式可以做出這些好玩的分析。

最新動態(tài)
相關文章
逾百位港澳和臺灣青年精英赴北京研修中...
弘揚孝善文化 金堂縣舉行第二屆孝善文化節(jié)
萬子和家族肖像權法律授權委托書
中式名言四天王,除了魯迅莫言白巖松還...
唐代小姐姐們,你們待在墻上挺美,可我...
周總理為我們保護了多少文物古跡?
?