TF-IDF(Term Frequency-Inverse Document Frequency),是用来衡量一个词在文档中的重要性,下面看一下TDF-IDF的公式:

首先是TF,也就是词频,用来衡量一个词在文档中出现频率的指标。假设某词在文档中出现了( n )次,而文档总共包含( N )个词,则该词的TF定义为:

注意:(t,d)中的t表示的是文档中的词汇,d表示的是文档的词汇集合,通过计算TF也就是进行词频率的统计,好的,那么看一下代码的实现。

def compute_tf(word_dict, doc_words):
""" :param word_dict: 字符的统计个数
:param doc_words: 文档中的字符集合
:return:
"""
tf_dict = {}
words_len = len(doc_words)
for word_i, count_i in word_dict.items():
tf_dict[word_i] = count_i / words_len
return tf_dict # 示例文档
doc1 = "this is a sample"
doc2 = "this is another example example example"
doc3 = "this is a different example example" # 分割单词
doc1_words = doc1.split()
doc2_words = doc2.split()
doc3_words = doc3.split() # 计算每个文档的词频
word_dict1 = Counter(doc1_words)
word_dict2 = Counter(doc2_words)
word_dict3 = Counter(doc3_words) # 计算TF
tf1 = compute_tf(word_dict1, doc1_words)
tf2 = compute_tf(word_dict2, doc2_words)
tf3 = compute_tf(word_dict3, doc3_words) print(f'tf1:{tf1}')
print(f'tf2:{tf2}')
print(f'tf3:{tf3}') # tf1:{'this': 0.25, 'is': 0.25, 'a': 0.25, 'sample': 0.25}
# tf2:{'this': 0.16666666666666666, 'is': 0.16666666666666666, 'another': 0.16666666666666666, 'example': 0.5}
# tf3:{'this': 0.16666666666666666, 'is': 0.16666666666666666, 'a': 0.16666666666666666, 'different': 0.16666666666666666, 'example': 0.3333333333333333}

看完TF的计算之后,我们看一下IDF的定义,公式和对应的实现吧,IDF的定义是:即逆文档频率,反映了词的稀有程度,IDF越高,说明词越稀有。这个逆文档频率也就是说一个词的文档集合中出现的次数越少,他就越具有表征型,因为在文中有很多“的”,“了”这种词,这些词重要性不大,反而出现少的词重要性大一点,来看一下IDF的公式:

其中,( D )是文档总数,( df_t )是包含词( t )的文档数量。通过取对数,可以避免数值过大的问题,同时保证了IDF的单调递减特性,下面看一下代码的现实:

def compute_idf(doc_list):
""" :param doc_list: 文档的集合
:return:
""" sum_list = list(set([word_i for doc_i in doc_list for word_i in doc_i])) idf_dict = {word_i: 0 for word_i in sum_list} for word_j in sum_list:
for doc_j in doc_list:
if word_j in doc_j:
idf_dict[word_j] += 1
return {k: math.log(len(doc_list) / (v + 1)) for k, v in idf_dict.items()} # 示例文档
doc1 = "this is a sample"
doc2 = "this is another example example example"
doc3 = "this is a different example example" # 分割单词
doc1_words = doc1.split()
doc2_words = doc2.split()
doc3_words = doc3.split() # 计算每个文档的词频
word_dict1 = Counter(doc1_words)
word_dict2 = Counter(doc2_words)
word_dict3 = Counter(doc3_words) # 计算整个文档集合的IDF
idf = compute_idf([doc1_words, doc2_words, doc3_words])
# idf:{'different': 0.4054651081081644, 'another': 0.4054651081081644, 'a': 0.0, 'example': 0.0, 'this': -0.2876820724517809, 'sample': 0.4054651081081644, 'is': -0.2876820724517809}

通过结果可以发现,different、another和sample都比is、a等词汇的IDF值要高,代表越重要。

好的,最后看一下TF-IDF的公式吧,

$$TF-IDF=TF*IDF  $$

TF-IDF 就是TF*IDF,来综合的评价一个词在文档中的重要性。

最后看一下完整的代码,

