一. TF-IDF

TF-IDF是一种基于统计的文档检索算法,用于评估一个词语对于一个语料库中的某个文档的重要程度,可提取语料库中文档的关键词

1. Term-Frequency

在给定的语料库中,词频指的是,某个词语在语料库中的某个文档中出现的次数 / 该文档中的总次数。为了避免过长的文件的影响(大概率词语出现的次数多一些),常考虑为对词数(term count)的归一化, 即词频 (TF) = 单词在文档中出现的次数 / 文档的总词数

假设语料库中包含若干个文档,整个语料库包含多个词。

分子表示语料库的第  个词在第  个文件中出现的次数,分母表示文件  中的总词数。在判断关键词时,通常还需要去掉一些停用词,如中文的“的”,“地”。

2. Inverse document frequency

逆文档频率是一个词语普遍重要性的度量,如果一个词越常见,则分母越大,逆文档概率就越小,越接近0,分母加1是防止分母为0。即逆文档频率(IDF) = log (语料库中的文档总数 / 语料库中包含某个词的文档数 + 1) .

上述公式中,分母  表示语料库中的文档总数,分子  表示包含 语料库中的第  个词的文件个数。更通用的计算公式为:

分母加1是防止出现所有文件中都未出现过该词的情况, log可防止计算的值过大。

3. TF-IDF

最终TF-IDF = 词频(TF) * 逆文档频率(IDF),即 

上式可以看出,TF-IDF与一个词在语料库中的一个文件中出现次数成正比,与语料库中的所有文件中包含该词的文件数成反比。TF-IDF可作为一种提取文件中关键词的算法,即计算出文档中的每一个词的TF-IDF值,然后降序排列,前几个词可看做某个文档中的关键词。

举例,假设某篇文章的标题为《中国程序员薪资》。求关键词时,中国,程序员,薪资3个词,在文章的词频应该都会很大,即TF的值很大,但中国这个词在所有文章中出现的值都较大,因此中国的IDF值较小。因此最终的关键词更可能是程序员,薪资。

4. 处理英文语料

        以 Scikit-learn 中所包含的TF-IDF算法为例,代码如下:

(1) 定义语料库

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.feature_extraction.text import TfidfTransformercorpus = ["This is the first document.","This document is the second document.","And this is the third one","Is this the first document"
]

(2) 初始化函数

# CountVectorizer:
#     Convert a collection of text documents to a matrix of token counts
#     统计语料库中每一个词语的词频矩阵
# TfidfTransformer:
#     Transform a count matrix to a normalized tf or tf-idf representation
#     将词频矩阵Count转换为TF-IDF矩阵
# TfidfVectorizer:
#     Convert a collection of raw documents to a matrix of TF-IDF features
#     统计语料库中每一个词语的TF-IDF矩阵

(3) 转换为TF-IDF矩阵

vectorizer = CountVectorizer()
count = vectorizer.fit_transform(corpus)
words = vectorizer.get_feature_names()transformer = TfidfTransformer()
tfidf = transformer.fit_transform(count)# vectorizer = TfidfVectorizer()
# tfidf = vectorizer.fit_transform(corpus)
# words = vectorizer.get_feature_names()

(4) 结果展示

# words =  ['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
# count =  [
#   [0 1 1 1 0 0 1 0 1]
#   [0 2 0 1 0 1 1 0 1]
#   [1 0 0 1 1 0 1 1 1]
#   [0 1 1 1 0 0 1 0 1]
# ]
# tfidf = [
#   [0.0, 0.46979138557992045, 0.5802858236844359, 0.38408524091481483, 0.0, 0.0, 0.38408524091481483, 0.0, 0.38408524091481483],
#   [0.0, 0.6876235979836938, 0.0, 0.281088674033753, 0.0, 0.5386476208856763, 0.281088674033753, 0.0, 0.281088674033753],
#   [0.511848512707169, 0.0, 0.0, 0.267103787642168, 0.511848512707169, 0.0, 0.267103787642168, 0.511848512707169, 0.267103787642168],
#   [0.0, 0.46979138557992045, 0.5802858236844359, 0.38408524091481483, 0.0, 0.0, 0.38408524091481483, 0.0, 0.38408524091481483]
# ]

(5) sklearn源码分析

class TfidfTransformer(TransformerMixin, BaseEstimator):def __init__(self,norm='l2',use_idf=True,smooth_idf=True,sublinear_tf=False):self.norm = normself.use_idf = use_idfself.smooth_idf = smooth_idfself.sublinear_tf = sublinear_tf

几个参数的意义如下:

  • norm: Each output row will have unit norm(输出的值的每一行进行正则化)。(L1 Norm/L2 Norm)
  • use_idf: Enable inverse-document-frequency reweighting.(是否计算IDF值)
  • smooth_idf: Smooth idf weights by adding one to document frequencies.(计算IDF时,分母加1)
  • sublinear_tf: replace tf with 1 + log(tf).(更新计算tf值)

5. 处理中文语料

(1) 定义语料库

corpus = ["我想订一张从北京到上海的机票。","帮我订一张明天下午到成都的机票,从广州出发。","我明天早上从广州飞往香港,半给我订一张机票。","我要在10月30日飞往香港。","帮我查一下有没有当澳门的机票,今下午出发。","我要订一张25号星期四去北京的飞机票。","你已预订并确认了后天飞往伦敦的177次航班。","我想取消我预订的航班,改航班号TG809。"
]

(2) 分词

