1. 程式人生 > >機器學習基礎——詳解自然語言處理之tf-idf

機器學習基礎——詳解自然語言處理之tf-idf

本文始發於個人公眾號:TechFlow,原創不易,求個關注


今天的文章和大家聊聊文字分析當中的一個簡單但又大名鼎鼎的演算法——TF-idf。說起來這個演算法是自然語言處理領域的重要演算法,但是因為它太有名了,以至於雖然我不是從事NLP領域的,但在面試的時候仍然被問過好幾次,可見這個演算法的重要性。

好在演算法本身並不困難,雖然從名字上看疑惑重重,但是一旦理解了其中的原理,一切都水到渠成,再也不怕面試的時候想不起來了。廢話不多說,我們進入正題。


演算法原理


TF-idf名字的中間用分隔號進行了分割,並且TF和idf都不像是人名,所以它其實是表明了這個演算法是由TF和idf兩個部分構成的。我們先來看TF的部分。


TF的解釋

TF的英文全稱是Term Frequency,Frequency很好理解就是頻次、頻率。而這個Term硬翻譯是項的意思,聯絡上下文,它其實是指的文本當中的單詞或者短語。所以結合起來,Term Frequency就是短語的頻率。其實如果你明白了它的意思,剩下的光憑猜測都可以猜測出一個大概。

它的意思很樸素,就是字面意思,即一個單詞在本文當中的重要性和它出現的頻率有關。

這個觀點很直觀,比如我們在網頁搜尋”TechFlow“,出來的網站當中通篇連一個”TechFlow“都沒有,顯然這次搜尋的質量很差。如果一個網站當中包含的”TechFlow“很多,那說明很有可能搜尋正確,這個網站就是我們想要的。

除此之外,它還可以反映單詞的重要程度。如果在同一個文本當中,一個Term的出現頻率比另一個大,那麼一般情況下,顯然它的重要程度也更大。

據說早期的搜尋引擎就是用的這個策略,它衡量使用者搜尋的關鍵詞在各個網頁文本當中出現的頻率。傾向於將出現頻率高的網頁排在前面,由於排名靠前的網頁能夠獲得大量的流量。所以由於利益的驅動,後來越來越多的網頁傾向於在內容當中嵌入更多的搜尋熱詞,以此來獲得更高的排名和更多的流量。相信大家也都有過類似的體會,當我們使用搜索引擎輸入某個關鍵詞,搜尋出來的網頁號稱有相關的匹配,但是當我們真正點選進去卻什麼也沒有發現,或者是滿屏的廣告。

在早期的網際網路當中存在大量這樣的網頁,它們以囊括更多的搜尋熱詞為生。以此還衍生出了一個技術工種——SEO,即search engine optimization搜尋引擎優化,專門用各種手段來替各大網頁優化搜尋引擎當中的排名。

很快搜索引擎的工程師也都發現了這個問題,也正是為了解決這個問題,才引入了IDF的概念。


IDF的概念


IDF的英文是Inverse Document Frequency,即逆文件頻率。這個概念很難翻譯,也很難直白地解釋,所以往往我們還是使用它的英文縮寫。它表達的意思也很簡單,就是越廣泛存在的Term越不重要,也就是Term的重要性和出現的廣泛性成反比。

舉個例子,最常用的”的“,”了“,”是的“這些單詞肯定廣泛出現在各個文章當中,而像是“搜尋”,“機器學習”這些短語會出現的文章可能就要少得多。顯然對於搜尋引擎或者是一些其他模型而言,這些出現更少的單詞的參考意義更大,因為往往意味著更加精準的導向。所以IDF可以簡單理解成出現廣泛程度的倒數,它的定義也很簡單:

\[\displaystyle idf_i=\log\frac{|D|}{1 + |\{j:t_i \in d_j \}|}\]

其中\(|D|\)是所有文件的數量,\(t_i\)是第i個短語,\(|\{j:t_i \in d_j \}|\)表示包含第i個短語的文件的數量。為了防止它為0,我們為它加上一個常數1。同樣,我們也可以寫出TF的公式:

\[TF(t) = \frac{TF_i}{TN_t}\]

分母的\(TN_t\)表示文章t當中包含的所有Term的數量,分子\(TF_i\)表示\(Term_i\)在文件中的數量。

我們回顧一下這兩個概念可以發現,TF衡量的是短語和文件的關係,而idf衡量的是短語和所有文件的關係。也就是說前者衡量的是短語對於某一個具體文件的重要性,而idf衡量的是短語對於所有文件的重要性。這兩者有點像是區域性和整體的關係,我們將兩者相乘就可以得到一個Term相容兩者最終得到的重要性,也就是說TF-idf是用來計算短語在某個文件中重要性的演算法。

