日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关键词提取算法—TF/IDF算法

發布時間:2024/9/20 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关键词提取算法—TF/IDF算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

關鍵詞提取算法一般可分為有監督學習和無監督學習兩類。
有監督的關鍵詞提取方法可以通過分類的方式進行,通過構建一個較為完善的詞表,然后判斷每個文檔與詞表中的每個詞的匹配程度,以類似打標簽的方式,達到關鍵詞提取的效果。優點是可以獲得較高的精度,缺點是需要大批量的標注數據,并且要對詞表進行人工維護。

無監督學習既不需要詞表也不需要標注語料,也因此無監督的學習得到了大量的應用。

TF-IDF(term frequency–inverse document frequency,詞頻—逆文檔頻次算法)
是一種用于資訊檢索與資訊探勘的常用加權技術,是一種統計方法。常用于評估在一個文檔集中一個詞對某份文檔的重要性,一個詞對文檔越重要越有可能成為關鍵詞。

TF-IDF算法由兩部分組成:TF算法以及IDF算法。TF算法是統計一個詞在一篇文檔中出現的頻次。也即是一個詞在文檔中出現的次數越多,其對文檔的表達能力也越強。而IDF算法則是統計一個詞在文檔集的多少個文檔中出現,即是如果一個詞在越少的文檔中出現,則其對文檔的區分能力也越強。

但TF僅衡量詞的出現頻次,但沒有考慮到詞對文檔的區分能力,所以在實際應用中一般都是將TF和IDF算法一起使用,從詞頻、逆文檔頻次兩個角度對詞的重要性進行衡量。

(1)TF的計算方式:
tfij=nij∑knkjtf_{ij}=\frac {n_{ij}}{\sum_k n_{kj}}tfij?=k?nkj?nij??
在計算公式中,其中nijn_{ij}nij?表示詞iii在文檔中jjj中的出現頻次,但僅是用頻次來表示,長文本中的詞出現頻次高的概率會更大,因此會影響到不同文檔之間關鍵詞權值的比較,所以這里對詞頻進行了歸一化,分母就是統計文檔中每個詞出現次數的總和,也即是一篇文檔中總詞數。

(2)IDF的計算方式:
idfi=log(∣D∣1+∣Di∣)idf_i=log \begin{pmatrix} \frac{|D|}{1+|D_i|} \end{pmatrix}idfi?=log(1+Di?D??)

其中∣D∣|D|D為文檔中文檔總數,∣Di∣|D_i|Di?為文檔集中出現詞iii的文檔數量。分母之所以加1是采用了拉普拉斯平滑,比避免有部分新的詞沒有在語料庫中出現過而使分母為0的情況出現,增強算法的健壯性。

(3)TF—IDF的計算方式:
tf×idf(i,j)=tfij×idfi=nij∑knkj×log(∣D∣1+∣Di∣)tf \times idf(i,j) =tf_{ij} \times idf_i=\frac {n_{ij}}{\sum_k n_{kj}} \times log \begin{pmatrix} \frac{|D|}{1+|D_i|} \end{pmatrix}tf×idf(i,j)=tfij?×idfi?=k?nkj?nij??×log(1+Di?D??)
TF—IDF算法是TF和IDF算法的綜合使用,這里的tftftfidfidfidf相乘是經驗所得。

下面是一個具體的案例:
這里假設已經安裝好了jieba和gensim包,下面是代碼實現:

(1)idf的計算

  • 加載已有的文檔數據集
  • 加載停用表
  • 對數據集中的文檔進行分詞
  • 根據停用詞表過濾掉干擾詞
  • 根據過濾好詞統計計算idf值

(2)新文檔的關鍵詞提取

  • 對新文檔進行分詞
  • 根據停用詞表過濾掉干擾詞
  • 根據計算好的{詞:tf-idf值}得出新文檔的關鍵詞
