獲得詞文檔矩陣每每都是文本挖掘算法的第一步,詞文檔矩陣中行表示語料庫中出現過的詞(實際代碼都是對詞進行整數編碼),列表示全部的文檔,矩陣中的每一個值就表明詞在文檔中的重要程度。目前已經有不少計算詞在文檔中權重的模型,不過最通用的模型應該就是 詞頻-逆文檔頻率(簡稱:TF-IDF) 矩陣。算法
先看一下TF-IDF如何計算每一個詞在文檔中的重要程度,先假設獲得了下面幾個變量的值:數據庫
利用上面的幾個值就能夠計算一個詞在文檔中的重要程度,代碼以下:編程
def termDocWeight(termFrequencyInDoc: Int, totalTermsInDoc: Int, termFreqInCorpus: Int, totalDocs: Int): Double = { val tf = termFrequencyInDoc.toDouble / totalTermsInDoc val docFreq = totalDocs.toDouble / termFreqInCorpus val idf = math.log(docFreq) tf * idf }
直觀理解,TF-IDF考慮了以下兩個方面:分佈式
可是有個問題,首先詞頻是近似服從指數分佈,一些通用詞出現的次數多是低頻詞幾十或者幾百倍,直接採用文檔頻率取逆會致使稀缺詞得到一個巨大的權重,實際上就會忽略其餘詞的影響,這樣顯然不妥,爲了去掉這個影響,算法採用對文檔頻率取逆以後再取對數,這樣就把乘法差別轉化爲加法差別。使得稀缺詞權重下降了。編碼
這個算法本質仍是詞袋模型,它沒有考慮詞與詞之間的順序、語法結構以及語義。經過對每一個不一樣的詞計數,這個模型很難區別一詞多義、以及同義詞。實際編程中每每每篇文檔表示爲行向量,每一個元素表明詞對應的索引位置,這樣能夠適應語料庫中文檔變的愈來愈多,一般狀況下,語料庫文檔的增長速度確定大過詞的增加速度。並且這樣的行向量也是稀疏表示,節省空間。scala
TF-IDF原理很是簡單,實際工做中仍是有不少須要注意的地方,下面就用 Spark 實戰的方式講解如何將一個語料庫轉爲 TF-IDF 矩陣,首先給出具體的步驟:code
數據清洗、停詞庫每一個項目都會有不一樣的要求,可是分詞、詞編碼、文檔編碼等工做仍是比較通用的,下面會對通用技術經過 Spark 實戰詳細講解(尤爲是分佈式編程須要注意的地方:)orm
分佈式文本分詞注意兩個地方:索引
val documents: RDD[Seq[String]] = sc.textFile("your_data_dir").map(_.split(" ").toSeq) val hashingTF = new HashingTF() val tf: RDD[Vector] = hashingTF.transform(documents) tf.cache() //沒有在兩個文檔中出現過的詞語不要 val idf = new IDF(minDocFreq = 2).fit(tf) val tfidf: RDD[Vector] = idf.transform(tf)