news 2026/4/25 6:31:41

科普:CountVectorizer、TF、TF-IDF,三者层层递进

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
科普:CountVectorizer、TF、TF-IDF,三者层层递进
  1. CountVectorizer
    Count Vectorizer
    计数向量化器

  2. 词频
    TF = Term Frequency
    词条频率

  3. TF-IDF
    Term Frequency – Inverse Document Frequency
    词条频率 - 逆文档频率
    ountVectorizer、TF、TF-IDF本来是给 NLP(自然语言)用的,但常被借用来处理「多值离散字段」,即把「多值离散字段」当成文本来用!

一、三者层层递进关系

先看一业务场景

我们有一个离散字段merchant_type(用户交易活动的商户类型),每个用户的交易记录如下:

card_idmerchant_type(商户类型)
user1餐饮, 餐饮, 超市, 餐饮
user2超市, 超市, 便利店
user3餐饮, 便利店, 餐饮, 超市

我们把每个用户的交易记录,看成一段“文本”(伪文本):

  • user1 的“文本”:餐饮 餐饮 超市 餐饮
  • user2 的“文本”:超市 超市 便利店
  • user3 的“文本”:餐饮 便利店 餐饮 超市

第一层:CountVectorizer(计数向量化)

CountVectorizer(计数向量化)是一个工具,作用是:把文本/类别数据,转换成一个由「词频」组成的矩阵。

它的工作分两步:

  1. 构建词表:把所有出现过的“词”(这里就是所有商户类型)收集起来,形成一个固定的词汇表。
  2. 计数:对每一段文本,统计词表中每个词出现的次数。

举例:对我们的交易数据

  1. 构建词表
    ["餐饮", "超市", "便利店"]
  2. 计数:对每个用户的“文本”统计词频。

结果矩阵:

card_id餐饮超市便利店
user1310
user2021
user3211

第二层:词频(Term Frequency, TF)

词频,就是某个词在单条文本/单个用户中出现的次数。
它是 CountVectorizer 的直接计算的结果,也是构建更复杂特征(如 TF-IDF)的基础。

在我们的例子里,表格里的每一个数字,都是一个“词频”:

  • user1餐饮词频是 3
  • user2便利店词频是 1

词频的优缺点

  • 优点:直接反映用户的行为频次,和数值情况用groupby做的count统计逻辑完全一致,非常直观。
  • 缺点:它不考虑词的“重要性”。比如“超市”这个词,所有用户都用,词频很高,但它无法区分用户的独特偏好。

第三层:TF-IDF(Term Frequency – Inverse Document Frequency,词频-逆文档频率)

它是在“词频(TF)”的基础上,为克服其缺点,引入了“逆文档频率(IDF)”来衡量词的稀有度,从而给不同的词赋予不同的权重。

公式:
TF-IDF=词频(TF)×逆文档频率(IDF) \text{TF-IDF} = \text{词频(TF)} \times \text{逆文档频率(IDF)}TF-IDF=词频(TF)×逆文档频率(IDF)

  • TF(词频):就是第二层我们讲的,词在当前文本中出现的次数。
  • IDF(逆文档频率):衡量这个词在所有文本/所有用户中的稀有程度。词越稀有,IDF值越高。

举例:对我们的交易数据

第一步:计算 IDF(稀有度)

总共有 3 个用户(文本)。

  • 餐饮:出现在 2 个用户中 → 不算太普遍
  • 超市:出现在 3 个用户中 → 非常普遍
  • 便利店:出现在 2 个用户中 → 不算太普遍

IDF 的简化计算:
IDF(词)=log⁡(总用户数出现该词的用户数) \text{IDF}(词) = \log(\frac{\text{总用户数}}{\text{出现该词的用户数}})IDF()=log(出现该词的用户数总用户数)

  • IDF(餐饮)=log⁡(3/2)≈0.405\text{IDF(餐饮)} = \log(3/2) ≈ 0.405IDF(餐饮)=log(3/2)0.405
  • IDF(超市)=log⁡(3/3)=0\text{IDF(超市)} = \log(3/3) = 0IDF(超市)=log(3/3)=0
  • IDF(便利店)=log⁡(3/2)≈0.405\text{IDF(便利店)} = \log(3/2) ≈ 0.405IDF(便利店)=log(3/2)0.405
第二步:计算 TF-IDF

user1为例:

  • 餐饮TF=3×IDF=0.405≈1.215TF=3 \times IDF=0.405 ≈ 1.215TF=3×IDF=0.4051.215
  • 超市TF=1×IDF=0=0TF=1 \times IDF=0 = 0TF=1×IDF=0=0
  • 便利店TF=0×IDF=0.405=0TF=0 \times IDF=0.405 = 0TF=0×IDF=0.405=0

最终 TF-IDF 矩阵:

card_id餐饮_tfidf超市_tfidf便利店_tfidf
user11.21500
user2000.405
user30.8100.405

TF-IDF 完美解决了“词频”的缺点:

  • 高频普遍词被削弱:所有用户都爱去的“超市”,IDF为0,权重被压低,无法区分用户。
  • 低频独特词被强化:用户的独特偏好(如 user1 高频的“餐饮”、user2 的“便利店”)被放大,权重很高,能有效区分用户行为。

