🌻个人主页:相洋同学
🥇学习在于行动、总结和坚持,共勉!
#学习笔记#
目录
[01 TF-IDF算法介绍](#01 TF-IDF算法介绍)
[02 TF-IDF应用](#02 TF-IDF应用)
[03 Sklearn实现TF-IDF算法](#03 Sklearn实现TF-IDF算法)
[04 使用TF-IDF算法提取关键词](#04 使用TF-IDF算法提取关键词)
[05 TF-IDF算法的不足](#05 TF-IDF算法的不足)
TF-IDF算法非常容易理解,并且很容易实现,但其简单结构没有考虑词语的语义信息,无法处理一词多义与一义多词的情况。对于同类文本处理和一些生僻词筛选的效果不理想。
01 TF-IDF算法介绍
TF-IDF(term frequency-inverse doument frequency,词频-逆向文档频率)是一种用于信息检索(information retrieval)与文本挖掘(text mining)的常用加权技术。
TF-IDF是一种统计方法,用以评估一字词对与一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比的增加,但同时会随着它在语料库中出现的频率成反比下降。
TF-IDF的主要思想:如果某个单词在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语有很好的类别区分能力,适合用来分类。
(1)TF是词频(Term Frequency)
词频(TF)表示词条(关键字)在文本中出现的频率。
这个数字通常会被归一化(一般是词频除以文档总词数),防止它偏向长的文件
公式:
其中是该词在文件中出现的次数,分母则是文件中所有词汇出现的次数总和;
(2)IDF是逆向文本频率(Inverse Document Frequency)
逆向文件频率(IDF) :某一特定词语的IDF,可以由总文件数目除以包含该词语的文件的数目,再将得到的上取对数得到。
如果包含词条的t的文档越少,IDF越大,则说明词条具有很好的类别区分能力。
公式:
其中,|D|是语料库中的文件总数。分母表示包含词语的文件数目。如果该词语不在语料库中,就会导致分母为0,因此一般情况加会给分母加1
(3)TF-IDF实际上是:TF*IDF
某一特定文件内的高频词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的TF-IDF。因此,TF-IDF倾向于过滤掉常见的词语,保留重要的词语。
(左边表示连接并非减号)
注:TF-IDF算法非常容易理解,并且很容易实现,但其简单结构没有考虑词语的语义信息,无法处理一词多义与一义多词的情况。
02 TF-IDF应用
(1)搜索引擎
(2)关键词提取
(3)文本相似性
(4)文本摘要
03 Sklearn实现TF-IDF算法
python
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
x_train = ['大模型 是 当今 比较 火热 的 概念','深度学习 火热 现状 的 资源',
'人工智能 领域 最 重要 的 方法']
x_test=['算力 当今 重要 资源','GPU 火热']
#该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频
vectorizer = CountVectorizer(max_features=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('输出x_train文本向量:')
print(x_train_weight)
print('输出x_test文本向量:')
print(x_test_weight)
# 输出:
输出x_train文本向量:
[[0. 0.46735098 0.46735098 0. 0.46735098 0.46735098
0. 0.35543247 0. 0. ]
[0. 0. 0. 0. 0. 0.
0.52863461 0.40204024 0.52863461 0.52863461]
[0.70710678 0. 0. 0.70710678 0. 0.
0. 0. 0. 0. ]]
输出x_test文本向量:
[[0. 0. 0.70710678 0. 0. 0.
0. 0. 0. 0.70710678]
[0. 0. 0. 0. 0. 0.
0. 1. 0. 0. ]]
04 使用TF-IDF算法提取关键词
我们使用sklearn中的TF-IDF方法对新闻文本进行关键词提取分析,并和单纯通过词频来提取关键词的方法进行方法对比
python
from collections import Counter
from sklearn.feature_extraction.text import TfidfVectorizer
import jieba
# 这里省略文本处理的过程
......
filtered_chinese_news_body = []
for content in chinese_news_body:
filtered_content = drop_stopwords_and_tonkenize(content)
filtered_chinese_news_body.append(filtered_content)
print(filtered_chinese_news_body)
# 使用传统方法获取文本词频排行前n的词
def get_cnt_list(text,n=5):
# 统计词频
cnt_list = []
for content in text:
cnt_list.append(Counter(content))
cnt_word_list = []
for cnt in cnt_list:
cnt_word_list.append([word[0] for word in cnt.most_common(n)])
return cnt_word_list
# 使用TF-IDF获取TF-IDF排名前n的词
def get_important_words_tfidf(text_list, n=5): # 获取关键词
'''
如果输入的是文本列表,则返回文本列表中每个文本的关键词
如果是已经分好词的文本列表,先将其转化为文本列表
'''
# 计算TF-IDF
# TfidfVectorizer所接受的对象是列表字符串,我先前已经把正文分词和去停用词了,我还需要
# 把分词后的正文列表转换成列表字符串
if type(text_list[0]) == list :
filtered_news_body_str = []
for content in text_list:
filtered_content_str = ' '.join(content)
filtered_news_body_str.append(filtered_content_str)
text_list = filtered_news_body_str
tfidf_vectorizer = TfidfVectorizer()
tfidf_matrix = tfidf_vectorizer.fit_transform(text_list)
tfidf_matrix.toarray()
feature_names = tfidf_vectorizer.get_feature_names_out()
content_important_words = []
for doc_num, doc in enumerate(tfidf_matrix):
# 将该文档的TF-IDF向量转换为数组,并获取每个词的索引及其TF-IDF值
tfidf_scores = zip(feature_names, doc.toarray()[0])
# 根据TF-IDF值对词进行排序,并获取最重要的前10个词
sorted_words = sorted(tfidf_scores, key=lambda x: x[1], reverse=True)[:n]
important_words = [word[0] for word in sorted_words]
content_important_words.append(important_words)
return content_important_words
cnt_chinese_word_list = get_cnt_list(filtered_chinese_news_body,10)
tfidf_chinese_word_list = get_important_words_tfidf(filtered_chinese_news_body,n=10)
# 最后我们来对比输出一下
print('结果对比:')
for i in range(len(chinese_news_title)):
print(f'新闻标题{i+1}:{chinese_news_title[i]}')
print('count方法提取关键词:', ' '.join(cnt_chinese_word_list[i]))
print('TF-IDF方法提取关键词:', ' '.join(tfidf_chinese_word_list[i]))
print('==========================')
# 输出:
结果对比:
新闻标题1:用好"人工智能+" 赋能产业升级(人民融观察)
count方法提取关键词: 人工智能 大模型 算力 研究 方面 数据 创新 领域 治理 研发
TF-IDF方法提取关键词: 人工智能 大模型 算力 治理 智能 机器人 算法 风险 研究 攻关
==========================
新闻标题2:这个雪季,吉林省冰雪旅游市场异常火热
count方法提取关键词: 冰雪 游客 滑雪 旅游 吉林省 增长 吉林 同比 度假区 接待
TF-IDF方法提取关键词: 冰雪 游客 滑雪 旅游 吉林省 度假区 吉林 北大 接待 长白山
==========================
新闻标题3:中国经济有强劲韧性和巨大潜力
count方法提取关键词: 中国 经济 增长 表示 全球 工作 世界 高质量 政府 目标
TF-IDF方法提取关键词: 中国 经济 增长 表示 全球 工作 高质量 经济体 政府 预期
==========================
新闻标题4:外文出版社回应"龙"应该翻译成Loong还是Dragon
count方法提取关键词: dragon 中国 译文 龙 Chinese 翻译 规范 英文 Loong
TF-IDF方法提取关键词: dragon 译文 chinese 中国 loong 正面 约定俗成 英文 翻译 规范
==========================
新闻标题5:独家|追赶抖音快手,腾讯系多款产品加码短剧
count方法提取关键词: 短剧 腾讯 阅文 视频 内容 平台 抖音 快手 产品 流量
TF-IDF方法提取关键词: 短剧 腾讯 阅文 视频 快手 抖音 平台 ip 流量 内容
==========================
新闻标题6:"超级星期二"基本尘埃落定,特朗普对决拜登,可能性越来越大
count方法提取关键词: 特朗普 选 初选 星期二 拜登 美国 黑莉 对决 可能性 70%
TF-IDF方法提取关键词: 特朗普 初选 拜登 星期二 黑莉 美国 pk 党派 共和党 各州
==========================
新闻标题7:有史以来发现化学元素最多的,是一位诗人
count方法提取关键词: 戴维 发现 法拉第 研究院 诗人 皇家 化学家 化学 气体
TF-IDF方法提取关键词: 戴维 发现 法拉第 皇家 诗人 化学家 气体 研究院 化学 氯气
==========================
新闻标题8:AI引发材料科学变革,有一场"硬仗"无法规避
count方法提取关键词: 数据 模型 材料 集 GNoME 材料科学 化合物 人工智能 Google
TF-IDF方法提取关键词: 数据 模型 材料 gnome 材料科学 化合物 google 人工智能 materials project
==========================
新闻标题9:马斯克痛批"最糟糕的技术",国内氢能源汽车加速崛起
count方法提取关键词: 汽车 氢能源 氢能 燃料电池 氢气 氢 制氢 运输 生产 成本
TF-IDF方法提取关键词: 汽车 氢能 氢能源 燃料电池 氢气 制氢 成本 运输 续航 马斯克
05 TF-IDF算法的不足
- 其简单的结构并不能有效地反映单词的重要程度和特征词的分布情况
- 本质上TF-IDF是一种试图异质噪声的加权,并单纯认为文本频率小的单词就重要,对于大部分的文本信息并不是完全正确,在同类语料库中这一方法就有很大弊端
- 没有考虑特征词位置因素对文本的区分度,词条出现在文档不同位置对区分度的贡献大小不同
- 一些生僻词可能会被误认为文档关键词
更详细的内容和其他实现细节见下面这篇文章:
以上
互联网是最好的课本,实践是最好的老师,AI是最好的学习助手
行动起来,共勉