什么是推荐系统?
在如今这个信息爆炸的时代,推荐系统是根据用户的信息或者行为,向用户推荐用户可能会感兴趣的内容。其中基于文本的推荐系统,比如搜索引擎,头条、微信这类资讯类应用的搜索功能,就是在一个文本库中,挖掘和提取每一条文本的特征,然后再计算出文本之间的相似度,从而推荐给用户。
在这类文本推荐算法中,非常重要且实用的算法之一就是本文的主题:TF-IDF。根据一份2015年的调查统计,83%的文本推荐系统都有采用TF-IDF。(实在没有找到更新的调查数据了......)
什么是TF-IDF?
TF-IDF(term frequency--inverse document frequency,词频-逆文档频率)是一种统计方法,用来评估一个关键字对于语料库中某一个文档的重要程度。
TF(Term Frequency)
TF(Term Frequency):词频表示某个关键字在某个文档中出现的频率。这个指标是对出现次数的归一化,以避免指标偏向长文档。频率越高,则这个关键字在该文档中的重要程度越高。
不过一些通用的词汇在所有的文档中出现的频率都很高,却并不能代表每个文档的特征,这就需要用IDF来度量并修正。
IDF(Inverse Document Frequency)
IDF(Inverse Document Frequency):逆文档频率指数表示关键字在整个语料库中的普遍程度。如果包含某个关键字的文档数量越少,则这个关键字的IDF越大,表示这个关键字对文档有很好的区分能力。
TF-IDF = TF * IDF
将每个关键字的TF值乘以IDF值,就是这个关键字的TF-IDF权重值。对语料库中的每个关键字都需要计算出对应的TF-IDF值,就得到了语料库的TF-IDF特征矩阵。某个关键字在某个文档中的高词频,以及该关键字在整个语料库的低文件频率,就会得出高权重的TF-IDF。
代码实现
在Python中,有一些现成的轮子可以用来计算语料库中的 TF-IDF,比如 NLTK、gensim 和 sklearn,我会比较推荐使用 sklearn,以下使用 sklearn 来举例说明计算 TF-IDF 的代码实现方式。
sklearn 中提供了三个关键的类来将文本转换为TF-IDF的特征矩阵:
- CountVectorizer:将语料库转换为词频向量矩阵;
- TfidfTransformer:将词频向量矩阵转换为TF-IDF的特征矩阵;
- TfidfVectorizer:结合了CountVectorizer和TfidfTransformer的功能,首先计算词频,然后计算TF-IDF权重。
所以,如果从零开始处理文本数据,可以直接使用TfidfVectorizer,示例如下:
python
from sklearn.feature_extraction.text import TfidfVectorizer
# 语料库
corpus = [
'This is the first document',
'This is the second document',
'This is the third one',
'Is this the first document',
]
# 创建TF-IDF向量化实例
vectorizer = TfidfVectorizer()
# 拟合并转换文本数据
tfidf_matrix = vectorizer.fit_transform(corpus)
# 打印TF-IDF特征名称
print("Feature names:", vectorizer.get_feature_names_out())
# 打印TF-IDF矩阵
print("TF-IDF matrix:\n", tfidf_matrix.toarray())
输出
less
Feature names:
['document' 'first' 'is' 'one' 'second' 'the' 'third' 'this']
TF-IDF matrix:
[[0.46979139 0.58028582 0.38408524 0. 0. 0.38408524 0. 0.38408524]
[0.42796959 0. 0.34989318 0. 0.67049706 0.34989318 0. 0.34989318]
[0. 0. 0.31091996 0.59581303 0. 0.31091996 0.59581303 0.31091996]
[0.46979139 0.58028582 0.38408524 0. 0. 0.38408524 0. 0.38408524]]
将其转换为更直观的表格来显示每个文档的特征关键字及权重如下:
文档 | 关键字权重 |
---|---|
This is the first document | first 0.58, document 0.47, this 0.38, the 0.38, is 0.38, third 0.00, second 0.00, one 0.00, |
This is the second document | second 0.67, document 0.43, this 0.35, the 0.35, is 0.35, third 0.00, one 0.00, first 0.00, |
This is the third one | third 0.60, one 0.60, this 0.31, the 0.31, is 0.31, second 0.00, first 0.00, document 0.00, |
Is this the first document | first 0.58, document 0.47, this 0.38, the 0.38, is 0.38, third 0.00, second 0.00, one 0.00, |
从结果中可以看出,"this"、"is" 和 "the" 这种在每个文档中都出现的通用词汇,权重都很低,而"first"、"second" 和 "third"这种可以很好区分文档的特征就被赋予了较高的权重。
TF-IDF 算法的缺陷
TF-IDF希望对大众化的、热门的词汇进行"惩罚",强调物以稀为贵,从而实现更加个性化的推荐。但由于其结构简单粗暴,虽然易于实现,但也由此存在一些缺陷。
- TF-IDF 是一种词袋模型,丢失了词汇的位置信息,比如一般出现在标题、首句、尾句的词汇应该会更重要一些,但TF-IDF丢失了这部分信息;
- TF-IDF 没有考虑词汇的语义信息,每个词汇都是独立的计算词频和逆文档频率,无法处理一词多义或者一义多词的情况;
- TF-IDF 受语料库的影响大,如果语料库中的关键字分布特征与待处理文档的关键字分布特征不同,那么TF-IDF算法的效果可能会很差。