用TF-IDF处理文本数据

计算机擅长处理数字,但不擅长处理文本数据,TF-IDF是处理文本数据最广泛使用的技术之一,本文对它的工作原理以及它的特性进行介绍。

根据直觉,我们认为在文本数据分析中出现频率更高的单词应该具有更大的权重,但事实并非总是如此。诸如“the”、“will”和“you”等被称为停顿词的词在语料库中出现得最多,但意义不大。相反,那些罕见的词实际上是那些有助于区分数据的词,而且更有分量。

TF-IDF简介

TF-IDF代表“Term Frequency — Inverse Data Frequency(词频-逆文档频次)”,其数学含义如下:

Term Frequency (tf, 词频):给出语料库中每个文档中单词出现的频率。它是单词在文档中出现的次数与该文档中单词总数的比率,随着该单词在文档中出现次数的增加而增加,每个文档都有自己的词频:

t f i , j = n i , j ∑ k n i , j {tf}_{i,j}=\frac{n_{i,j}}{\sum_k{n_{i,j}}} tfi,j=kni,jni,j

Inverse Data Frequency(idf, 逆数据频率):用于计算语料库中所有文档中罕见词的权重,语料库中很少出现的词具有较高的IDF分数,它由下面的方程给出:

i d f ( ω ) = l o g ( N d f t ) idf(\omega)=log(\frac{N}{{df}_t}) idf(ω)=log(dftN)

结合这两者,我们得出了语料库中文档中单词的TF-IDF分数( ω \omega ω)。它是tf和idf的乘积:

t f i , j × l o g ( N d f i ) {tf}_{i,j} \times log(\frac{N}{{df}_i}) tfi,j×log(dfiN)
其中:

  • t f i , j {tf}_{i,j} tfi,j j j j i i i出现的次数;
  • d f i {df}_i dfi:包含 i i i的文件数;
  • N N N:文件总数。

让我们举一个例子来更清楚地理解。

句子1:The car is driven on the road.

句子2:The truck is driven on the highway.

在本例中,每个句子都是一个单独的文档,现在我们将计算上述两个代表语料库的文档的TF-IDF。

在这里插入图片描述

由上表可知,常用词的TF-IDF为零,说明常用词不显著。另一方面,“car”、“truck”、“road”、“highway”的TF-IDF是非零的,这些词更有意义。

基于python计算TF-IDF

  1. sklearn.feature_extraction.text导入TfidfVectorizer
    from sklearn.feature_extraction.text import TfidfVectorizer
  1. 初始化矢量器,然后调用fit并对其进行变换,以计算文本的TF-IDF分数。
    vectorizer = TfidfVectorizer()response = vectorizer.fit_transform([s1, s2])
s1 = "The car is driven on the road"
s2 = "The truck is driven on the highway"
from sklearn.feature_extraction.text import TfidfVectorizervectorizer = TfidfVectorizer()
response = vectorizer.fit_transform([s1, s2])

这里返回的是csr_matrix稀疏矩阵,可以通过response.todense()转换成numpy形式。

print(response)
  (0, 5)	0.42471718586982765(0, 4)	0.30218977576862155(0, 1)	0.30218977576862155(0, 3)	0.30218977576862155(0, 0)	0.42471718586982765(0, 6)	0.6043795515372431(1, 2)	0.42471718586982765(1, 7)	0.42471718586982765(1, 4)	0.30218977576862155(1, 1)	0.30218977576862155(1, 3)	0.30218977576862155(1, 6)	0.6043795515372431

看一下TfidfVectorizer的源码:
在下述代码中需要注意的一点是,sklearn将1添加到n_samples中以计算IDF分数,这确保了IDF分数为0的单词不会被完全抑制。

    def fit(self, X, y=None):"""Learn the idf vector (global term weights)Parameters----------X : sparse matrix, [n_samples, n_features]a matrix of term/token counts"""if not sp.issparse(X):X = sp.csc_matrix(X)if self.use_idf:n_samples, n_features = X.shapedf = _document_frequency(X)# perform idf smoothing if requireddf += int(self.smooth_idf)n_samples += int(self.smooth_idf)# log+1 instead of log makes sure terms with zero idf don't get# suppressed entirely.idf = np.log(float(n_samples) / df) + 1.0self._idf_diag = sp.spdiags(idf, diags=0, m=n_features,n=n_features, format='csr')return selfdef transform(self, X, copy=True):"""Transform a count matrix to a tf or tf-idf representationParameters----------X : sparse matrix, [n_samples, n_features]a matrix of term/token countscopy : boolean, default TrueWhether to copy X and operate on the copy or perform in-placeoperations.Returns-------vectors : sparse matrix, [n_samples, n_features]"""if hasattr(X, 'dtype') and np.issubdtype(X.dtype, np.floating):# preserve float family dtypeX = sp.csr_matrix(X, copy=copy)else:# convert counts or binary occurrences to floatsX = sp.csr_matrix(X, dtype=np.float64, copy=copy)n_samples, n_features = X.shapeif self.sublinear_tf:np.log(X.data, X.data)X.data += 1if self.use_idf:check_is_fitted(self, '_idf_diag', 'idf vector is not fitted')expected_n_features = self._idf_diag.shape[0]if n_features != expected_n_features:raise ValueError("Input has n_features=%d while the model"" has been trained with n_features=%d" % (n_features, expected_n_features))# *= doesn't workX = X * self._idf_diagif self.norm:X = normalize(X, norm=self.norm, copy=False)return X

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/345764.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript数组全攻略