三者的递进关系总结

层级核心概念本质作用
1️⃣CountVectorizer工具把文本/类别列表转换成词频矩阵从非数值数据中提取基础频次特征
2️⃣词频 (TF)结果/基础特征词在单条文本中的出现次数反映用户的行为频次,是构建更复杂特征的基础
3️⃣TF-IDF进阶特征词频 × 稀有度(IDF)反映用户的独特行为偏好,是对词频特征的补充和优化

一句话串起来:
CountVectorizer 工具,产出了词频(TF);在词频的基础上,乘以逆文档频率(IDF),就得到了 TF-IDF。


二、TF-IDF 极简代码示例

用上述交易商户类型场景举例。

importpandasaspdfromsklearn.feature_extraction.textimportTfidfVectorizer# 1. 构造数据(每个用户的商户类型行为)data={'card_id':['user1','user2','user3'],'merchant_text':['餐饮 餐饮 超市 餐饮',# user1'超市 超市 便利店',# user2'餐饮 便利店 餐饮 超市'# user3]}df=pd.DataFrame(data)# 2. 初始化 TF-IDF 工具tfidf=TfidfVectorizer()# 3. 把文本转成 TF-IDF 特征矩阵tfidf_matrix=tfidf.fit_transform(df['merchant_text'])# 4. 转成 DataFrame 方便查看tfidf_df=pd.DataFrame(tfidf_matrix.toarray(),columns=tfidf.get_feature_names_out())# 5. 合并回原数据result=pd.concat([df[['card_id']],tfidf_df],axis=1)print(result)

运行结果

card_id 便利店 餐饮 超市 0 user1 0.000000 0.927743 0.372302 1 user2 0.720338 0.000000 0.693642 2 user3 0.542701 0.542701 0.643187

这个结果代表什么?

  • 数字越大 = 这个商户类型对这个用户越独特、越重要
  • 数字越小 = 越普通、越没有区分度

重点解读:

  1. user1 的 餐饮 分数最高(0.93)
    因为他经常去餐饮,且餐饮不是所有人都去 →独特行为

  2. 超市 分数都不高
    因为大家都去超市 →太普遍,不重要

  3. 便利店 只对 user2、user3 重要
    因为不是所有人都去 →有区分度


1. TF-IDF 用于离散字段做特征

例如:

  • merchant_type(商户类型)
  • city(城市)
  • category(品类)
  • brand(品牌)

把每个用户的历史行为拼成一段文本,直接用 TF-IDF 生成强特征。

2. 作用:

  • 自动识别用户独特偏好
  • 自动降低大家都有的普遍行为权重
  • 给模型提供区分度极强的特征

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 1:03:23

解决篡改猴开启开发者模式后,脚本没有生效的情况

第一步: 打开开发者选项 第二步:点击详情 第三步:开启启用开关 第四步:允许运行用户脚本 第五步:看情况开启:开启允许访问文件地址 看你的脚本是否需要读取本地文件,需要的话 &#xff08…

作者头像 李华
网站建设 2026/4/17 1:02:38

深度解析CAT.1物联网应用:从AT指令到云平台全流程

目录 一、CAT.1 核心功能与应用场景 1. 核心能力(深度挖掘点) 2. 典型应用场景 二、硬件与开发环境准备 1. 硬件选型(主流 CAT.1 模块) 2. 开发环境 三、完整例程详解(STM32EC200U) (一…

作者头像 李华
网站建设 2026/4/17 1:01:17

Spring Boot 启动性能调优方案

Spring Boot 启动性能调优方案 Spring Boot作为Java开发的主流框架,以其快速构建和约定优于配置的特性广受欢迎。随着项目规模扩大,启动时间可能成为瓶颈,影响开发效率和部署体验。本文将介绍几种实用的启动性能调优方案,帮助开发…

作者头像 李华
网站建设 2026/4/17 1:01:16

学Simulink——基于Simulink的CLLC谐振变换器双向对称控制

目录 手把手教你学Simulink——基于Simulink的CLLC谐振变换器双向对称控制​ 摘要​ 一、背景与挑战​ 1.1 为什么CLLC + 对称控制是“天作之合”?​ 1.2 设计目标​ 二、系统架构与核心控制推导​ 2.1 整体架构:双向能量流动的“旋转门”​ 2.2 对称控制律推导(核心…

作者头像 李华
网站建设 2026/4/17 0:58:35

告别官方WebRTC编译噩梦:用libdatachannel轻松搞定USB摄像头实时推流

用libdatachannel实现USB摄像头零延迟推流的实战指南 当我们需要快速实现一个低延迟的视频推流系统时,传统WebRTC庞大的编译体系往往让人望而却步。最近在RK3588平台上开发多摄像头监控系统时,我亲身体验了从官方WebRTC转向libdatachannel的完整过程&am…

作者头像 李华
网站建设 2026/4/17 0:57:01

# 7天从零搞定GBase培训——数据库知识真的可以平移

7天从零搞定GBase培训——数据库知识真的可以平移 背景 接到一个任务:给甲方做GBase数据库培训。要求覆盖GBase 8s(事务型)和GBase 8a(分析型MPP)两个产品。 问题来了:我从来没碰过GBase。 官方给了一批产品…

作者头像 李华