def get_lac_results(text):result = lac.lexical_analysis(data={"text": [text]})words = result[0]["word"]tags = result[0]["tag"]return words, tagsdef convert_corpus(sents):return [" ".join(get_lac_results(sent)[0]) for sent in sents]def convert_tfidf(corpus):corpus = convert_corpus(corpus)vectorizer = CountVectorizer()count = vectorizer.fit_transform(corpus)words = vectorizer.get_feature_names()transformer = TfidfTransformer()tfidf = transformer.fit_transform(count)return words, tfidf

(3) 寻找无序数组中最大的k个值的索引

# 寻找无序数组中的最大的k个值的索引
def max_num(num_list, topk):max_num_idx = list(map(num_list.index, heapq.nlargest(topk, num_list)))return max_num_idx

(4) 得到关键词

words, tfidf = convert_tfidf(corpus)tf_idf   = numpy.array(tfidf.toarray()).sum(axis=0).tolist()  # 按行求和
# tf_idf = numpy.array(tfidf.toarray()).sum(axis=1).tolist()  # 按列求和max_idxs = max_num(tf_idf, topk=5)

6. 通过大规模语料计算IDF

(1) 常用中文语料

https://github.com/brightmart/nlp_chinese_corpus
https://github.com/SophonPlus/ChineseNlpCorpus

BM25

TextRank算法

[NLP --- 3] 文档检索算法TF-IDF相关推荐

  1. 关键词提取算法—TF/IDF算法

    关键词提取算法一般可分为有监督学习和无监督学习两类. 有监督的关键词提取方法可以通过分类的方式进行,通过构建一个较为完善的词表,然后判断每个文档与词表中的每个词的匹配程度,以类似打标签的方式,达到关键 ...

  2. 随笔_从《芳华》影评到TF/IDF算法

     前两天看好多<芳华>的影评说:为什么好人没好报?于是感叹一堆世态炎凉,人性丑陋什么的.我觉得这问题是:为什么中央空调(对谁都温暖)往往不被看好.  先说说TF/IDF算法,这是一种信息处 ...

  3. 搜索引擎:文本分类——TF/IDF算法

    原理 TFIDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类.TFIDF实际上是:TF * IDF,TF ...

  4. tf/idf_Neo4j:带密码的TF / IDF(和变体)

    tf/idf 几周前,我写了一篇博客文章,介绍了如何使用scikit-learn在HIMYM成绩单上运行TF / IDF,以按情节找到最重要的短语,然后我很好奇在Neo4j中很难做到. 我首先将Wik ...

  5. Neo4j:带密码的TF / IDF(和变体)

    几周前,我写了一篇博客文章,介绍了如何使用scikit-learn在HIMYM成绩单上运行TF / IDF,以按情节找到最重要的短语,然后我很好奇在Neo4j中很难做到. 我首先将Wikipedia的 ...

  6. tfidf算法 python_tf–idf算法解释及其python代码实现(下)

    tf–idf算法python代码实现 这是我写的一个tf-idf的简单实现的代码,我们知道tfidf=tf*idf,所以可以分别计算tf和idf值在相乘,首先我们创建一个简单的语料库,作为例子,只有四 ...

  7. scitkit-learn:计算机科学论文的TF / IDF和余弦相似度

    几个月前,我下载了数千篇计算机科学论文的元数据,这样我就可以尝试编写一个迷你推荐引擎来告诉我接下来应该读什么论文. 由于我没有任何人可以阅读每篇论文的数据,因此排除了协作过滤方法,所以我认为我可以尝试 ...

  8. 文本特征抽取的向量空间模型(VSM)和TF/IDF方法

    文本特征抽取 两组小说,一组是爱情的,另一组是科幻的.我们能否用支持向量机训练一个模型,用来识别小说类型呢? 这个并不容易.因为支持向量机这类机器学习算法只能接受数学里面的向量作为输入.如果用它来做文 ...

  9. tf-idf词向量和bow_使用词袋Bow和TF IDF进行多标签分类

    tf-idf词向量和bow 1.加载数据 (1. Load the data) For this study, we are using Kaggle data for Toxic Comment C ...

最新文章

  1. Jupyter安装r内核
  2. ubuntu 配置apt代理源
  3. 极致无边界!2021 神策数据 Tech-Day 即将开幕
  4. MYSQL----myownstars(102)
  5. i18n国际化登录页面
  6. SQLite学习笔记(十二)虚拟机指令
  7. 话里话外:按单制造企业用什么来做生产计划
  8. 毕竟这个世界互相适合的人太少了
  9. vim中替换字符串的方法有哪些
  10. 分享(Java中new一个对象的过程)
  11. vantfieldlabel样式修改_Vant Field 输入框
  12. 网络抖动多少ms算正常_网络延迟多少秒算正常
  13. Java 实现 百度地图
  14. 自建公众号服务器开发教程,01-微信公众号开发入门篇
  15. 群辉监控Surveillance Station不支持H265解决方案(解决群辉不支持的摄像头)
  16. 【树莓派】搭建OpenWrt软路由,并作为旁路由的配置与应用方法
  17. Office快捷键大全之一(Word快捷键)
  18. 两个div右侧固定,左侧自适应屏幕
  19. APP加固各种反调试
  20. C primer Plus 9.3.4 递归和倒序计算 DE3

热门文章

  1. 花呗部分用户已接入央行征信系统,快看你被选中了没?
  2. Linux查看软件安装和系统信息操作
  3. 服务器版本的ansys证书错误,关于ANSYS Workbench 出现证书错误的解决办法
  4. 数组的下标访问和指针访问方式效率分析比较
  5. MySQL索引(详细,1万字长文)
  6. ShardingJdbc入门
  7. 计算机学院刘岗,刘岗-中国科学院大学-UCAS
  8. inputstream流乱码_Java FileInputStream读中文乱码问题解决方案
  9. HDU 6047 Maximum Sequence 思维
  10. HTML+CSS+Javascript简易记账本(localStorage)