科普: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_id merchant_type(商户类型)
user1 餐饮, 餐饮, 超市, 餐饮
user2 超市, 超市, 便利店
user3 餐饮, 便利店, 餐饮, 超市

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

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

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

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

它的工作分两步:

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

举例:对我们的交易数据

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

结果矩阵:

card_id 餐饮 超市 便利店
user1 3 1 0
user2 0 2 1
user3 2 1 1

第二层:词频(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.405≈1.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
user1 1.215 0 0
user2 0 0 0.405
user3 0.81 0 0.405

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

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

三者的递进关系总结

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

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


二、TF-IDF 极简代码示例

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

python 复制代码
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer

# 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. 作用:

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

相关推荐
QQ2422199794 小时前
基于python+微信小程序的家教管理系统_mh3j9
开发语言·python·微信小程序
RSTJ_16254 小时前
PYTHON+AI LLM DAY THREETY-SEVEN
开发语言·人工智能·python
郝学胜-神的一滴4 小时前
深度学习优化核心:梯度下降与网络训练全解析
数据结构·人工智能·python·深度学习·算法·机器学习
Aision_4 小时前
Agent 为什么需要 Checkpoint?
人工智能·python·gpt·langchain·prompt·aigc·agi
清水白石0084 小时前
《Python性能深潜:从对象分配开销到“小对象风暴”的破解之道(含实战与最佳实践)》
开发语言·python
Land03295 小时前
RPA工具选型技术指南:架构差异与实测数据
python·自动化·rpa
kafei_*6 小时前
VScode 添加 UV虚拟环境方法
vscode·python·uv
洛_尘6 小时前
Python 5:使用库
java·前端·python
m0_596749097 小时前
如何防止SQL拼接漏洞_使用PDO对象实现安全的SQL交互
jvm·数据库·python
AIFQuant9 小时前
2026 全球股票/外汇/贵金属行情 API 深度对比:延迟、覆盖、价格与稳定性
python·websocket·ai·金融·mcp