🧑‍🎓 个人主页:《爱蹦跶的大A阿》 🔥当前正在更新专栏:《VUE》 、《JavaScript保姆级教程》、《krpano》 ​ ​ 目录 ✨ 前言 数组的定义 创建数组 1. 数组字面量 2. Array构造函数 3. Array.of() 4. Arra…

Unity摇杆+键鼠控制位移、旋转

1、位移 首先我们找到两张图片,一个大圆一个小圆,像这样: 结构是这样的: 然后,新建一个场景,用胶囊去做玩家,摄像机在胶囊下,并且在场景中放两个cube作为参照物 像这样搭好后&#…

STM32——OLED实验

1.OLED简介 OLED,即有机发光二极管 OLED引脚说明 引脚说明: 1、CS:OLED片选信号(低电平有效) 2、WR:向OLED写入数据 3、RD:向OLED读取数据 4、D[7:0]:8位双向数据线,有…

API Monitor简易使用教程 监控Windows dll调用 监控Windows API调用 查看函数名,参数类型,参数,返回值

先看效果,可以显示所有dll及windows api的指定函数调用,以及传递的参数查看与修改。 官网下载 也有教程 我验证使用方法 1、API Filter窗口:选定要监听的dll函数或windows API,可以打断点 选中并右键勾上Breakpoint 选 Before C…

线程安全--互斥锁

文章目录 一.线程安全问题读取无效(脏)数据丢失更新线程安全的保证--操作的原子性 二.互斥锁及其实现原理互斥锁的实现原理pthread线程库提供的锁操作 三.死锁问题 一.线程安全问题 当多个线程并发地对同一个共享资源进行修改操作时,可能会引发数据读写错误(比如读取无效(脏)数…

【Databend】行列转化:一行变多行和简单分列

文章目录 数据准备和需求生成序列和分隔函数根据分隔符变多行JSON 数据简单分列总结 数据准备和需求 行列转化在实际工作中很常见,其中最常见的有一行变多行,有下面一份数据: drop table if exists fact_suject_data; create table if not …

设计模式之迭代器模式【行为型模式】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档> 学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某…

linux搭建SRS服务器

linux搭建SRS服务器 文章目录 linux搭建SRS服务器SRS说明实验说明搭建步骤推流步骤查看web端服务器拉流步骤final SRS说明 SRS(simple Rtmp Server),是一个简单高效的实时视频服务器,支持RTMP/WebRTC/HLS/HTTP-FLV/SRT, 是国人自己开发的一款…

“所有伙食开销统计:轻松查看,智能管理你的餐饮支出“

你是否经常为伙食开销感到困扰,不知道如何有效控制和管理?现在,有了我们的伙食开销统计工具,这些问题将得到轻松解决! 首先第一步,我们要进入晨曦记账本并在上方功能栏里选择“查看方式”。并在弹出来的列表…

c++算法之枚举

目录 解空间的类型 循环枚举解空间 例题 特别数的和 输入格式 输出格式 输入样例: 输出样例: 解 例题 反倍数 问题描述 输入格式 输出格式 样例输入 样例输出 解 例题 找到最多的数 解 枚举算法是一种基本的算法思想,它通过…

写一个文字滑动切换样式效果

<template><div class"mainrouter centerWindi"><h1>2024,马上暴富</h1></div> </template> <style lang"scss"> /* 居中 */ .centerWindi {apply flex justify-center items-center;text-align: center; }/* 路…

【Linux笔记】进程等待与程序替换

一、进程的终止 1、进程退出码 在讲解进程的终止之前&#xff0c;先要普及一下进程的退出码概念。 我们父进程之所以要创建子进程&#xff0c;就是为了让子进程运行不一样的任务&#xff0c;那么对于子进程执行的这个任务执行完毕后的结果是否正确或者是否出差错&#xff0c…