赞
踩
最一开始,在学习《Python人工智能:原理、实践及应用》中涉及到了写词频统计,只是对词频进行了统计。但在我们在日常工作中,涉及词频统计,我们往往绕不开TF-IDF,因此对词频-逆文档频率
进行了学习总结,以及日常中你经常会被问到的几个问题。
词频统计是指输入一些字符串(手动输入或者从指定的文件读取),用程序来统计
这些字符串中总共有多少个单词,每个单词出现的次数。单词的总数(即为Total)为不重复的单词数总和。
词频指词的频率,即词在一定的语料中出现的次数。
# Hamlet文档可在https://python123.io/resources/pye/hamlet.txt下载
with open('hamlet.txt', 'r', encoding='utf-8') as fr:
text = fr.read().lower()
# text = text.replace(',', ' ').replace('.', ' ').replace('!', ' ').replace('?', ' ')\
# .replace(';', ' ').replace(':', ' ')
# 去除标点符号
for char in "!'#$%&()*+,-./:;<=>?@[\\\\]^_{|}~":
text = text.replace(char, ' ')
text = text.split()
counts = {}
# 词频统计
for i in text:
counts[i] = counts.get(i, 0) + 1
items = list(counts.items())
# 高频词展示
for i in sorted(items, key=lambda x: x[1], reverse=True)[:10]:
print('{:<6} -> {}'.format(i[0], i[1]))
TF-IDF(Term Frequency–Inverse Document Frequency)
是一种用于信息检索与文本挖掘的常用加权技术。
TF-IDF 是一种统计方法
,用以评估一字词对于一个文档集或一个语料库中的其中一份文档的重要程度。字词的重要性随着它在文档中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。
简单的解释为,一个单词在一个文档中出现次数很多,同时在其他文档中出现此时较少,那么我们认为这个单词对该文档是非常重要的。
TF(Term Frequency,词频),某个词条在文中出现的次数。
词频( T F ) = 某个词在文档中的出现次数 词频(TF)=某个词在文档中的出现次数 词频(TF)=某个词在文档中的出现次数
TF标准化
词频( T F ) = 某个词在文档中出现的次数 / 文档的总词数 词频(TF)=某个词在文档中出现的次数/文档的总词数 词频(TF)=某个词在文档中出现的次数/文档的总词数
IDF(Inverse Document Frequency,逆向文档频率)
逆文档频率( I D F ) = l o g ( 语料库的文档总数 / ( 包含该词的文档数 + 1 ) ) 逆文档频率(IDF)=log(语料库的文档总数/(包含该词的文档数+1)) 逆文档频率(IDF)=log(语料库的文档总数/(包含该词的文档数+1))
如果只用词频来表达一个词对一篇文档的重要程度显然是不合适的,因为在一篇文档里面,可能出现频率很高的词是一些没有意义的词语,真正能代表这篇文档的关键词可能只出很少的次数。(如果有太多文档都涵盖了某个单词,这个单词也就越不重要,或者说是这个单词就越没有信息量
)因此,我们需要对 TF 的值进行修正,而 IDF 的想法是用 DF (文档频率)的倒数
来进行修正。倒数的应用正好表达了这样的思想,DF 值越大越不重要。
使用log可以防止权重爆炸。如果某些词只出现一篇或者少数几篇文档中(比如错别字),在没有log的情况下,IDF就会非常小(分母过小),从而影响其权重,而使用log能减轻这种影响。(平滑)
文档中的停用词(如“的”,“地”,“了”)词频很高,文档集中含停用词的数量约等于总的文档集数量,即 N / n ≃ N/n \simeq N/n≃ 1( N / n N/n N/n恒大于1)。在只使用TF的情况下,停用词所占的权重很大,但是它并没有区分能力,与我们的期望不符。使用IDF之后,由于log(1)=0,则停用词通过TF-IDF计算出的权重就为0(根号达不到这样的效果),就可以消除很多停用词的影响。
利用对数来达到非线性增长的目的,压缩了数据之间的距离,使数据更加平稳,削弱他们之间的差异性。缩小数据的绝对数值,方便计算(缩放)
TF * IDF
的乘积可以提高重要性较高的词的权重,同时降低重要性较低的词的权重,从而更好地区分不同的词语。
文档中的停用词(如“的”,“地”,“了”)词频很高,文档集中含停用词的数量约等于总的文档集数量,即 N / n ≃ N/n \simeq N/n≃ 1( N / n N/n N/n恒大于1)。在只使用TF的情况下,停用词所占的权重很大,但是它并没有区分能力,与我们的期望不符。使用IDF之后,由于log(1)=0,则停用词通过TF-IDF计算出的权重就为0(根号达不到这样的效果),就可以消除很多停用词的影响。
涉及概率,用乘法,简单有效。
优点:易于计算
缺点:
import numpy as np
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer,TfidfTransformer
# 停用词表可在我的资源中免费下载
stop_words = './停用词/en_stopwords.txt'
with open(stop_words, 'r', encoding='utf-8') as fr:
stopwords_list = "".join(fr.readlines()).split()
with open('hamlet.txt', 'r', encoding='utf-8') as fr:
text = fr.read().lower()
for char in "!'#$%&()*+,-./:;<=>?@[\\\\]^_{|}~":
text = text.replace(char, ' ')
# 去除停用词,避免停用词对整个文档词的影响
text = [word for word in text.split() if word not in stopwords_list]
# TfidfVectorizer=TfidfTransformer + CountVectorizer
# fit_transform方法将语料转化成TF-IDF权重矩阵
tfidf_vec = TfidfVectorizer()
tfidf_matrix = tfidf_vec.fit_transform(text)
# 得到语料库所有不重复的词
print(tfidf_vec.get_feature_names())
# 得到每个单词对应的id值
print(tfidf_vec.vocabulary_)
# 得到每个句子所对应的向量,向量里数字的顺序是按照词语的id顺序来的
print(tfidf_matrix.toarray())
# print(tfidf_matrix.todense())
"""
m行n列处值的含义是词汇表中第n个词在第m篇文档的TF-IDF值。提取单篇文档的关键词只需要将矩阵按行的值从大到小排序取前几个即可。如果要提取所有文档的关键词,我们可以将矩阵按列求和,得到每个词汇综合TF-IDF值。
"""
vec_array = tfidf_matrix.toarray().sum(axis=0).tolist()
df = pd.DataFrame(vec_array, index=tfidf_vec.get_feature_names(), columns=['tf-idf'])
# 如果只看TF-IDF分数值,可以直接输出df数据
# 如果进行关键词提取,可按照TF-IDF分数值排序后,取出TOP-N个即可
key_word = df.sort_values(by=['tf-idf'], ascending=False).head()
print(key_word)
以上是我个人在学习过程中的记录所学,希望对正在一起学习的小伙伴有所帮助!!!
如果对你有帮助,希望你能一键三连【关注、点赞、收藏】!!!
https://blog.csdn.net/qq_52181283/article/details/125013666
https://www.cnblogs.com/chenying99/p/4596707.html
https://52opencourse.com/187/idf%E9%80%86%E6%96%87%E6%A1%A3%E9%A2%91%E7%8E%87%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E7%94%A8log
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。