#!/usr/bin/env python3 # -*- coding: utf-8 -*-import mathimport jieba import jieba.posseg as psg from gensim import corpora, models from jieba import analyse import functools# TF-IDF類 class TfIdf(object):# 四個參數分別是:訓練好的idf字典,默認idf值,處理后的待提取文本,關鍵詞數量def __init__(self, idf_dic, default_idf, word_list, keyword_num):self.word_list = word_listself.idf_dic, self.default_idf = idf_dic, default_idfself.tf_dic = self.get_tf_dic()self.keyword_num = keyword_num# 統計tf值def get_tf_dic(self):tf_dic = {}for word in self.word_list:tf_dic[word] = tf_dic.get(word, 0.0) + 1.0tt_count = len(self.word_list)for k, v in tf_dic.items():tf_dic[k] = float(v) / tt_countreturn tf_dic# 按公式計算tf-idfdef get_tfidf(self):tfidf_dic = {}for word in self.word_list:idf = self.idf_dic.get(word, self.default_idf) # 這里是計算待處理文本的詞的idf(針對文檔集)tf = self.tf_dic.get(word, 0) # 待處理文本的詞頻(針對自身的文檔)tfidf = tf * idftfidf_dic[word] = tfidf#print(tfidf_dic.items())# 根據tf-idf排序,去排名前keyword_num的詞作為關鍵詞for k, v in sorted(tfidf_dic.items(), key=functools.cmp_to_key(cmp), reverse=True)[:self.keyword_num]:print(k + "/ ", end='')# 排序函數,用于topK關鍵詞的按值排序 def cmp(e1, e2):import numpy as npres = np.sign(e1[1] - e2[1])if res != 0:return reselse:a = e1[0] + e2[0]b = e2[0] + e1[0]if a > b:return 1elif a == b:return 0else:return -1 # 停用詞表加載方法 def get_stopword_list():# 停用詞表存儲路徑,每一行為一個詞,按行讀取進行加載# 進行編碼轉換確保匹配準確率stop_word_path = './stopword.txt'stopword_list = [sw.replace('\n', '') for sw in open(stop_word_path).readlines()]return stopword_list# 去除干擾詞 def word_filter(seg_list, pos=False):stopword_list = get_stopword_list()#print('stopword_list:',stopword_list)filter_list = []# 根據POS參數選擇是否詞性過濾 for seg in seg_list:if not pos: # 不進行詞性過濾,則將詞性都標記為n,表示全部保留word = segflag = 'n'else:#print(seg.word,seg.flag)word = seg.word # 詞性標注分詞后的詞flag = seg.flag # 詞性標注分詞后的詞性if not flag.startswith('n'):continue# 過濾停用詞表中的詞,以及長度為<2的詞if not word in stopword_list and len(word) > 1:filter_list.append(word)return filter_list# 分詞方法,調用結巴接口 def seg_to_list(sentence, pos=False):if not pos:# 不進行詞性標注的分詞方法seg_list = jieba.cut(sentence)else:# 進行詞性標注的分詞方法seg_list = psg.cut(sentence)return seg_list# 數據加載,pos為是否詞性標注的參數,corpus_path為數據集路徑 def load_data(pos=False, corpus_path='./corpus.txt'):# 調用上面方式對數據集進行處理,處理后的每條數據僅保留非干擾詞doc_list = []for line in open(corpus_path, 'r'):content = line.strip()seg_list = seg_to_list(content, pos) # 這里對語料進行不標注詞性的分詞filter_list = word_filter(seg_list, pos)doc_list.append(filter_list)return doc_list# idf值統計方法 def train_idf(doc_list):idf_dic = {}# 總文檔數tt_count = len(doc_list)# 每個詞出現的文檔數for doc in doc_list:# 每篇文檔的不重復詞for word in set(doc): idf_dic[word] = idf_dic.get(word, 0.0) + 1.0# 按公式轉換為idf值,分母加1進行平滑處理for k, v in idf_dic.items():idf_dic[k] = math.log(tt_count / (1.0 + v))# 對于沒有在字典中的詞,默認其僅在一個文檔出現,得到默認idf值default_idf = math.log(tt_count / (1.0))return idf_dic, default_idfdef tfidf_extract(word_list, pos=False, keyword_num=10):# 加載已有的文檔數據集,分詞時不標注詞性doc_list = load_data(pos) # IDF值的計算idf_dic, default_idf = train_idf(doc_list)tfidf_model = TfIdf(idf_dic, default_idf, word_list, keyword_num)tfidf_model.get_tfidf()if __name__ == '__main__':text = '6月19日,《2012年度“中國愛心城市”公益活動新聞發布會》在京舉行。' + \'中華社會救助基金會理事長許嘉璐到會講話。基金會高級顧問朱發忠,全國老齡' + \'辦副主任朱勇,民政部社會救助司助理巡視員周萍,中華社會救助基金會副理事長耿志遠,' + \'重慶市民政局巡視員譚明政。晉江市人大常委會主任陳健倩,以及10余個省、市、自治區民政局' + \'領導及四十多家媒體參加了發布會。中華社會救助基金會秘書長時正新介紹本年度“中國愛心城' + \'市”公益活動將以“愛心城市宣傳、孤老關愛救助項目及第二屆中國愛心城市大會”為主要內容,重慶市' + \'、呼和浩特市、長沙市、太原市、蚌埠市、南昌市、汕頭市、滄州市、晉江市及遵化市將會積極參加' + \'這一公益活動。中國雅虎副總編張銀生和鳳凰網城市頻道總監趙耀分別以各自媒體優勢介紹了活動' + \'的宣傳方案。會上,中華社會救助基金會與“第二屆中國愛心城市大會”承辦方晉江市簽約,許嘉璐理' + \'事長接受晉江市參與“百萬孤老關愛行動”向國家重點扶貧地區捐贈的價值400萬元的款物。晉江市人大' + \'常委會主任陳健倩介紹了大會的籌備情況。'pos = Trueseg_list = seg_to_list(text, pos)#for i in seg_list: # 打印輸出進行了詞性標注分詞的結果#print(i) filter_list = word_filter(seg_list, pos)print(filter_list)print('TF-IDF模型結果:')tfidf_extract(filter_list)

