一种基于 Numpy 的 TF-IDF 实现报告

摘要

本文使用了一种 state-of-the-art 的矩阵表示方法来计算每个词在每篇文章上的 TF-IDF 权重(特征)。本文还将介绍基于 TF-IDF 的文档相似度查询方法。

系统介绍

本节将着重介绍我的 TF-IDF 系统使用方法。

本系统由以下五部分组成

  • utility.py - 自己写的常用库函数封装
  • merge.py - 把白老师给的4个excel表格合并成一个excel表格
  • extraction.py - 从合并后的excel表格中抽取“公众号名称”、“文章标题”和“文章内容”,然后将这些内容分词然后合并
  • tf-idf.py - 基于合并、分词后的语料计算其每一个在每一个文档上的TF-IDF特征值,得到一个二维矩阵。本系统使用了一种 state-of-the-art 的二维矩阵存储方式,本文后面的章节将着重介绍。
  • query.py - 基于离线计算好的tf-idf特征,返回与该查询最接近的文档。

系统操作流程

Step 1. 合并 N 张Excel表格,将会得到 corpus.xls

python3 merge.py

Step 2. 基于 corpus.xls 进行二次抽取、分词、合并,得到分词后的文档集合 docs.txt

python3 extraction.py

Step 3. 基于 docs.txt 得到词汇表,然后计算每一个词在每一个文档上的 TF-IDF 特征。截至到该步骤,目前进行的处理都属于离线的(off-line),也即预先生成好的,在用户提交具体查询时将不再进行运行以上步骤的查询。所以需要把一些必要的数据保存下来,以备在线程序(on-line)直接采用 [3]。

执行本程序后,会得到词表文件 vocab.txt,TF-IDF特征文件 tf-idf.npy

python3 TF-IDF.py

Step 4. 基于用户的查询返回结果

python3 query.py

TF-IDF

数学公式计算公式为:

\[TF_{term} = \frac{count(term)}{len(doc)} = \frac{关键词在文档中出现的次数}{文档总次数} \quad(相当于把 TF 进行了归一化)\\
IDF_{term} = \log{\frac{D}{D_w}} = \log\frac{总文档数}{含有关键词的文档数} \\
TF \cdot IDF_{term} = TF_{term} \times IDF_{term}
\]

计算 TF-IDF 的例子

该例子的灵感受启发于文献[1]

假设我们有如下三个文档:

  1. 人工智能 的 应用
  2. 机器学习 与 人工智能
  3. 自然语言处理 的 应用

我们想要得到每个词在每篇文档上的 TF-IDF 权重,我们首先要得到 TF 表格,如下表所示

文档 \ TF \ 词汇 人工智能 应用 机器学习 自然语言处理
doc 1 1 1 1
doc 2 1 1 1
doc 3 1 1 1

然后要求得 IDF 表格,如下表所示(log1.5 = 0.18, log3=0.48)

文档 \ IDF \ 词汇 人工智能 应用 机器学习 自然语言处理
doc 1 log1.5=0.18 log1.5=0.18 log1.5=0.18
doc 2 log1.5=0.18 log3=0.48 log3=0.48
doc 3 log1.5=0.18 log1.5=0.18 log3=0.48

最后求得 TF-IDF 表格,如下表所示

文档 \ TF-IDF \ 词汇 人工智能 应用 机器学习 自然语言处理
doc 1 0.18 0.18 0.18
doc 2 0.18 0.48 0.48
doc 3 0.18 0.18 0.48

找出与查询最相似的文档

如何找出与查询(query)最相似的文档呢?

文献[1] 给出了一种计算方法,比如我们要查询 “人工智能 与 自然语言处理”,三个文档的TF-IDF值分别为

\[\begin{align}
TF-IDF_{doc1} &=0.18 + 0 + 0 &= 0.18 \\
TF-IDF_{doc2} &=0.18 + 0.48 + 0 &= 0.66 \\
TF-IDF_{doc3} &=0 + 0 + 0.48& = 0.48
\end{align}
\]

于是得到文档与查询(人工智能 与 自然语言处理)的相似度排序为:

doc2 > doc3 > doc1

Python中的二维矩阵表示方法

基于二维数组的方法

声明一个三行两列的矩阵,传统的基于二维数组表示方法为

row = 3
col = 2
matrix = [[0 for c in range(col)] for r in range(row)]

这种方法的缺点有:

  1. 占用内存大
  2. 代码复杂
  3. 没有相关配套库函数支持

基于 Numpy

基于numpy的方法有很多好处:

  1. 占用内存小(底层是使用C语言写成的Python拓展)
  2. API简单
  3. 强大的相关库函数支持
  4. 程序健壮、代码短少、易于调试等等

声明一个三行两列的矩阵,代码如下

import numpy as np
matrix = np.zeros(shape=[3,2])

基于 Numpy 实现的 TF-IDF 程序详解

def tf(table, vocab, docs):
for r in range(len(docs)):
for w in docs[r]:
c = vocab.index(w)
table[r][c] = table[r][c] + 1 #numpy的矩阵的元素存取方式与二维数组无异,都是用[]操作符
table[r] = table[r] / len(docs[r]) #table[r]取第r行的一整行数据,其每个元素均除以同一个数
return table def idf(table, D):
for c in range(table.shape[1]): #shape返回一个元组——(行,列)
tf = table[:, c] #以行的形式,返回第c列
Dw = np.count_nonzero(tf) #计算向量/矩阵中非零元素的数目
idf = math.log(D/Dw)
table[:, c] = table[:, c] * idf #以列的形式返回第c列
return table table = np.zeros(shape=(len(docs), len(vocab))) #声明矩阵,行数是文档总数,列数是词汇总数
table = tf(table, vocab, docs)
table = idf(table, len(docs))

