天天看點

[python] 使用scikit-learn工具計算文本TF-IDF值

  在文本聚類、文本分類或者比較兩個文檔相似程度過程中,可能會涉及到TF-IDF值的計算。這裡主要講述基于Python的機器學習子產品和開源工具:scikit-learn。

        希望文章對你有所幫助,相關文章如下:

        ​​[python爬蟲] Selenium擷取百度百科旅遊景點的InfoBox消息盒​​

        ​​Python簡單實作基于VSM的餘弦相似度計算​​

        ​​基于VSM的命名實體識别、歧義消解和指代消解​​

        ​​[python] 使用Jieba工具中文分詞及文本聚類概念​​

目錄:

  • 一.Scikit-learn概念
  • 1.概念知識
  • 2.安裝軟體
  • 二.TF-IDF基礎知識
  • 1.TF-IDF
  • 2.舉例介紹
  • 三.TF-IDF調用兩個方法
  • 1.CountVectorizer
  • 2.TfidfTransformer
  • 3.别人示例

一. Scikit-learn概念

        1.概念知識

        官方網址:http://scikit-learn.org/stable/

        Scikit-learn是一個用于資料挖掘和資料分析的簡單且有效的工具,它是基于Python的機器學習子產品,基于BSD開源許可證。

[python] 使用scikit-learn工具計算文本TF-IDF值

        Scikit-learn的基本功能主要被分為六個部分:分類(Classification)、回歸(Regression)、聚類(Clustering)、資料降維(Dimensionality reduction)、模型選擇(Model selection)、資料預處理(Preprocessing)。

        Scikit-Learn中的機器學習模型非常豐富,包括SVM,決策樹,GBDT,KNN等等,可以根據問題的類型選擇合适的模型,具體可以參考官網文檔,推薦大家從官網中下載下傳資源、子產品、文檔進行學習。

[python] 使用scikit-learn工具計算文本TF-IDF值

        Scikit-Learn的安裝需要numpy、scipy、matplotlib等子產品,windows使用者可以到:http://www.lfd.uci.edu/~gohlke/pythonlibs直接下載下傳編譯好的安裝包以及依賴,也可以到這個網站下載下傳:http://sourceforge.jp/projects/sfnet_scikit-learn/。

        參考文章:​​開源機器學習工具scikit-learn入門 - 軒轅森​​

        2.安裝軟體

        Python 2.0我推薦使用"pip install scikit-learn"或"easy_install scikit-learn"全自動安裝,再通過"from sklearn import feature_extraction"導入。

        安裝時如果出現錯誤"unknown encoding: cp65001",輸入"chcp 936"将編碼方式由utf-8變為簡體中文gbk。

[python] 使用scikit-learn工具計算文本TF-IDF值

二. TF-IDF基礎知識

        參考官方文檔:

        gensim中TF-IDF:http://radimrehurek.com/gensim/models/tfidfmodel.html

        1.TF-IDF

        TF-IDF(Term Frequency-InversDocument Frequency)是一種常用于資訊處理和資料挖掘的權重技術。該技術采用一種統計方法,根據字詞的在文本中出現的次數和在整個語料中出現的文檔頻率來計算一個字詞在整個語料中的重要程度。它的優點是能過濾掉一些常見的卻無關緊要本的詞語,同時保留影響整個文本的重要字詞。計算方法如下面公式所示。

[python] 使用scikit-learn工具計算文本TF-IDF值

        其中,式中tfidfi,j表示詞頻tfi,j和倒文本詞頻idfi的乘積。TF-IDF值越大表示該特征詞對這個文本的重要性越大。

        TF(Term Frequency)表示某個關鍵詞在整篇文章中出現的頻率。

        IDF(InversDocument Frequency)表示計算倒文本頻率。文本頻率是指某個關鍵詞在整個語料所有文章中出現的次數。倒文檔頻率又稱為逆文檔頻率,它是文檔頻率的倒數,主要用于降低所有文檔中一些常見卻對文檔影響不大的詞語的作用。

        下面公式是TF詞頻的計算公式。