運行結果:

['年度', '中國', '愛心', '城市', '公益活動', '新聞', '發布會', '在京舉行', '中華', '社會', '基金會', '理事長', '許嘉璐', '講話', '基金會', '朱發忠', '全國', '老齡', '朱勇', '民政部', '社會', '巡視員', '周萍', '中華', '社會', '基金會', '副理事長', '志遠', '重慶市', '民政局', '巡視員', '明政', '晉江市', '人大常委會', '陳健倩', '自治區', '民政局', '領導', '媒體', '發布會', '中華', '社會', '基金會', '秘書長', '本年度', '中國', '愛心', '城市', '公益活動', '愛心', '城市', '項目', '中國', '愛心', '城市', '大會', '內容', '重慶市', '呼和浩特市', '長沙市', '太原市', '蚌埠市', '南昌市', '汕頭市', '滄州市', '晉江市', '遵化市', '公益活動', '中國', '雅虎', '副總編', '張銀生', '鳳凰網', '城市', '頻道', '總監', '趙耀', '媒體', '優勢', '方案', '中華', '社會', '基金會', '中國', '愛心', '城市', '大會', '承辦方', '晉江市', '許嘉璐', '理事長', '晉江市', '國家', '重點', '地區', '價值', '款物', '晉江市', '人大常委會', '陳健倩', '大會', '情況'] TF-IDF模型結果: 晉江市/ 城市/ 大會/ 愛心/ 中華/ 基金會/ 陳健倩/ 重慶市/ 許嘉璐/ 巡視員/

下面簡單解釋下代碼:
tf-idf算法是需要語料庫的,主要是用來統計計算idf值,通過計算每篇訓練文檔集中每篇文檔中的過濾好的詞在多少篇訓練文檔中出現,然后根據上述的idf計算公式計算其值,也即是訓練過程,這里的所謂的訓練好的模型也就是根據訓練語料庫計算好的過濾后詞的idf值。然后針對待處理文本,遍歷每個詞的tf值,再結合計算好的idf值計算得到tf-idf值,排序得出值最大的前10個詞作為待處理文檔的關鍵詞。

從代碼里還要注意幾點:

  • 待處理文本的分詞采用jieba的帶詞性標注的分詞,而訓練集文檔分詞時采用的是不帶詞性標注的分詞。
  • 要構建一個停用詞表,因為除了能表達文檔信息的實詞外,還有很多無用的詞會干擾詞的tf/idf統計值,因此需要構建一個停用詞表過濾掉所有文檔里的干擾詞。現在中文自然語言處理常用的一個停用詞表是哈工大的停用詞表,里面包含大部分中文文本常用的干擾詞。當然在實際應用中,也可以根據具體的項目構建一個更適用的停用詞表。除了停用詞表外,也可以適用詞性對文本的詞進一步的篩選,在這里對于待處理的文檔篩選的是只保留名詞性的詞語(也即是以“n”開頭的詞),從代碼里可以看出。
  • 訓練文檔集中的文檔在分詞后過濾干擾詞時,保留了所有的詞性的詞,而待處理文檔則是帶詞性標注的分詞后,除了過濾干擾詞外,還過濾掉了除名詞性的詞以外的詞。
  • tf-idf的訓練主要是根據數據集生成對應的idf值字典,后續計算每個詞的tf-idf時,直接從字典中讀取。而LSI和LDA的訓練是根據現有的數據集生成文檔-主題分布矩陣和主題-詞分布矩陣,在gensim中有實現好的訓練方法。
  • 訓練得到idf值,tf值是針對待處理文本的,總和計算tf-idf值進行排序得到關鍵詞。

訓練文檔和停用詞下載:
https://github.com/nlpinaction/learning-nlp/tree/master/chapter-5

總結

以上是生活随笔為你收集整理的关键词提取算法—TF/IDF算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。