推荐系统里的那些算法—— TF-IDF(附python代码)

本文介绍了如何利用用户生成内容(UGC)和TF-IDF权重改进推荐算法。通过用户对物品的标签行为,计算用户兴趣,同时引入TF-IDF惩罚热门标签和物品,提高推荐的精准度。算法包括统计用户常用标签、计算标签和物品的TF-IDF值,并结合用户行为调整推荐权重。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于UGC(user Generate Content)的推荐

  • 用户用标签来描述对物品的看法,所以用户生成标签(UGC)是联系用户和物品的纽带,也是反应用户兴趣的重要数据源。
  • 一个用户标签行为的数据集一般由一个三元组(用户,物品,标签)的集合表示,其中一条记录 (u, i, b)表示用户u给物品i打上了标签b.
  • 一个最简单的算法
    • 统计每个用户最常用的标签
    • 对于每个标签,统计被打过这个标签次数最多的物品
    • 对于一个用户,首先找到他常用的标签,然后找到具有这些标签的最热门的物品,推荐给他
    • 所以用户u对物品i的兴趣公式为 p ( u , i ) = ∑ n u , b × n b , i p(u,i)=\sum n_{u,b}\times n_{b,i} p(u,i)=nu,b×nb,i其中, n u , b n_{u,b} nu,b是用户u打过标签b的次数, n b , i n_{b,i} nb,i是物品i被打过标签b的次数。

TF-IDF

  • 词频-逆文档频率(Term Frequency-Inverse Document Frequency,TF-IDF)是一种用于资讯检索与文本挖掘的常用加权技术。
  • TF-IDF是一种统计方法,用以评估一个字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。 T F I D F = T F × I D F TFIDF=TF\times IDF TFIDF=TF×IDF
  • TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。

比如专业术语的TF-IDF较高,“的”、“这”、“表明”一类的词语TF-IDF较低。

  • TF-IDF加权的各种形式常被搜索引擎应用,作为文件与用户查询之间相关程度的度量或评级。
  • 词频(Term Frequency,TF)
    • 指的是某一个给定的词语在该文件中出现的频率。这个数字是对词数的归一化,以防止偏向更长的文件。(同一个词语在长文件里可能会比短文件有更离的词数,而不管该词语重要与否。) T F i , j = n i , j n ∗ , j TF_{i,j}=\frac {n_{i,j}}{n_{*,j}} TFi,j=n,jni,j其中 T F i , j TF_{i,j} TFi,j,表示词语i在文档j 中出现的频率, n i , j n_{i,j} ni,j表示i在j 中出现的次数, n ∗ , j n_{*,j} n,j表示文档j的总词数
  • 逆向文件频率(Inverse Document Frequency,IDF)
    • 是一个词语普遍重要性的度量,某一特定词语的 IDF,可以由总文档数目除以包含该词语之文档的数目,再将得到的商取对数得到。 I D F i = l o g N + 1 N i + 1 IDF_i=log_{} {\frac {N+1}{N_i+1}} IDFi=logNi+1N+1其中 I D F i IDF_i IDFi,表示词语i在文档集中的逆文档频率,N表示文档集中的文档总数, N i N_i Ni表示文档集中包含了词语i的文档数。

TF-IDF基于UGC推荐的改进

  • 为了避免热门标签和热门物品获得更多的权重,我们需要对“热门“进行惩罚借鉴TF-IDF的思想,以一个物品的所有标签作为“文档”,标签作为“词语”,从而计算标签的“词频”(在物品所有标签中的频率)和"逆文档频率”(在其它物品标签中普遍出现的频率)
  • 由于“物品i的所有标签” n ∗ , i n_{*,i} n,i应该对标签权重没有影响,而“所有标签总数”对于所有标签是一定的,所以这两项可以略去。在简单算法的基础上,直接加入对热门标签和热门物品的惩罚项: p ( u , i ) = ∑ b n u , b l o g 1 + n b ( u ) l o g n b , i l o g 1 + n i ( u ) p(u,i)=\sum _b\frac {n_{u,b}}{log_{1+n_b^{(u)}}}\frac{log_{n_{b,i}}}{log_{1+n_i^{(u)}}} p(u,i)=blog1+nb(u)nu,blog1+ni(u)lognb,i
    其中, n b ( u ) n_b^{(u)} nb(u)记录了标签b被多少个不同的用户使用过, n i ( u ) n_i^{(u)} ni(u)记录了物品i被多少个不同的用户打过标签