[python] 使用scikit-learn工具計算文本TF-IDF值

        其中,ni,j為特征詞ti在文本dj中出現的次數,是文本dj中所有特征詞的個數。計算的結果即為某個特征詞的詞頻。

        下面公式是IDF的計算公式。

[python] 使用scikit-learn工具計算文本TF-IDF值

        其中,|D|表示語料中文本的總數,表示文本中包含特征詞ti的數量。為防止該詞語在語料庫中不存在,即分母為0,則使用作為分母。

        2.示例

        示例參考仿造阮一峰大神的例子進行簡單講解,推薦大家去閱讀:

        TF-IDF與餘弦相似性的應用(一):自動提取關鍵詞

        下面通過一個示例進行講解TF-IDF權重計算的方法。

        假設現在有一篇文章《貴州的大資料分析》,這篇文章包含了10000個詞組,其中“貴州”、“大資料”、“分析”各出現100次,“的”出現500次(假設沒有去除停用詞),則通過前面TF詞頻計算公式,可以計算得到三個單詞的詞頻,即:

[python] 使用scikit-learn工具計算文本TF-IDF值

        現在預料庫中共存在 1000 篇文章,其中包含“貴州”的共 99 篇,包含“大資料”的共 19 篇,包含“分析”的共“ 59 ”篇,包含“的”共“ 899 ”篇。則它們的 IDF 計算如下:

[python] 使用scikit-learn工具計算文本TF-IDF值

        由IDF可以發現,當某個詞在語料庫中各個文檔出現的次數越多,它的IDF值越低,當它在所有文檔中都出現時,其IDF計算結果為0,而通常這些出現次數非常多的詞或字為“的”、“我”、“嗎”等,它對文章的權重計算起不到一定的作用。

        同時計算TF-IDF值如下:

[python] 使用scikit-learn工具計算文本TF-IDF值

        通過TF-IDF計算,“大資料”在某篇文章中出現頻率很高,這就能反應這篇文章的主題就是關于“大資料”方向的。如果隻選擇一個詞,“大資料”就是這篇文章的關鍵詞。是以,可以通過TF-IDF方法統計文章的關鍵詞。同時,如果同時計算“貴州”、“大資料”、“分析”的TF-IDF,将這些詞的TF-IDF相加,可以得到整篇文檔的值,用于資訊檢索。

        TF-IDF算法的優點是簡單快速,結果比較符合實際情況。缺點是單純以詞頻衡量一個詞的重要性,不夠全面,有時重要的詞可能出現次數并不多。而且,這種算法無法展現詞的位置資訊。

三. TF-IDF計算

        Scikit-Learn中TF-IDF權重計算方法主要用到兩個類:CountVectorizer和TfidfTransformer。

       1.CountVectorizer

        CountVectorizer類會将文本中的詞語轉換為詞頻矩陣,例如矩陣中包含一個元素a[i][j],它表示j詞在i類文本下的詞頻。它通過fit_transform函數計算各個詞語出現的次數,通過get_feature_names()可擷取詞袋中所有文本的關鍵字,通過toarray()可看到詞頻矩陣的結果。

        代碼如下:

# coding:utf-8
from sklearn.feature_extraction.text import CountVectorizer

#語料
corpus = [
    'This is the first document.',
    'This is the second second document.',
    'And the third one.',
    'Is this the first document?',
]
#将文本中的詞語轉換為詞頻矩陣
vectorizer = CountVectorizer()
#計算個詞語出現的次數
X = vectorizer.fit_transform(corpus)
#擷取詞袋中所有文本關鍵詞
word = vectorizer.get_feature_names()
print word
#檢視詞頻結果
print X.toarray()      

輸出如下所示:

>>> 
[u'and', u'document', u'first', u'is', u'one', u'second', u'the', u'third', u'this']
[[0 1 1 1 0 0 1 0 1]
 [0 1 0 1 0 2 1 0 1]
 [1 0 0 0 1 0 1 1 0]
 [0 1 1 1 0 0 1 0 1]]
>>>      

        從結果中可以看到,總共包括9個特征詞,即:

        [u'and', u'document', u'first', u'is', u'one', u'second', u'the', u'third', u'this']

        同時在輸出每個句子中包含特征詞的個數。例如,第一句“This is the first document.”,它對應的詞頻為[0, 1, 1, 1, 0, 0, 1, 0, 1],假設初始序号從1開始計數,則該詞頻表示存在第2個位置的單詞“document”共1次、第3個位置的單詞“first”共1次、第4個位置的單詞“is”共1次、第9個位置的單詞“this”共1詞。是以,每個句子都會得到一個詞頻向量。

        2.TfidfTransformer

        TfidfTransformer用于統計vectorizer中每個詞語的TF-IDF值。具體用法如下:

# coding:utf-8
from sklearn.feature_extraction.text import CountVectorizer

#語料
corpus = [
    'This is the first document.',
    'This is the second second document.',
    'And the third one.',
    'Is this the first document?',
]
#将文本中的詞語轉換為詞頻矩陣
vectorizer = CountVectorizer()
#計算個詞語出現的次數
X = vectorizer.fit_transform(corpus)
#擷取詞袋中所有文本關鍵詞
word = vectorizer.get_feature_names()
print word
#檢視詞頻結果
print X.toarray()

from sklearn.feature_extraction.text import TfidfTransformer

#類調用
transformer = TfidfTransformer()
print transformer
#将詞頻矩陣X統計成TF-IDF值
tfidf = transformer.fit_transform(X)
#檢視資料結構 tfidf[i][j]表示i類文本中的tf-idf權重
print tfidf.toarray()      

        輸出結果入下所示:

[python] 使用scikit-learn工具計算文本TF-IDF值

        3.别人示例

        如果需要同時進行詞頻統計并計算TF-IDF值,則使用核心代碼:

        vectorizer=CountVectorizer()

        transformer=TfidfTransformer()

        tfidf=transformer.fit_transform(vectorizer.fit_transform(corpus))

        下面給出一個liuxuejiang158大神的例子,供大家學習,推薦大家閱讀原文:

         ​​python scikit-learn計算tf-idf詞語權重 - liuxuejiang​​

# coding:utf-8
__author__ = "liuxuejiang"
import jieba
import jieba.posseg as pseg
import os
import sys
from sklearn import feature_extraction
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer

if __name__ == "__main__":
    corpus=["我 來到 北京 清華大學",#第一類文本切詞後的結果,詞之間以空格隔開
        "他 來到 了 網易 杭研 大廈",#第二類文本的切詞結果
        "小明 碩士 畢業 與 中國 科學院",#第三類文本的切詞結果
        "我 愛 北京 天安門"]#第四類文本的切詞結果
    vectorizer=CountVectorizer()#該類會将文本中的詞語轉換為詞頻矩陣,矩陣元素a[i][j] 表示j詞在i類文本下的詞頻
    transformer=TfidfTransformer()#該類會統計每個詞語的tf-idf權值
    tfidf=transformer.fit_transform(vectorizer.fit_transform(corpus))#第一個fit_transform是計算tf-idf,第二個fit_transform是将文本轉為詞頻矩陣
    word=vectorizer.get_feature_names()#擷取詞袋模型中的所有詞語
    weight=tfidf.toarray()#将tf-idf矩陣抽取出來,元素a[i][j]表示j詞在i類文本中的tf-idf權重
    for i in range(len(weight)):#列印每類文本的tf-idf詞語權重,第一個for周遊所有文本,第二個for便利某一類文本下的詞語權重
        print u"-------這裡輸出第",i,u"類文本的詞語tf-idf權重------"
        for j in range(len(word)):
            print word[j],weight[i][j]
        輸出如下所示: 