import math
from collections import Counter
import math def compute_tfidf(tf_dict, idf_dict):
tfidf = {}
for word, tf_value in tf_dict.items():
tfidf[word] = tf_value * idf_dict[word]
return tfidf def compute_tf(word_dict, doc_words):
""" :param word_dict: 字符的统计个数
:param doc_words: 文档中的字符集合
:return:
"""
tf_dict = {}
words_len = len(doc_words)
for word_i, count_i in word_dict.items():
tf_dict[word_i] = count_i / words_len
return tf_dict def compute_idf(doc_list):
""" :param doc_list: 文档的集合
:return:
""" sum_list = list(set([word_i for doc_i in doc_list for word_i in doc_i])) idf_dict = {word_i: 0 for word_i in sum_list} for word_j in sum_list:
for doc_j in doc_list:
if word_j in doc_j:
idf_dict[word_j] += 1
return {k: math.log(len(doc_list) / (v + 1)) for k, v in idf_dict.items()} # 示例文档
doc1 = "this is a sample"
doc2 = "this is another example example example"
doc3 = "this is a different example example" # 分割单词
doc1_words = doc1.split()
doc2_words = doc2.split()
doc3_words = doc3.split() # 计算每个文档的词频
word_dict1 = Counter(doc1_words)
word_dict2 = Counter(doc2_words)
word_dict3 = Counter(doc3_words) # 计算TF
tf1 = compute_tf(word_dict1, doc1_words)
tf2 = compute_tf(word_dict2, doc2_words)
tf3 = compute_tf(word_dict3, doc3_words) print(f'tf1:{tf1}')
print(f'tf2:{tf2}')
print(f'tf3:{tf3}') # 计算整个文档集合的IDF
idf = compute_idf([doc1_words, doc2_words, doc3_words]) print(f'idf:{idf}')
# 计算每个文档的TF-IDF
tfidf1 = compute_tfidf(tf1, idf)
tfidf2 = compute_tfidf(tf2, idf)
tfidf3 = compute_tfidf(tf3, idf) print("TF-IDF for Document 1:", tfidf1)
print("TF-IDF for Document 2:", tfidf2)
print("TF-IDF for Document 3:", tfidf3) """
tf1:{'this': 0.25, 'is': 0.25, 'a': 0.25, 'sample': 0.25}
tf2:{'this': 0.16666666666666666, 'is': 0.16666666666666666, 'another': 0.16666666666666666, 'example': 0.5}
tf3:{'this': 0.16666666666666666, 'is': 0.16666666666666666, 'a': 0.16666666666666666, 'different': 0.16666666666666666, 'example': 0.3333333333333333}
idf:{'example': 0.0, 'different': 0.4054651081081644, 'this': -0.2876820724517809, 'another': 0.4054651081081644, 'is': -0.2876820724517809, 'a': 0.0, 'sample': 0.4054651081081644}
TF-IDF for Document 1: {'this': -0.07192051811294523, 'is': -0.07192051811294523, 'a': 0.0, 'sample': 0.1013662770270411}
TF-IDF for Document 2: {'this': -0.047947012075296815, 'is': -0.047947012075296815, 'another': 0.06757751801802739, 'example': 0.0}
TF-IDF for Document 3: {'this': -0.047947012075296815, 'is': -0.047947012075296815, 'a': 0.0, 'different': 0.06757751801802739, 'example': 0.0} """
 