TF-idf的演算法也很簡單,我們直接將TF和idf計算得到的取值相乘即可。

演算法的原理理解了之後,我們可以自己動手寫一個計算TF-idf的演算法,並不複雜,整個過程不超過40行:

class TFIdfCalculator:

    # 初始化方法
    def __init__(self, text=[]):
        # 自定義的文字預處理,包括停用詞過濾和分詞,歸一化等
        self.preprocessor = SimpleTextPreprocessing()
        # 防止使用者只傳了單條文字,做相容處理
        if isinstance(text, list):
            rows = self.preprocessor.preprocess(text)
        else:
            rows = self.preprocessor.preprocess([text])

        self.count_list = []
        # 使用Counter來計算詞頻
        for row in rows:
            self.count_list.append(Counter(row))

    # fit介面,初始化工作
    def fit(self, text):
        self.__init__(text)

    # 計算詞頻,即單詞出現次數除以總詞數
    # 用在初始化之後
    def tf(self, word, count):
        return count[word] / sum(count.values())

    # 計算包含單詞的文字數量
    def num_containing(self, word):
        return sum(1 for count in self.count_list if word in count)

    # 計算idf,即log(文件數除以出現次數+1)
    def idf(self, word):
        return math.log(len(self.count_list) / (1 + self.num_containing(word)))

    # 計算tfidf,即tf*idf
    def tf_idf(self, word, count_id):
        if isinstance(count_id, int) and count_id < len(self.count_list):
            return self.tf(word, self.count_list[count_id]) * self.idf(word)
        else:
            return 0.0

其中SimpleTextPreprocessing是我自己開發的一個進行文字預處理的類,包括分詞、去除停用詞以及詞性歸一化等基本操作。這些內容在之前樸素貝葉斯分類的文章當中曾經提到過,感興趣的同學可以點選下方的連結進行檢視。

機器學習基礎——樸素貝葉斯做文字分類程式碼實戰

我們來實驗一下程式碼:

tfidf = TFIdfCalculator()
tfidf.fit(['go until jurong', 'point craze go', 'cine there got amore', 'cine point until'])
print(tfidf.tf_idf('jurong', 0))
print(tfidf.tf_idf('go', 0))

我們自己建立了一些無意義的文字進行呼叫,我們計算第一條文本當中go和jurong單詞的重要程度。根據TFidf的定義,go出現在了第一條和第二條文本當中,它出現的次數更多,所以它的idf更小,並且兩者在第一條文本當中出現的詞頻一致,所以應該jurong的TFidf更大。

最後的結果也符合我們預期,jurong的TFidf是0.345,而go的TFidf是0.143。


深度思考


TFidf的原理我們都理解了,程式碼也寫出來了,看似圓滿了,但其實有一個關鍵的點被我們忽略了。有一點很奇怪,為什麼我們計算idf的時候需要對擬文字頻率這個值求log呢?雖然從結果上來看求了log之後的結果看起來更加正常,並且分佈也更加合理。但這是結果不是原因,而從原理上來說,這個log出現的原因是什麼呢?

其實在TFidf這個理論出現的早期,並沒有人想過這個問題,可以說是誤打誤撞。後來有大神從夏農資訊理論的角度給與瞭解釋,這一切才完美的自圓其說。

在之前關於交叉熵的推導文章當中,我們曾經討論過,如果存在一個事件A,它包含的資訊量是\(-\log(P(A))\),即它發生概率的對數。也就是說發生概率越小的事件,它的資訊量越大。這個log的出現是有玄機的,資訊理論的本質是將資訊量化。資訊量化的結果是bit,也就是二進位制位。我們都知道一個二進位制位能夠表示0和1兩個數字,代表了2分量的資訊。隨著bit的增多,我們能表示的資訊量也在增大,但是資訊量不是線性增長的,而是指數增長的。

舉個簡單又經典的例子,32支球隊挺近了世界盃,這其中只有一支球隊能夠獲勝。假設最終獲勝的是法國隊、西班牙隊,我們知道訊息的時候並不會驚訝。而如果獲勝的是日本隊,估計所有人會大吃一驚。這背後的原因就和資訊量有關,我們都知道雖然從表面上來看32支球隊是平等的,哪一支都有獲勝的可能,但是實際上各個球隊獲勝的概率是不同的。

假設法國隊、西班牙這種勁旅獲勝的概率是1/4,\(-\log(\frac{1}{4})=2\)那麼我們只需要2個bit就可以表示。假設日本隊獲勝的概率是1/128,那麼我們需要7個bit才能表示,顯然後者的資訊量大得多。