-------這裡輸出第 0 類文本的詞語tf-idf權重------           #該類對應的原文本是:"我來到北京清華大學"
中國 0.0
北京 0.52640543361
大廈 0.0
天安門 0.0
小明 0.0
來到 0.52640543361
杭研 0.0
畢業 0.0
清華大學 0.66767854461
碩士 0.0
科學院 0.0
網易 0.0
-------這裡輸出第 1 類文本的詞語tf-idf權重------           #該類對應的原文本是: "他來到了網易杭研大廈"
中國 0.0
北京 0.0
大廈 0.525472749264
天安門 0.0
小明 0.0
來到 0.414288751166
杭研 0.525472749264
畢業 0.0
清華大學 0.0
碩士 0.0
科學院 0.0
網易 0.525472749264
-------這裡輸出第 2 類文本的詞語tf-idf權重------           #該類對應的原文本是: "小明碩士畢業于中國科學院“
中國 0.4472135955
北京 0.0
大廈 0.0
天安門 0.0
小明 0.4472135955
來到 0.0
杭研 0.0
畢業 0.4472135955
清華大學 0.0
碩士 0.4472135955
科學院 0.4472135955
網易 0.0
-------這裡輸出第 3 類文本的詞語tf-idf權重------            #該類對應的原文本是: "我愛北京天安門"
中國 0.0
北京 0.61913029649
大廈 0.0
天安門 0.78528827571
小明 0.0
來到 0.0
杭研 0.0
畢業 0.0
清華大學 0.0
碩士 0.0
科學院 0.0
網易 0.0      

        推薦幾篇機器學習和NLP領域的大神部落格: 

        ​​應用scikit-learn做文本分類 - Rachel-Zhang​​

        ​​python scikit-learn計算tf-idf詞語權重 - liuxuejiang​​

        ​​用Python開始機器學習(5:文本特征抽取與向量化)(強推)- lsldd​​

        ​​再談word2vec - Felven (強推)​​

        ​​利用word2vec對關鍵詞進行聚類 - Felven (強推)​​

        ​​Python 對文檔内容TFIDF處理​​

        Python TF-IDF計算100份文檔關鍵詞權重 - chenbjin

[python] 使用scikit-learn工具計算文本TF-IDF值
[python] 使用scikit-learn工具計算文本TF-IDF值

[python] 使用scikit-learn工具計算文本TF-IDF值

[python] 使用scikit-learn工具計算文本TF-IDF值
[python] 使用scikit-learn工具計算文本TF-IDF值
[python] 使用scikit-learn工具計算文本TF-IDF值

[python] 使用scikit-learn工具計算文本TF-IDF值
[python] 使用scikit-learn工具計算文本TF-IDF值
[python] 使用scikit-learn工具計算文本TF-IDF值

# coding:utf-8
from sklearn.feature_extraction.text import CountVectorizer

#語料
corpus = [
    'This is the first document.',
    'This is the second second document.',
    'And the third one.',
    'Is this the first document?',
]
#将文本中的詞語轉換為詞頻矩陣
vectorizer = CountVectorizer()
#計算個詞語出現的次數
X = vectorizer.fit_transform(corpus)
#擷取詞袋中所有文本關鍵詞
word = vectorizer.get_feature_names()
print word
#檢視詞頻結果
print X.toarray()      
>>> 
[u'and', u'document', u'first', u'is', u'one', u'second', u'the', u'third', u'this']
[[0 1 1 1 0 0 1 0 1]
 [0 1 0 1 0 2 1 0 1]
 [1 0 0 0 1 0 1 1 0]
 [0 1 1 1 0 0 1 0 1]]
>>>      

# coding:utf-8
from sklearn.feature_extraction.text import CountVectorizer

