這幾天在研究如何用統計方法來發現新詞,擴充自己的詞典。看到了幾篇很有想法的文章,作者闡述了一下思路。文章里面的數據,我計算了一下,發現文有很多數據不夠嚴謹,最主要的問題,並沒有給出很詳細的理論方面的說明。結合作者的思路,我進行了如下數學模型的構建和算法的實現。
一、概念介紹
1、詞語分片
設一個文檔集 。其中,
為一個文本,
。
設 為文檔
的分片集合。其中,
為文檔的一個詞語分片,分片就是按step步長對文檔進行分割的詞語單位。這里說的詞語分片可以是一個字、一個詞或者一個長詞。
譬如:中國隊,
按step=1進行切分 S={中,國,隊}
按step=2進行切分 S={中,國,隊,中國,國隊}
按step=3進行切分 S={中,國,隊,中國,國隊,中國隊}。
當然,這個定義可以推廣到有字典的情況:
譬如 字典 {中國}
"中國國家隊"的詞語分片為{中國,國,家,隊,中國國,國家,家隊,中國國家,國家隊,中國國家隊}。
這樣來看,一個文本分若干段落;一個段落通過標點符號進行分割,分割成若干短句,我們成為語義單元;一個語義單元按step步長進行切分成若干個詞語切片。我們把所有切片合並成一個大集合
。
2、分片屬性
為了解決上面的問題,對於分片S我們從分片概率、分片頻度、自由度、凝固程度等屬性去考慮。這些屬性都是概率變量。
這樣,一個分片s用6個屬性去進行描述
參數說明
f: 文檔唯一標識
w: 分片的頻度,表示分片在一種切分過程中出現的次數
s: 分片
co: 分片的凝固度
fr: 分片的自由度
st: 分片的概率
3、詞語分片的概率
分片的概率,如果一個字串S長度為L,按stepN進行切分,切分出來的集合為M,為每個分片的頻度。那么每一個分片的概率可以用下面公式表示:
----------------------------------------------------------(1)
S="中國國家的中國隊",長度N = 8 按step=2進行切分,切分為
M={中,國,家,的,隊,中國,國國,國家,家的,的中,國隊}。
分片 |
中 |
國 |
家 |
的 |
隊 |
中國 |
國國 |
國家 |
家的 |
的中 |
國隊 |
總計 |
頻次 |
2 |
3 |
1 |
1 |
1 |
2 |
1 |
1 |
1 |
1 |
1 |
15 |
P |
2/15 |
3/15 |
1/15 |
1/15 |
1/15 |
2/15 |
1/15 |
1/15 |
1/15 |
1/15 |
1/15 |
100% |
4、分片的凝固度
要想從一段文本中抽出詞來,我們的第一個問題就是,怎樣的文本片段才算一個詞?大家想到的第一個標准或許是,看這個文本片段出現的次數是否足夠多。我們可以把所有出現頻數超過某個閾值的片段提取出來,作為該語料中的詞匯輸出。不過,光是出現頻數高還不夠,一個經常出現的文本片段有可能不是一個詞,而是多個詞構成的詞組。通過我們的數據分析,"的電影"出現了 389 次,"電影院"只出現了 175 次,然而我們卻更傾向於把"電影院"當作一個詞,因為直覺上看,"電影"和"院"凝固得更緊一些。
為了描述這個屬性,我們用一下公式:
---------------------------------(2)
為分片的概率,
分片對應的子分片的概率。
分片"電影院"的概率P(電影院)=0.0005 電影院對應的子分片 {電影,院} 和{電,影院},
"的電影"的凝合程度則是 p(的電影) 分別除以 p(的) · p(電影) 和 p(的電) · p(影) 所得的商的較小值。
光看文本片段內部的凝合程度還不夠,我們還需要從整體來看它在外部的表現。考慮"被子"和"輩子"這兩個片段。我們可以說"買被子"、"蓋被子"、"進被子"、"好被子"、"這被子"等等,在"被子"前面加各種字;但"輩子"的用法卻非常固定,除了"一輩子"、"這輩子"、"上輩子"、"下輩子",基本上"輩子"前面不能加別的字了。"輩子"這個文本片段左邊可以出現的字太有限,以至於直覺上我們可能會認為,"輩子"並不單獨成詞,真正成詞的其實是"一輩子"、"這輩子"之類的整體。可見,文本片段的自由運用程度也是判斷它是否成詞的重要標准。如果一個文本片段能夠算作一個詞的話,它應該能夠靈活地出現在各種不同的環境中,具有非常豐富的左鄰字集合和右鄰字集合。
二、信息熵和自由度
"信息熵"是一個非常神奇的概念,它能夠反映知道一個事件的結果后平均會給你帶來多大的信息量。如果某個結果的發生概率為 p ,當你知道它確實發生了,你得到的信息量就被定義為 - log(p) 。 p 越小,你得到的信息量就越大。
設U1…Ui…Un,對應概率為:P1…Pi…Pn,且各種符號的出現彼此獨立。這時,信源的平均不確定性應當為單個符號不確定性-logPi的統計平均值(E),可稱為信息熵,即
----------------------------------------------(3)
式中對數一般取2為底,單位為比特。
我們用信息熵來衡量一個文本片段的左鄰字集合和右鄰字集合有多隨機。考慮這么一句話"吃葡萄不吐葡萄皮不吃葡萄倒吐葡萄皮","葡萄"一詞出現了四次,其中左鄰字分別為 {吃, 吐, 吃, 吐} ,右鄰字分別為 {不, 皮, 倒, 皮} 。根據公式,"葡萄"一詞的左鄰字的信息熵為 - (1/2) · log(1/2) - (1/2) · log(1/2) ≈ 0.693 ,它的右鄰字的信息熵則為 - (1/2) · log(1/2) - (1/4) · log(1/4) - (1/4) · log(1/4) ≈ 1.04 。可見,在這個句子中,"葡萄"一詞的右鄰字更加豐富一些。
我們不妨就把一個文本片段的自由運用程度定義為它的左鄰字信息熵和右鄰字信息熵中的較小值。
------------------------------------------(4)
通過信息熵算法,可以很好的區分一些專有名詞像玫瑰、蝙蝠等,一些地名像新西蘭、倫敦等,這些自由度較低的詞匯的。
三、算法的構建
在實際運用中你會發現,文本片段的凝固程度和自由程度,兩種判斷標准缺一不可。只看凝固程度的話,程序會找出"巧克"、"俄羅"、"顏六色"、"柴可夫"等實際上是"半個詞"的片段;只看自由程度的話,程序則會把"吃了一頓"、"看了一遍"、"睡了一晚"、"去了一趟"中的"了一"提取出來,因為它的左右鄰字都太豐富了。
無詞典分詞法的基本步驟:
1. 輸入閥值參數 出現頻數w、凝固程度co、自由程度fr和最大切片stepN,詞典集合的大小N;
2. 對文檔集進行預處理,包括:編碼轉換、全半角 處理、字符轉換,再將停用詞、英文字母、數學運算符等其它非漢字字符用占位符替代;
3. 從文檔集里取一個文檔D,按1,2,...,stepN進行切片形成切片集合S;
4. 通過公式(1)計算切片集合S的每一個切片的頻數W和概率P,通過給定頻數閥值過濾;
5. 結果4 中的長度>1的詞語切片,通過公式(2)計算凝固程度,並通過給定的閥值參數過濾。
6. 結果5 中的詞語切片,通過公式(3)計算左鄰右鄰的信息熵,通過公式(4),得出詞語切片的自由度,並通過給定的閥值參數過濾。
7. 對於結果6,按照分片的頻數倒排序,取前N個,就產生了我們需要的詞典。
四、參考
《基於SNS的文本數據挖掘》http://www.matrix67.com/blog/archives/5044