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. VSCode因网络问题导致下载更新/扩展出错

    VSCode因网络问题导致下载更新/扩展出错 可尝试方法:   问题0: VSCode出现网络问题排查方法?       法1: 启动时加上选项 --log-net-log=netlog.json   ...

  2. RabbitMQ 3.7.9版本中,Create Channel超时的常见原因及排查方法

    在RabbitMQ 3.7.9版本中,Create Channel超时的常见原因及排查方法如下: 常见原因 网络问题: 网络延迟或不稳定可能导致通信超时. 网络分区(network partition ...

  3. React项目国际化-React-intl

    npx create-react-app react-intl-demo && cd react-intl-demo,创建react-intl-demo项目.npm install r ...

  4. Spark3学习【基于Java】2. Spark-Sql核心概念

    SparkSession 从Spark2开始,Spark-SQL引入了SparkSession这个核心类,它是处理DataSet等结构数据的入口.在2.0之前,使用的是spark-core里的Spar ...

  5. 【韦东山】嵌入式全系统:单片机-linux-Android对硬件操作的不同侧重点

    我是韦东山,一直从事嵌入式Linux培训,最近打算连载一系列文章. 正在录制全新的嵌入式Linux视频,使用新路线,不再从裸机/uboot开始,效率更高. 对应文档也会写成书<<嵌入式Li ...

  6. DDP:微软提出动态detection head选择,适配计算资源有限场景 | CVPR 2022

    DPP能够对目标检测proposal进行非统一处理,根据proposal选择不同复杂度的算子,加速整体推理过程.从实验结果来看,效果非常不错 来源:晓飞的算法工程笔记 公众号 论文: Should A ...

  7. redis基本数据结构-散列

    redis基本数据结构-hash散列数据结构  1. 基本情况 一个散列键最多可以包含 2^32 - 1 个字段 散列类型不能嵌套其他数据类型 2.命令 插入/更新字段 hset key field1 ...

  8. 前端开发-- Webpack 代码分割和懒加载技术

    在现代前端开发中,优化应用性能是一个至关重要的任务.Webpack 作为一个强大的打包工具,为我们提供了代码分割和懒加载的功能,可以显著提升应用的加载速度和用户体验.本文将深入解析 Webpack 的 ...

  9. 5 pdf页码跳转失效

    PC端网页查看pdf时,输入非数字页码回车后,页码跳转功能失效

  10. vue中 lang="ts"与js的区别

    `lang="ts"` 与 `js` 的区别在于指定了脚本语言的类型,其中: - `lang="ts"` 指定了 TypeScript,一种由微软开发的 Jav ...