#語料
corpus = [
    'This is the first document.',
    'This is the second second document.',
    'And the third one.',
    'Is this the first document?',
]
#将文本中的詞語轉換為詞頻矩陣
vectorizer = CountVectorizer()
#計算個詞語出現的次數
X = vectorizer.fit_transform(corpus)
#擷取詞袋中所有文本關鍵詞
word = vectorizer.get_feature_names()
print word
#檢視詞頻結果
print X.toarray()

from sklearn.feature_extraction.text import TfidfTransformer

#類調用
transformer = TfidfTransformer()
print transformer
#将詞頻矩陣X統計成TF-IDF值
tfidf = transformer.fit_transform(X)
#檢視資料結構 tfidf[i][j]表示i類文本中的tf-idf權重
print tfidf.toarray()      
[python] 使用scikit-learn工具計算文本TF-IDF值

# coding:utf-8
__author__ = "liuxuejiang"
import jieba
import jieba.posseg as pseg
import os
import sys
from sklearn import feature_extraction
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer

if __name__ == "__main__":
    corpus=["我 來到 北京 清華大學",#第一類文本切詞後的結果,詞之間以空格隔開
        "他 來到 了 網易 杭研 大廈",#第二類文本的切詞結果
        "小明 碩士 畢業 與 中國 科學院",#第三類文本的切詞結果
        "我 愛 北京 天安門"]#第四類文本的切詞結果
    vectorizer=CountVectorizer()#該類會将文本中的詞語轉換為詞頻矩陣,矩陣元素a[i][j] 表示j詞在i類文本下的詞頻
    transformer=TfidfTransformer()#該類會統計每個詞語的tf-idf權值
    tfidf=transformer.fit_transform(vectorizer.fit_transform(corpus))#第一個fit_transform是計算tf-idf,第二個fit_transform是将文本轉為詞頻矩陣
    word=vectorizer.get_feature_names()#擷取詞袋模型中的所有詞語
    weight=tfidf.toarray()#将tf-idf矩陣抽取出來,元素a[i][j]表示j詞在i類文本中的tf-idf權重
    for i in range(len(weight)):#列印每類文本的tf-idf詞語權重,第一個for周遊所有文本,第二個for便利某一類文本下的詞語權重
        print u"-------這裡輸出第",i,u"類文本的詞語tf-idf權重------"
        for j in range(len(word)):
            print word[j],weight[i][j]
        輸出如下所示: 

-------這裡輸出第 0 類文本的詞語tf-idf權重------           #該類對應的原文本是:"我來到北京清華大學"
中國 0.0
北京 0.52640543361
大廈 0.0
天安門 0.0
小明 0.0
來到 0.52640543361
杭研 0.0
畢業 0.0
清華大學 0.66767854461
碩士 0.0
科學院 0.0
網易 0.0
-------這裡輸出第 1 類文本的詞語tf-idf權重------           #該類對應的原文本是: "他來到了網易杭研大廈"
中國 0.0
北京 0.0
大廈 0.525472749264
天安門 0.0
小明 0.0
來到 0.414288751166
杭研 0.525472749264
畢業 0.0
清華大學 0.0
碩士 0.0
科學院 0.0
網易 0.525472749264
-------這裡輸出第 2 類文本的詞語tf-idf權重------           #該類對應的原文本是: "小明碩士畢業于中國科學院“
中國 0.4472135955
北京 0.0
大廈 0.0
天安門 0.0
小明 0.4472135955
來到 0.0
杭研 0.0
畢業 0.4472135955
清華大學 0.0
碩士 0.4472135955
科學院 0.4472135955
網易 0.0
-------這裡輸出第 3 類文本的詞語tf-idf權重------            #該類對應的原文本是: "我愛北京天安門"
中國 0.0
北京 0.61913029649
大廈 0.0
天安門 0.78528827571
小明 0.0
來到 0.0
杭研 0.0
畢業 0.0
清華大學 0.0
碩士 0.0
科學院 0.0
網易 0.0