python如何實現TF-IDF算法
概念
1.定義
TF-IDF(term frequency-inverse document frequency)
是一種用于信息檢索與數據挖掘的常用加權技術,常用于挖掘文章中的關鍵詞。
2.特點
簡單高效,用于最開始的文本數據清洗。
3.TF-IDF
(1)TF:詞頻
可以統計到停用詞,并把它們過濾,避免對結果造成影響。
e.g.:“的”、“了”、“是”等等
(2)IDF:逆文檔頻率
在詞的頻率相同時,不同詞的重要性卻不同。IDF會給常見的詞較小的權重。
e.g.:假設“量化”和“系統”的詞頻相同,則重要性:“量化” > “系統”
4.實現方法
當有TF和IDF后,將其相乘,能夠得到一個詞的TF-IDF的值。
某個詞在文章中的TF-IDF越大,那么它在文章中的重要性越高。
算法步驟
1.計算詞頻
詞頻 = 某個詞在文章中出現的次數 / 文章的總次數
2.計算逆文檔的頻率
需要一個語料庫(corpus)來模擬語言的使用環(huán)境。
逆文檔頻率 = log(語料庫的文檔總數 / (包含該詞的文檔數 + 1))
3.計算TF-IDF
TF-IDF= TF × IDF
與一個詞在文檔中出現的次數成正比。
與該詞在整個語言中出現的次數成反比。
優(yōu)缺點
優(yōu)點
簡單高效,容易理解。
缺點
(1)詞頻衡量此的重要性不夠全面,有時重要的詞出現得不多
(2)無法體現位置信息=>無法體現該詞在上下文中的重要性=>用word2vec算法來支持
python實現TF-IDF算法
1.自己構建語料庫
這個例子比較特殊,dataset既是語料庫,可是我們要統計核心詞的對象。
# -*- coding: utf-8 -*-
from collections import defaultdict
import math
import operator
"""
函數說明:創(chuàng)建數據樣本
Returns:
dataset - 實驗樣本切分的詞條
classVec - 類別標簽向量
"""
def loadDataSet():
dataset = [['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'], # 切分的詞條
['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'my'],
['stop', 'posting', 'stupid', 'worthless', 'garbage'],
['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
classVec = [0, 1, 0, 1, 0, 1] # 類別標簽向量,1代表好,0代表不好
return dataset, classVec
"""
函數說明:特征選擇TF-IDF算法
Parameters:
list_words:詞列表
Returns:
dict_feature_select:特征選擇詞字典
"""
#dataset:文件夾,word_list:某一個文件,word某個詞
def feature_select(dataset):
# 總詞頻統計
doc_frequency = defaultdict(int) #記錄每個詞出現的次數,可以把它理解成一個可變長度的list,只要你索引它,它就自動擴列
for file in dataset:
for word in file:
doc_frequency[word] += 1
# 計算每個詞的TF值
word_tf = {} # 存儲沒個詞的tf值
for i in doc_frequency:
word_tf[i] = doc_frequency[i] / sum(doc_frequency.values()) #sum(doc.frequency.values)
# 計算每個詞的IDF值
doc_num = len(dataset)
word_idf = {} # 存儲每個詞的idf值
word_doc = defaultdict(int) # 存儲包含該詞的文檔數
for word in doc_frequency:
for file in dataset:
if word in file:
word_doc[word] += 1
#word_doc和doc_frequency的區(qū)別是word_doc存儲的是包含這個詞的文檔數,即如果一個文檔里有重復出現一個詞則word_doc < doc_frequency
for word in doc_frequency:
word_idf[word] = math.log(doc_num / (word_doc[word] + 1))
# 計算每個詞的TF*IDF的值
word_tf_idf = {}
for word in doc_frequency:
word_tf_idf[word] = word_tf[word] * word_idf[word]
# 對字典按值由大到小排序
dict_feature_select = sorted(word_tf_idf.items(), key=operator.itemgetter(1), reverse=True)
return dict_feature_select
if __name__ == '__main__':
data_list, label_list = loadDataSet() # 加載數據
features = feature_select(data_list) # 所有詞的TF-IDF值
print(features)
運算結果:

2.NLTK實現TF-IDF算法
由于我的電腦安裝了本地代理所以不能下載nltk的語料庫,這里只貼代碼供大家參考
from nltk.text import TextCollection
from nltk.tokenize import word_tokenize
#首先,構建語料庫corpus
sents=['this is sentence one','this is sentence two','this is sentence three']
sents=[word_tokenize(sent) for sent in sents] #對每個句子進行分詞
print(sents) #輸出分詞后的結果
corpus=TextCollection(sents) #構建語料庫
print(corpus) #輸出語料庫
#計算語料庫中"one"的tf值
tf=corpus.tf('one',corpus) # 1/12
print(tf)
#計算語料庫中"one"的idf值
idf=corpus.idf('one') #log(3/1)
print(idf)
#計算語料庫中"one"的tf-idf值
tf_idf=corpus.tf_idf('one',corpus)
print(tf_idf)
3.利用sklearn做tf-idf
import sklearn
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
x_train = ['TF-IDF 主要 思想 是', '算法 一個 重要 特點 可以 脫離 語料庫 背景',
'如果 一個 網頁 被 很多 其他 網頁 鏈接 說明 網頁 重要']
x_test = ['原始 文本 進行 標記', '主要 思想']
# 該類會將文本中的詞語轉換為詞頻矩陣,矩陣元素a[i][j] 表示j詞在i類文本下的詞頻
vectorizer = CountVectorizer(max_features=10) #列數為10
# 該類會統計每個詞語的tf-idf權值
tf_idf_transformer = TfidfTransformer()
# 將文本轉為詞頻矩陣并計算tf-idf
tf_idf = tf_idf_transformer.fit_transform(vectorizer.fit_transform(x_train))
# 將tf-idf矩陣抽取出來,元素a[i][j]表示j詞在i類文本中的tf-idf權重
x_train_weight = tf_idf.toarray()
# 對測試集進行tf-idf權重計算
tf_idf = tf_idf_transformer.transform(vectorizer.transform(x_test))
x_test_weight = tf_idf.toarray() # 測試集TF-IDF權重矩陣
print('vectorizer.fit_transform(x_train) : ')
print(vectorizer.fit_transform(x_train))
print('輸出x_train文本向量:')
print(x_train_weight)
print('輸出x_test文本向量:')
print(x_test_weight)


4.利用Jieba實現tf-idf
import jieba.analyse text='關鍵詞是能夠表達文檔中心內容的詞語,常用于計算機系統標引論文內容特征、 信息檢索、系統匯集以供讀者檢閱。關鍵詞提取是文本挖掘領域的一個分支,是文本檢索、 文檔比較、摘要生成、文檔分類和聚類等文本挖掘研究的基礎性工作' keywords=jieba.analyse.extract_tags(text, topK=5, withWeight=False, allowPOS=()) print(keywords)
注:
jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())
sentence為待提取的文本topK為返回幾個 TF/IDF 權重最大的關鍵詞,默認值為 20withWeight為是否一并返回關鍵詞權重值,默認值為 FalseallowPOS僅包括指定詞性的詞,默認值為空,即不篩選
運行結果:

(安裝不了就pip install jieba; conda install jieba; pip3 install jieba;都嘗試一邊,我用pip3安裝才成功的,如果還不成功可以去jieba官網手動下載后自行配置到anaconda環(huán)境)
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
python3使用logging包,如何把日志寫到系統的rsyslog中
這篇文章主要介紹了python3使用logging包,如何把日志寫到系統的rsyslog中的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09
Python中FastAPI項目使用 Annotated的參數設計的處理方案
FastAPI 是一個非?,F代化和高效的框架,非常適合用于構建高性能的 API,FastAPI 是一個用于構建 API 的現代、快速(高性能)web 框架,基于 Python 類型提示,這篇文章主要介紹了Python中FastAPI項目使用 Annotated的參數設計,需要的朋友可以參考下2024-08-08