到這裡,大家也就明白了,我們取對數的本質是計算資訊量對應的bit的數量。bit的數量是線性的,資訊量是指數級的,也就是說我們將一個指數級的資訊量轉化成了線性的bit。對於大多數模型而言,線性的特徵更加容易擬合,這也是TFidf效果出色的本質原因。

最後,我們從資訊理論的角度解釋一下idf,假設網際網路世界當中所有的文件有\(2^{30}\)。現在使用者搜尋中美貿易戰,其中包含中國和美國的文件數量都是\(2^{14}\),那麼中國和美國這兩個詞包含的資訊量就是\(\log(\frac{2^{30}}{2^{14}})=16\),而如果包含貿易戰這個詞的文件數量只有\(2^6\),那麼貿易戰這個詞包含的資訊量就是\(\log(\frac{2^{30}}{2^6})=24\),那麼顯然,貿易戰這個詞的資訊量要比中國和美國大得多,那麼它在文件排序當中起到的作用也就應該更大。

如果你能從資訊理論的角度對TFidf的原理進行解釋,而不只是簡單地瞭解原理,那我覺得這個知識點才是真正掌握了,那麼當你在面試當中遇到自然也就能遊刃有餘了。

今天的文章就是這些,如果覺得有所收穫,請順手掃碼點個關注吧,你們的舉手之勞對我來說很重要。

相關推薦

機器學習基礎——自然語言處理tf-idf

本文始發於個人公眾號:TechFlow,原創不易,求個關注 今天的文章和大家聊聊文字分析當中的一個簡單但又大名鼎鼎的演算法——TF-idf。說起來這個演算法是自然語言處理領域的重要演算法,但是因為它太有名了,以至於雖然我不是從事NLP領域的,但在面試的時候仍然被問過好幾次,可見這個演算法的重要性。 好在演算

自然語言處理TF-IDF演算法

假定現在有一篇長文《中國的蜜蜂養殖》,我們準備用計算機提取它的關鍵詞。 一個容易想到的思路,就是找到出現次數最多的詞。如果某個詞很重要,它應該在這篇文章中多次出現。於是,我們進行"詞頻"(Term Frequency,縮寫為TF)統計。 結果你肯定猜到了,出現次數最多的詞是----"的"、"是"、"在"--

[轉]機器學習科普文章:“一文讀懂機器學習,大資料/自然語言處理/演算法全有了”

       在本篇文章中,我將對機器學習做個概要的介紹。本文的目的是能讓即便完全不瞭解機器學習的人也能瞭解機器學習,並且上手相關的實 踐。這篇文件也算是EasyPR開發的番外篇,從這裡開始,必須對機器學習瞭解才能進一步介紹EasyPR的核心。當然,本文也面對一般讀者,不會對

一文讀懂機器學習,大資料/自然語言處理/演算法全有了……

作者注:本文生動形象,深入淺出的方式介紹了機器學習及其它演算法,適合新人和想更加了解機器學習的讀者閱讀,此文屬於轉載,下面連結是原文出處,我們尊重原作者的版權保護。https://www.cnblogs.com/donaldlee2008/p/5224325.html  在本

自然語言處理方法---TF-IDF