TF-IDF 算法原理以及源码实现的更多相关文章

  1. OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波

    http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...

  2. 【图像处理笔记】SIFT算法原理与源码分析

    [图像处理笔记]总目录 0 引言 特征提取就是从图像中提取显著并且具有可区分性和可匹配性的点结构.常见的点结构一般为图像内容中的角点.交叉点.闭合区域中心点等具有一定物理结构的点,而提取点结构的一般思 ...

  3. Elasticsearch由浅入深(十)搜索引擎:相关度评分 TF&IDF算法、doc value正排索引、解密query、fetch phrase原理、Bouncing Results问题、基于scoll技术滚动搜索大量数据

    相关度评分 TF&IDF算法 Elasticsearch的相关度评分(relevance score)算法采用的是term frequency/inverse document frequen ...

  4. ConcurrentHashMap实现原理及源码分析

    ConcurrentHashMap实现原理 ConcurrentHashMap源码分析 总结 ConcurrentHashMap是Java并发包中提供的一个线程安全且高效的HashMap实现(若对Ha ...

  5. HashMap和ConcurrentHashMap实现原理及源码分析

    HashMap实现原理及源码分析 哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表, ...

  6. 第十一节、Harris角点检测原理(附源码)

    OpenCV可以检测图像的主要特征,然后提取这些特征.使其成为图像描述符,这类似于人的眼睛和大脑.这些图像特征可作为图像搜索的数据库.此外,人们可以利用这些关键点将图像拼接起来,组成一个更大的图像,比 ...

  7. 【OpenCV】SIFT原理与源码分析:DoG尺度空间构造

    原文地址:http://blog.csdn.net/xiaowei_cqu/article/details/8067881 尺度空间理论   自然界中的物体随着观测尺度不同有不同的表现形态.例如我们形 ...

  8. 机器学习实战(Machine Learning in Action)学习笔记————03.决策树原理、源码解析及测试

    机器学习实战(Machine Learning in Action)学习笔记————03.决策树原理.源码解析及测试 关键字:决策树.python.源码解析.测试作者:米仓山下时间:2018-10-2 ...

  9. 【OpenCV】SIFT原理与源码分析:关键点描述

    <SIFT原理与源码分析>系列文章索引:http://www.cnblogs.com/tianyalu/p/5467813.html 由前一篇<方向赋值>,为找到的关键点即SI ...

  10. 【OpenCV】SIFT原理与源码分析:方向赋值

    <SIFT原理与源码分析>系列文章索引:http://www.cnblogs.com/tianyalu/p/5467813.html 由前一篇<关键点搜索与定位>,我们已经找到 ...

随机推荐

  1. test20230824总结

    A 怎么是重构树板子,放在图上都是水题. B 考场上只打了一个暴力,赛后发现似乎是很可做的 C 是一个考察状态设计的 dp 以后要多刷 D 是一道数据结构优化 dp 考场上写出来了却因为空间问题挂了 ...

  2. VMware vCenter Server 7.0U3r 下载 - 修复堆溢出 (远程执行代码) 和本地权限提升漏洞

    VMware vCenter Server 是一款高级服务器管理软件,提供了一个集中式平台来控制 vSphere 环境,以实现跨混合云的可见性. 简化且高效的服务器管理 什么是 vCenter Ser ...

  3. sshd管理限制登录配置(centos7.9)

    背景情况:为了公网的主机,被无限的密码爆破,需要对主机的ssh进行安装加固 1.首先要禁用root的远程登录和修改ssh的端口 vi /etc/ssh/sshd_config# 修改端口,不适用22端 ...

  4. 解决方案 | vbnet的msgbox 窗口最前置,topmost属性设置

    For that you can use the TopMost Property of MsgBox (Number 262144) MsgBox("Hello there", ...

  5. 新一代云原生日志架构 - Loggie的设计与实践

    Loggie萌芽于网易严选业务的实际需求,成长于严选与数帆的长期共建,持续发展于网易数帆与网易传媒.中国工商银行的紧密协作.广泛的生态,使得项目能够基于业务需求不断完善.成熟.目前已经开源:https ...

  6. oeasy教您玩转vim - 13 - # 大词小词

    大词小词 回忆上节课内容 我们上次学习了 e e 代表 end 词尾 自有跳跃 还可以成倍次数的跳跃 但其实我是想以一个一个属性地跳跃,有没有方法呢? 查询帮助 没思路的话我们还是得继续查询 :h w ...

  7. 不是,大哥,咱这小门小户的,别搞我CDN流量啊

    分享是最有效的学习方式. 博客:https://blog.ktdaddy.com/ 最近遇上事儿了,老猫的小小博客网站[程序员老猫的博客]被人盗刷CDN流量了.开始的时候收到了欠费的短信也没有怎么去重 ...

  8. 自制基于simplefoc大功率驱动板想法的由来,同时欢迎有相同兴趣的F友一起来玩。。。

    前一阵子,偶然在B站上看了一个simplefoc的介绍视频,代码简洁.算法精妙让人佩服,更让人佩服的是:开源!遂!搜索之!不搜不知道一搜吓一跳,发现太OUT了,原来玩这个算法的人这么多,让我这个整天沉 ...

  9. 【Java】PDF模板生成PDF文档

    一.需求背景 客户要求一份文书,文书内容有一些表单项,例如: 1.基本的是和否 (单选框或复选框) 2.备注内容(纯文本信息) 3.单位,机构组织,人员,字典项(下拉选择) 4.用户数字签名(图片信息 ...

  10. 【Java-GUI】02 Dialog对话框

    --1.对话框 Dialog java.awt.Dialog 和Window一样可以独立存在的一个窗体 但是注意: 1.Dialog对象一定需要一个依附的父级窗口 2.两种模式(模式和非模式),模式打 ...