参考文献

[1] 吴军. 《数学之美(第二版)》. 人民邮电出版社[M]

[2] 白宇. 信息检索概述KERC2016. [PPT]

[3] Mark Allen Weiss(美). 冯舜玺(译). 《数据结构与算法分析——C语言描述》. 2004. 机械工业出版社[M]

一种基于 Numpy 的 TF-IDF 实现报告的更多相关文章

  1. Elasticsearch由浅入深(十)搜索引擎:相关度评分 TF&IDF算法、doc value正排索引、解密query、fetch phrase原理、Bouncing Results问题、基于scoll技术滚动搜索大量数据

    相关度评分 TF&IDF算法 Elasticsearch的相关度评分(relevance score)算法采用的是term frequency/inverse document frequen ...

  2. 基于TF/IDF的聚类算法原理

        一.TF/IDF描述单个term与特定document的相关性TF(Term Frequency): 表示一个term与某个document的相关性. 公式为这个term在document中出 ...

  3. 信息检索中的TF/IDF概念与算法的解释

    https://blog.csdn.net/class_brick/article/details/79135909 概念 TF-IDF(term frequency–inverse document ...

  4. TF/IDF(term frequency/inverse document frequency)

    TF/IDF(term frequency/inverse document frequency) 的概念被公认为信息检索中最重要的发明. 一. TF/IDF描述单个term与特定document的相 ...

  5. [开发技巧]·Python极简实现滑动平均滤波(基于Numpy.convolve)

    [开发技巧]·Python极简实现滑动平均滤波(基于Numpy.convolve) ​ 1.滑动平均概念 滑动平均滤波法(又称递推平均滤波法),时把连续取N个采样值看成一个队列 ,队列的长度固定为N ...

  6. tf idf公式及sklearn中TfidfVectorizer

    在文本挖掘预处理之向量化与Hash Trick中我们讲到在文本挖掘的预处理中,向量化之后一般都伴随着TF-IDF的处理,那么什么是TF-IDF,为什么一般我们要加这一步预处理呢?这里就对TF-IDF的 ...

  7. 25.TF&IDF算法以及向量空间模型算法

    主要知识点: boolean model IF/IDF vector space model     一.boolean model     在es做各种搜索进行打分排序时,会先用boolean mo ...

  8. 深度学习基础-基于Numpy的卷积神经网络(CNN)实现

    本文是深度学习入门: 基于Python的实现.神经网络与深度学习(NNDL)以及动手学深度学习的读书笔记.本文将介绍基于Numpy的卷积神经网络(Convolutional Networks,CNN) ...

  9. [信安Presentation]一种基于GPU并行计算的MD5密码解密方法

    -------------------paper--------------------- 一种基于GPU并行计算的MD5密码解密方法 0.abstract1.md5算法概述2.md5安全性分析3.基 ...

随机推荐

  1. cocos2d JS 在 JavaScript 中,怎样把一个对象转化成 JSON 字符串?

    为什么今天要做这样子的操作,原因很简单,因为cocos JS 的本地缓存储存不了对象,所以当我通过本地缓存的 key和value来取值的时候就取不出来来,json的消息数据是一个对象来的,然而在做牌局 ...

  2. Windows jmeter配置

    JMeter是Apache软件基金会的产品,用于对提供静态的和动态的资源服务器性能的测试.是一款很方便的测试软件. JMeter 要依附Java SE 环境 所以在启用JMeter之前要安装JAVA ...

  3. Hibernate框架的第四天

    ## Hibernate框架的第四天 ## ---------- **回顾:Hibernate框架的第三天** 1. 一对多关联关系映射 * JavaBean的编写 * 编写映射的配置文件 * 使用级 ...

  4. db2字符串相关函数的使用

    db2字符串相关函数的使用 from :internet    一.字符转换函数 1.ASCII() 返回字符表达式最左端字符的ASCII 码值.在ASCII()函数中,纯数字的字符串可不用‘’括起来 ...

  5. [ Learning ] Spring Resources

    1. Spring MVC Spring MVC原理及配置详解 springMVC系列之(三) spring+springMVC集成(annotation方式) Mybatis3+Spring4+Sp ...

  6. 事件响应模型(游戏引擎、JAVA中等应用)

    事件,我们在生活中时时在产生事件并且做出响应,如早晨出门时,看见外面下雨了,这时候我们需要带把伞等情况! 在现实生活之中事件分为人为事件和自然事件,那么在计算机操作系统中也不例外,存在两种事件 1.人 ...

  7. Keras中使用LSTM层时设置的units参数是什么

    https://www.zhihu.com/question/64470274 http://colah.github.io/posts/2015-08-Understanding-LSTMs/ ht ...

  8. EasyUI创建DataGrid及冻结列的两种方式

       第一种方式:通过HTML标签创建数据表格控件 <table class="easyui-datagrid" title="基本数据表格" style ...

  9. 什么是Unicode

    写这篇博客的原因, 从做软件开始,什么ASCII码, Unicode,UTF-8,UTF-16,UTF-32......这些鬼东西总是经常碰到,只知道这些鬼是编码格式,其他的就啥都不清楚了,既然总是遇 ...

  10. BP神经网络的直观推导与Java实现

    人工神经网络模拟人体对于外界刺激的反应.某种刺激经过人体多层神经细胞传递后,可以触发人脑中特定的区域做出反应.人体神经网络的作用就是把某种刺激与大脑中的特定区域关联起来了,这样我们对于不同的刺激就可以 ...