文檔和單詞 Documents and Words
即將構造的分類器須要利用某些特征來對不同的內容項進行分類。
所謂特征,是指任何可以用來判斷內容中具備或缺失的東西。
當考慮對文檔進行分類時,所謂的內容即是文檔,而特征則是文檔中的單詞。當將單詞作為特征時,其假設是:某些單詞相對而言更有可能會出現于垃圾信息中。這一假設是大多數垃圾信息過濾器背后所依賴的基本前提。不過,特征未必一定是一個個單詞;它們也可以是詞組或短語,或者任何可以歸為文檔中缺失或存在的其他東西。
請新建一個文件,取名docclass.py,并在其中加入一個名為getwords的函數,以從文本中提取特征:
import re
import math
def getwords(doc):
splitter=re.compile('\\W*')
# 根據非字母字符進行單詞拆分
words=[s.lower() for s in splitter.split(doc)
if len(s)>2 and len(s)<20]
# 只返回一組不重復的單詞
return dict([(w,1) for w in words])
該函數以任何非字母類字符為分隔符對文本進行劃分,將文本拆分成了一個個單詞。這一過程只留下了真正的單詞,并將這些單詞全都轉換成了小寫形式。
決定采用哪些特征頗具技巧性,也十分重要。特征必須具備足夠的普遍性,即時常出現,但又不能普遍到每一篇文檔里都能找到。
理論上,整篇文檔的文本都可以作為特征,但是除非我們一再收到內容完全相同的郵件,否則這樣的特征幾乎肯定是毫無價值的。在另一種極端情況下,特征也可以是單個字符。但是由于每一封電子郵件中都有可能會出現所有這些字符,因此要想利用這樣的特征將希望看到和不希望看到的文檔區分開來是很困難的。即便選擇使用單詞作為特征,也依然還是會帶來一些問題,包括如何正確劃分單詞,哪些標點符號應該被納入單詞,以及是否應該包含頭信息(header information)等。
在根據特征進行判斷時還有一點須要考慮,那就是如何才能更好地利用特征將一組文檔劃歸到目標分類中去。例如,前述getwords函數的代碼通過將單詞轉換為小寫形式,從而減少了特征的總數。這意味著,程序會將位于句首以大寫字母開頭的單詞與位于句中全小寫形式的單詞視為相同--這樣做非常好,因為具有不同大小寫形式的同一單詞往往代表的含義是相同的。
然而,上述函數完全沒有考慮到被用于許多垃圾信息中的"SHOUTING風格"(譯注1),而這一點可能對區分垃圾郵件和非垃圾郵件是至關重要的。除此以外,如果超過半數以上的單詞都是大寫時,那就說明必定會有其他的特征存在。
正如你所看到的,在選擇特征集時須要做大量的權衡,而且還要不斷地進行調整。不過眼下,可以暫且使用這個簡單的getwords函數;在本章的后續部分,我們還將了解到有關特征提取的一些改進方法。