最近閒來無事,做了小小的專案,主要工作有: 1、爬取歷年政府工作報告 2、統計詞頻,並計算TF-IDF值 3、視覺化輸出,並分析結果 PS:以上都是基於python實現,需要原始碼請聯絡(其實很簡單。。) 成果如圖所示: 其中,關於計算TF-IDF是自然語言處理(NL

自然語言處理TF-IDF演算法提取關鍵詞

自然語言處理——TF-IDF演算法提取關鍵詞 這個標題看上去好像很複雜,其實我要談的是一個很簡單的問題。 有一篇很長的文章,我要用計算機提取它的關鍵詞(Automatic Keyphrase extraction),完全不加以人工干預,請問怎樣才能正確做到? 這個問

自然語言處理中文分詞器

中文分詞是中文文字處理的一個基礎步驟,也是中文人機自然語言互動的基礎模組,不同於英文的是,中文句子中沒有詞的界限,因此在進行中文自然語言處理時,通常需要先進行分詞,分詞效果將直接影響詞性,句法樹等模組

自然語言處理中文分詞器-jieba分詞器及python實戰

中文分詞是中文文字處理的一個基礎步驟,也是中文人機自然語言互動的基礎模組,在進行中文自然語言處理時,通常需要先進行分詞。本文詳細介紹現在非常流行的且開源的分詞器結巴jieba分詞器,並使用python實

自然語言處理AI深度學習頂級實戰課

自然語言處理之AI深度學習頂級實戰課網盤地址:https://pan.baidu.com/s/1cPqqMpX-xDEMoA3iDscrnw 提取碼: swqh備用地址(騰訊微雲):https://share.weiyun.com/5UGchsv 密碼:pp5ix3 課程大綱:1、NLP和深度學習發展概況和

一文了自然語言處理神經史

摘要:越來越火的NLP到底經歷了什麼?本文擴充套件了HermanKamper和我在2018年深度學習Indaba組織的自然語言處理前沿課程。整個課程的幻燈片都可以在這裡找到,這篇文章將主要討論NLP中基於神經網路方法的近期進展。 免責

CS224n學習筆記1——深度自然語言處理

一、什麼是自然語言處理呢? 自然語言處理是電腦科學家提出的名字,本質上與計算機語言學是同義的,它跨越了計算機學、語言學以及人工智慧學科。 自然語言處理是人工智慧的一個分支,在計算機研究領域中,也有其他的分支,例如計算機視覺、機器人技術、知識表達和推理等。   目標:讓計算機能夠理解人類語言來

13.深度學習(詞嵌入)與自然語言處理--HanLP實現

筆記轉載於GitHub專案:https://github.com/NLP-LOVE/Introduction-NLP 13. 深度學習與自然語言處理 13.1 傳統方法的侷限 前面已經講過了隱馬爾可夫模型、感知機、條件隨機場、樸素貝葉斯模型、支援向量機等傳統機器學習模型,同時,為了將這些機器學習模型應用於 N

機器學習SVM軟間隔與對偶問題

今天是**機器學習專題**的第34篇文章,我們繼續來聊聊SVM模型。 我們在上一篇文章當中推導了SVM模型在硬間隔的原理以及公式,最後我們消去了所有的變數,只剩下了$\alpha$。在硬間隔模型當中,樣本是線性可分的,也就是說-1和1的類別可以找到一個平面將它完美分開。但是在實際當中,這樣的情況幾乎是不

自然語言處理jieba, gensim模塊

src tex tokenize 出現 其中 lambda pip 理論 aid 一,自然語言處理 自然語言處理(NLP) :自然語言處理是計算機科學領域與人工智能領域中的一個重要方向。它研究能實現人與計算機之間用自然語言進行有效通信的各種理論和方法。自然語言處理是一門融

自然語言處理:搭建基於HanLP的開發環境(轉)

環境搭建比FNLP的簡單,具體參考:https://github.com/hankcs/HanLP 各個版本的下載:https://github.com/hankcs/HanLP/releases 完畢後有一個報錯: 字元型別對應表載入失敗: D:/eclipse_workspace

自然語言處理情感分析與觀點挖掘

觀點、情感以及與之相關的許多概念,如評價、評估、態度、感情、情緒和心情,與我們主觀的感覺和感受密切相關。這些是人類心理活動的核心要素,也是影響人們日常行為的關鍵因素。情感分析也稱為觀點挖掘,是一個旨在利用可計算的方法從自然語言文字中提取觀點和情感資訊的研究課題。 一.情感分

自然語言處理分詞、命名主體識別、詞性、語法分析-stanfordcorenlp-NER(二)

轉載請註明出處:https://blog.csdn.net/HHTNAN 在前面我們介紹了Stanford CoreNLP, 自然語言處理之命名實體識別-tanfordcorenlp-NER(一) 功能列表 工具以及對各種語言的支援如下表(英文和中文支援的最好),分別對應:

自然語言處理命名實體識別-tanfordcorenlp-NER(一)

轉載請註明出處:https://blog.csdn.net/HHTNAN 簡介 CoreNLP 專案是Stanford開發的一套開源的NLP系統。包括tokenize, pos , parse 等功能,與SpaCy類似。SpaCy號稱是目前最快的NLP系統, 並且提供現成的pyt

自然語言處理Bag-of-words,TF-IDF模型

轉自:https://blog.csdn.net/m0_37744293/article/details/78881231 Bag-of-words,TF-IDF模型 Bag-of-words model (BoW model)忽略文字的語法和語序,用一組無序的單詞(words)來表達一段文

自然語言處理維特比(Viterbi)演算法

維特比演算法 (Viterbi algorithm) 是機器學習中應用非常廣泛的動態規劃演算法,在求解隱馬爾科夫、條件隨機場的預測以及seq2seq模型概率計算等問題中均用到了該演算法。實際上,維特比演算法不僅是很多自然語言處理的解碼演算法,也是現代數字通訊中使用最頻繁的演