c语言英文分词,英文分词的算法和原理
英文分詞的算法和原理
根據文檔相關性計算公式
分詞質量對于基于詞頻的相關性計算是無比重要的
英文(西方語言)語言的基本單位就是單詞,所以分詞特別容易做,只需要3步:
根據空格/符號/段落 分隔,得到單詞組
過濾,排除掉stop word
提取詞干
第一步:按空格/符號分詞
用正則表達式很容易
pattern = r'''(?x) ? ?# set flag to allow verbose regexps
([A-Z]\.)+ ? ? ? ?# abbreviations, e.g. U.S.A.
| \w+(-\w+)* ? ? ? ?# words with optional internal hyphens
| \$?\d+(\.\d+)?%? ?# currency and percentages, e.g. $12.40, 82%
| \.\.\. ? ? ? ? ? ?# ellipsis
| [][.,;"'?():-_`] ?# these are separate tokens
'''
re.findall(pattern,待分詞文本)
第二步:排除stop word
stopword就是類似a/an/and/are/then?的這類高頻詞,高頻詞會對基于詞頻的算分公式產生極大的干擾,所以需要過濾
第三步:提取詞干
詞干提取(Stemming) 這是西方語言特有的處理,比如說英文單詞有 單數復數的變形,-ing和-ed的變形,但是在計算相關性的時候,應該當做同一個單詞。比如 apple和apples,doing和done是同一個詞,提取詞干的目的就是要合并這些變態
Stemming有3大主流算法
Lucene 英文分詞自帶了3個stemming算法,分別是
EnglishMinimalStemmer
著名的 Porter Stemming
KStemmer
詞干提取算法并不復雜,要么是一堆規則,要么用映射表,編程容易,但是必須是這種語言的專家,了解構詞法才行啊
Lemmatisation
Lemmatisation是和詞干提取(Stemming) 齊名的一個語言學名詞,中文可以叫做?詞形還原?,就是通過查詢字典,把 "drove" 還原到 "drive"
而stemming會把單詞變短,"apples","apple"處理之后都變成了 "appl"
做計算機語言學研究才會涉及到lemmatization,我個人覺得做搜索完全可以不考慮,Stemming已經可以解決大問題了
參考
搜索相關度算法公式: BM25
BM25算法的全稱是 Okapi BM25,是一種二元獨立模型的擴展,也可以用來做搜索的相關度排序。
Sphinx的默認相關性算法就是用的BM25。Lucene4.0之后也可以選擇使用BM25算法(默認是TF-IDF)。如果你使用的solr,只需要修改schema.xml,加入下面這行就可以
BM25也是基于詞頻的算分公式,分詞對它的算分結果也很重要
IDF公式
f(qi,D):就是詞頻
|D|:[給定文檔]D長度。
avgdl:索引中所有文檔長度。
抽象點看,BM25的公式其實和TF-IDF公式大同小異,可以也可以當做 = ∑ idf(q) * fx(tf),
只不過,BM25的idf和tf都做了一些變形,特別是tf公式,還加入了兩個經驗參數k1和b,K1和b用來調整精準度,一般情況下我們取K1=2,b=0.75
至于BM25和TF-IDF 哪種相關性算法更更好,我認為依賴于搜索質量評估標準
參考
Lucene TF-IDF 相關性算分公式
Lucene在進行關鍵詞查詢的時候,默認用TF-IDF算法來計算關鍵詞和文檔的相關性,用這個數據排序
TF:詞頻,IDF:逆向文檔頻率,TF-IDF是一種統計方法,或者被稱為向量空間模型,名字聽起來很復雜,但是它其實只包含了兩個簡單規則
某個詞或短語在一篇文章中出現的次數越多,越相關
整個文檔集合中包含某個詞的文檔數量越少,這個詞越重要
所以一個term的TF-IDF相關性等于 TF * IDF
這兩個規則非常簡單,這就是TF-IDF的核心規則,第二個的規則其實有缺陷的,他單純地認為文本頻率小的單詞就越重要,文本頻率大的單詞就越無 用,顯然這并不是完全正確的。并不能有效地反映單詞的重要程度和特征詞的分布情況,比如說搜索web文檔的時候,處于HTML不同結構的特征詞中對文章內 容的反映程度不同,應該有不同的權重
TF-IDF的優點是算法簡單,運算速度很快
Lucene為了提高可編程行,在上述規則做了一些擴充,就是加入一些編程接口,對不同的查詢做了權重歸一化處理,但是核心公式還是TF * IDF
Lucene算法公式如下
score(q,d) ? = ? coord(q,d) · ?queryNorm(q) · ? ?∑ ? ?( tf(t in d) · ?idf(t)2 · ?t.getBoost() · ?norm(t,d) )
tf(t in d ), ?= frequency?
idf(t)?? = 1 +log(文檔總數/(包含t的文檔數+1))
coord(q,d)?評分因子,。越多的查詢項在一個文檔中,說明些文檔的匹配程序越高,比如說,查詢"A B C",那么同時包含A/B/C3個詞的文檔 是3分,只包含A/B的文檔是2分,coord可以在query中關掉的
queryNorm(q)查詢的標準查詢,使不同查詢之間可以比較
t.getBoost() 和 norm(t,d) 都是提供的可編程接口,可以調整 field/文檔/query項 的權重
各種編程插口顯得很麻煩,可以不使用,所以我們可以把Lucence的算分公式進行簡化
score(q,d) = coord(q,d) · ? ? ?∑ ? ?( tf(t in d) · ?idf(t)2 )
結論
TF-IDF 算法是以 term為基礎的,term就是最小的分詞單元,這說明分詞算法對基于統計的ranking無比重要,如果你對中文用單字切分,那么就會損失所有的語義相關性,這個時候 搜索只是當做一種高效的全文匹配方法
按照規則1?某個詞或短語在一篇文章中出現的次數越多,越相關?一定要去除掉stop word,因為這些詞出現的頻率太高了,也就是TF的值很大,會嚴重干擾算分結果
TF和IDF在生成索引的時候,就會計算出來: TF會和DocID保存在一起(docIDs的一部分),而IDF= 總文檔數 / 當前term擁有的docIDs 長度
http://my.oschina.net/bruceray/blog/493317
總結
以上是生活随笔為你收集整理的c语言英文分词,英文分词的算法和原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 宽带码分多址系统中多径衰落与多址干扰的影
- 下一篇: LATEX 排版问题记录