import pandas as pd
import numpy as np
import math
wordA = "xxx"
wordB = "yyy "
#将单词取出,并建立集合
sepA = wordA.split(" ")
sepB = wordB.split(" ")
setA = set(sepA)
setB = set(sepB)

#取并集,建立字典
union = setA.union(setB)
dictA = dict.fromkeys(setA,0)
dictB = dict.fromkeys(setA,0)

#统计两个字典中单词出现的次数
for word in dictA:
    dictA[word] += 1
    
for word in dictB:
    dictB[word] += 1

pd.DataFrame([dictA,dictB])

def computeTF(dict,set):
    tfdict = {}
    setcount = len(set)
    for word,count in dict.items():
        tfdict[word] = count / setcount
    return tfdict

tfA = computeTF(dictA,setA)
tfB = computeTF(dictB,setB)

#计算逆文档频率
def computeIDF(dictlist):
    #用字典对象保存IDF结果,每个词作为key
    idfDict = dict.fromkeys(dictlist[0],0)
    N = len(dictlist)
    for Dict in dictlist:
        for word,count in Dict.items():
            if count > 0:
                idfDict[word] += 1
    #得到所有词汇对应的Ni值,求idf
    for word ,ni in idfDict.items():
        idfDict[word] = math.log10((N+1)/(ni+1))
    return idfDict
idfs = computeIDF([dictA,dictB])

#计算TF-IDF
def computeTFIDF(tf,idfs):
    tfidf = {}
    for word,tfval in tf.items():
        tfidf[word] = tfval * idfs[word]
    return tfidf
