TF-IDF的原理与实际应用

TF-IDF的原理与实际应用

在这里插入图片描述

一、TF-IDF简介

TF-IDF(term frequency-inverse document frequency) 是一种统计方法,用以评估一个字词对于一个文本集或一个语料库中的其中一份文件的重要程度,是用于信息检索和文本挖掘的常用加权技术。
tf-idf = tf(词频) × idf (逆向文档频率) 利用逆向文档频率来控制约束词频
tf = n / N
n: 词语在某篇文本中出现的频率 ;
n / N 的目的是实现归一化, N :该文件中所有词汇的数目
idf = log(D / d)
D: 总的文档数
d: 词语所在的文档数

在公式中,我们能够发现,总的文档数是固定不变的,词语所在的文档数越少,idf值越大;词语所在的文档数越多,idf值越小。
这样的话,我们总体来看,tf-idf的值会与tf(词语的频率)成正比,但是会随着词语所在的文档数越多而减少。这样,tf-idf就达到了突出重要词语,抑制次要词语的效果

二、TF-IDF的缺陷
单纯的认为频率越小的词越重要;频率越大的词越无用;同时无法体现上下文信息。
三、sklearn中的TF-IDF
https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html?highlight=tfidf#sklearn.feature_extraction.text.TfidfVectorizer

tf = n 没有对tf进行归一化 ,但是对 tf-idf的整个值进行了归一化
idf = log[ ( D + 1 ) / (d + 1) ] + 1 平滑处理保证分母不为0
注: sklearn是一个开源的基于python语言的机器学习工具包。它通过NumPy, SciPy和Matplotlib等python数值计算的库实现高效的算法应用,并且涵盖了几乎所有主流机器学习算法。分类classification、回归 regression、聚类 clustering、降维 dimensionality reduction 、模型选择 model selection 、预处理 preprocessing

四、归一化问题
(一)不归一化

from sklearn.feature_extraction.text import TfidfVectorizer
# 使用之前实例化 tf实例
tv = TfidfVectorizer(use_idf=True, smooth_idf=True, norm=None) # norm=None表示不做归一化处理,默认采用l2的方式 
# 输入训练集矩阵,每行表示一个文本
# train = ["Chinese Beijing Chinese",
#           "Chinese Chinese Shanghai",
#           "Chinese Macao",
#           "Tokyo Japan Chinese"]
train = ["I love nlp nlp",
         "nlp loves me",
         "I love China",
         "China Chinese"]   
# 训练,构建词汇表以及词项idf值,并将输入文本列表转成VSM矩阵形式(向量空间模型)
tv_fit = tv.fit_transform(train)
# 打印构建的词汇表
print(tv.get_feature_names()) 

tv_fit.toarray().tolist() # 将每个词对应的tf-idf值以列表的形式输出  由于没有采用归一化,这样tf-idf的值就不会在0-1之间

在这里插入图片描述
为了验证,我们可以通过公式进行计算:
以词语 nlp 为例,在第一篇文档中出现的次数为2,所有文档中包含nlp的文档数为2

import math
tf = 2
idf = math.log((4+1)/(2+1))+1
print(tf*idf)

在这里插入图片描述
可以看到两者值相等。
(二)以l2的方式归一化
在这里插入图片描述
从sklearn提供的官方文档中,我们可以发现,sklearn默认以l2的方式进行归一化操作;
l2: sum of sqquares of vector elements is 1. 每一行的平方和为1

tv = TfidfVectorizer(use_idf=True, smooth_idf=True,norm = 'l2')#Sum of squares of vector elements is 1 表示 每一行平方和为1
# 输入训练集矩阵,每行表示一个文本
train = ["I love nlp nlp",
         "nlp loves me",
         "I love China",
         "China Chinese"]
# 训练,构建词汇表以及词项idf值,并将输入文本列表转成VSM矩阵形式
tv_fit = tv.fit_transform(train)
# 查看一下构建的词汇表
print(tv.get_feature_names())

# 查看输入文本列表的VSM矩阵
tv_fit.toarray().tolist()

在这里插入图片描述

通过验证:
在这里插入图片描述
(三)以l1的方式归一化
l1:Sum of absolute values of vector elements is 1. 每一行的绝对值之和为1

from sklearn.feature_extraction.text import TfidfVectorizer
# 表示l1归一化的方式为每一行相加之和为1
tv = TfidfVectorizer(use_idf=True, smooth_idf=True,norm = 'l1') # l1 Sum of absolute values of vector elements is 1
# 输入训练集矩阵,每行表示一个文本
train = ["I love nlp nlp",
         "nlp loves me",
         "I love China",
         "China Chinese"]
# train = ["我 爱 自然语言处理",
#         "自然语言处理 也爱 我",
#         "我 是 中国人",
#         "自然语言处理 是一门 课程"]
# 训练,构建词汇表以及词项idf值,并将输入文本列表转成VSM矩阵形式
tv_fit = tv.fit_transform(train)
# 查看一下构建的词汇表
print(tv.get_feature_names())
# 查看输入文本列表的VSM矩阵
tv_fit.toarray().tolist()

在这里插入图片描述
验证:
在这里插入图片描述
(四)传统方式归一化
需要导入TfidfTransformer和CountVectorizer这两个第三方库

from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.preprocessing import Normalizer # sklearn中实现归一化的方法Normalizer
vectorizer = CountVectorizer()  # 实例化 计数文本中出现的单词个数
transformer = TfidfTransformer(norm = None)
# corpus = ["我 来到 中国 旅游", "中国 欢迎 你","我 喜欢 来到 中国 天安门"]
train = ["I love nlp nlp",
         "nlp loves me",
         "I love China",
         "China Chinese"]
norm1 = Normalizer(norm='l1') # 采用l1的方式 相加之和为1
a = vectorizer.fit_transform(train)
print(vectorizer.get_feature_names())
print(a.toarray().tolist())  # 制作频率统计的矩阵之后就可以对矩阵进行归一化

在这里插入图片描述

a = norm1.fit_transform(a)   
print(a.toarray().tolist()) # n/N 1/3  2/3

在这里插入图片描述

result_list2 = transformer.fit_transform(a).toarray().tolist()
word = vectorizer.get_feature_names()
#print(transformer.get_params())
print('词典为:')
print(word)
print('tf-idf值(没有归一化)为:')
for weight in result_list2:
    print(weight)

在这里插入图片描述

import math
tf =2/3
idf = math.log((4+1)/(2+1))+1
tf*idf

在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敷衍zgf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值