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

张开发
2026/4/17 1:05:12 15 分钟阅读

分享文章

科普:CountVectorizer、TF、TF-IDF,三者层层递进
CountVectorizer→Count Vectorizer计数向量化器词频→TF Term Frequency词条频率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计数向量化是一个工具作用是把文本/类别数据转换成一个由「词频」组成的矩阵。它的工作分两步构建词表把所有出现过的“词”这里就是所有商户类型收集起来形成一个固定的词汇表。计数对每一段文本统计词表中每个词出现的次数。举例对我们的交易数据构建词表[餐饮, 超市, 便利店]计数对每个用户的“文本”统计词频。结果矩阵card_id餐饮超市便利店user1310user2021user3211第二层词频Term Frequency, TF词频就是某个词在单条文本/单个用户中出现的次数。它是 CountVectorizer 的直接计算的结果也是构建更复杂特征如 TF-IDF的基础。在我们的例子里表格里的每一个数字都是一个“词频”user1的餐饮词频是 3user2的便利店词频是 1词频的优缺点✅优点直接反映用户的行为频次和数值情况用groupby做的count统计逻辑完全一致非常直观。❌缺点它不考虑词的“重要性”。比如“超市”这个词所有用户都用词频很高但它无法区分用户的独特偏好。第三层TF-IDFTerm 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.405IDF(超市)log⁡(3/3)0\text{IDF(超市)} \log(3/3) 0IDF(超市)log(3/3)0IDF(便利店)log⁡(3/2)≈0.405\text{IDF(便利店)} \log(3/2) ≈ 0.405IDF(便利店)log(3/2)≈0.405第二步计算 TF-IDF以user1为例餐饮TF3×IDF0.405≈1.215TF3 \times IDF0.405 ≈ 1.215TF3×IDF0.405≈1.215超市TF1×IDF00TF1 \times IDF0 0TF1×IDF00便利店TF0×IDF0.4050TF0 \times IDF0.405 0TF0×IDF0.4050最终 TF-IDF 矩阵card_id餐饮_tfidf超市_tfidf便利店_tfidfuser11.21500user2000.405user30.8100.405TF-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]}dfpd.DataFrame(data)# 2. 初始化 TF-IDF 工具tfidfTfidfVectorizer()# 3. 把文本转成 TF-IDF 特征矩阵tfidf_matrixtfidf.fit_transform(df[merchant_text])# 4. 转成 DataFrame 方便查看tfidf_dfpd.DataFrame(tfidf_matrix.toarray(),columnstfidf.get_feature_names_out())# 5. 合并回原数据resultpd.concat([df[[card_id]],tfidf_df],axis1)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这个结果代表什么数字越大 这个商户类型对这个用户越独特、越重要数字越小 越普通、越没有区分度重点解读user1 的 餐饮 分数最高0.93因为他经常去餐饮且餐饮不是所有人都去 →独特行为超市 分数都不高因为大家都去超市 →太普遍不重要便利店 只对 user2、user3 重要因为不是所有人都去 →有区分度1. TF-IDF 用于离散字段做特征例如merchant_type商户类型city城市category品类brand品牌把每个用户的历史行为拼成一段文本直接用 TF-IDF 生成强特征。2. 作用自动识别用户独特偏好自动降低大家都有的普遍行为权重给模型提供区分度极强的特征

更多文章