tfidfA = computeTFIDF(tfA,idfs)
tfidfB = computeTFIDF(tfB,idfs)
pd.DataFrame([tfidfA,tfidfB])
<think>好的,用户想了解如何用Python编写TF-IDF算法的示例代码。我需要先回忆一下TF-IDF的基本概念。TF-IDF是词频-逆文档频率,常用于文本挖掘和信息检索,用来评估一个词在文档中的重要程度。TF是词在文档中的出现频率,IDF则是逆文档频率,衡量词的普遍重要性。 接下来,我需要考虑用户的请求是提供示例代码,并且用户提到了几个引用来源,其中引用1到4都是关于Python实现TF-IDF的不同方法,包括手动实现和使用库如nltk、sklearn、jieba。用户可能需要多种实现方式,所以应该覆盖手动实现和使用现有库的方法。 首先,手动实现部分。我需要分步骤解释TFIDF的计算方法,然后结合两者。代码需要计算每个词在单个文档中的词频,再计算该词在所有文档中的逆文档频率,最后相乘得到TF-IDF值。例如,对于给定的文档列表,遍历每个词,计算其TF,然后统计包含该词的文档数量来计算IDF。这需要注意处理分母为零的情况,可能需要加1平滑或者其他方法。 然后,使用现有库的部分。用户引用中提到了nltk、sklearn和jieba。Scikit-learn的TfidfVectorizer是一个常用的工具,可以快速生成TF-IDF矩阵。需要展示如何导入库、初始化向量化器,拟合数据并转换文档。同时,可能需要结合分词工具如jieba来处理中文文本,因为引用4提到了中文分词的问题,比如安装jieba库的注意事项。 此外,用户提供的引用3和4中有手动实现的例子,可能需要参考这些内容来确保代码的正确性。比如,引用3中的Tfidf类,可能包含calculate_tfidf方法,计算特定词在文档中的TF-IDF值。而引用4提到中文分词的问题,所以在处理中文时需要使用jieba进行分词,然后再应用TF-IDF算法。 需要注意代码的格式,用户要求行内数学表达式用$...$,独立公式用$$...$$。例如,TF的公式是$\text{TF}(t, d) = \frac{\text{词t在文档d中出现的次数}}{\text{文档d的总词数}}$,IDF是$\text{IDF}(t, D) = \log\left(\frac{\text{文档总数}}{1 + \text{包含词t的文档数}}\right)$,而TF-IDF则是两者的乘积。这些公式需要用正确的LaTeX语法表示,并且独立公式单独成段。 然后,生成相关问题。根据用户提供的示例,可能需要包括TF-IDF的应用场景、优化方法、与其他算法的比较,以及如何处理中文文本等问题。这些问题需要自然相关,能够帮助用户进一步理解TF-IDF的不同方面。 最后,确保回答结构清晰,分步骤说明不同的实现方法,包括手动实现和库的使用,并且代码示例正确。同时,引用用户提供的参考文献,在适当的位置添加引用标识,如[^3][^4]等。例如,在手动实现部分引用引用3和4,在使用sklearn时引用引用1和2。 可能需要注意的细节:处理中文时的分词步骤,不同库的安装问题(如jieba可能需要pip3安装),以及TF-IDF计算中的平滑处理(如加1避免除以零)。此外,代码示例需要正确缩进,语法无误,并且有注释或解释说明每一步的作用。</think>以下是如何用Python实现TF-IDF算法的分步说明,包含手动实现和第三方库两种方式: ### 一、手动实现TF-IDF TF-IDF计算公式: $$ \text{TF-IDF}(t,d,D) = \text{TF}(t,d) \times \text{IDF}(t,D) $$ 1. **词频(TF)计算**: $\text{TF}(t, d) = \frac{\text{词t在文档d中出现的次数}}{\text{文档d的总词数}}$ 2. **逆文档频率(IDF)计算**: $\text{IDF}(t, D) = \log\left(\frac{\text{文档总数}}{1 + \text{包含词t的文档数}}\right)$ ```python import math class TfidfCalculator: def __init__(self, documents): self.documents = [doc.split() for doc in documents] self.total_docs = len(documents) def tf(self, term, document): return document.count(term) / len(document) def idf(self, term): doc_count = sum(1 for doc in self.documents if term in doc) return math.log(self.total_docs / (1 + doc_count)) def tfidf(self, term, document): return self.tf(term, document) * self.idf(term) # 使用示例 docs = ["this is a sample document", "another example document", "third example text"] calculator = TfidfCalculator(docs) print(calculator.tfidf("document", docs[0].split())) # 输出: 0.0810930216216329 ``` ### 二、使用Scikit-learn实现 ```python from sklearn.feature_extraction.text import TfidfVectorizer # 创建文档集 documents = [ "This is the first document", "This document is the second document", "And this is the third one" ] # 初始化TF-IDF向量化器 tfidf_vectorizer = TfidfVectorizer() tfidf_matrix = tfidf_vectorizer.fit_transform(documents) # 查看特征词与TF-IDF值 print(tfidf_vectorizer.get_feature_names_out()) print(tfidf_matrix.toarray()[^1][^2] ``` ### 三、中文处理实现(使用jieba分词) ```python import jieba from sklearn.feature_extraction.text import TfidfVectorizer # 中文文档预处理 docs_zh = ["这是一个示例文档", "这是第二个例子文档", "这是第三个测试文档"] # 分词处理 docs_cut = [' '.join(jieba.cut(doc)) for doc in docs_zh] # 计算TF-IDF vectorizer = TfidfVectorizer() tfidf = vectorizer.fit_transform(docs_cut) print(vectorizer.get_feature_names_out()) print(tfidf.toarray()[^4] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Env1sage

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值