什么是余弦定理

学过向量代数的人都知道,向量实际上是多维空间中有方向的线段。如果两个向量的方向一致,即夹角接近零,那么这两个向量就相近。而要确定两个向量方向是否一致,这就要用到余弦定理计算向量的夹角了。

余弦定理对我们每个人都不陌生,它描述了三角形中任何一个夹角和三个边的关系,换句话说,给定三角形的三条边,我们可以用余弦定理求出三角形各个角的角度。假定三角形的三条边为 a, b 和 c,对应的三个角为 A, B 和 C,那么角 A 的余弦:

$$\cos {A} =\frac{b^2+c^2-a^2}{2bc}$$

如果我们将三角形的两边 b 和 c 看成是两个向量,那么上述公式等价于:

$$\cos {A} = \frac{}{|b||c|}$$

其中分母表示两个向量 b 和 c 的长度,分子表示两个向量的内积。举一个具体的例子,假如文本X 和文本 Y 对应向量分别是:

x_1,x_2,…,x_64000

y_1,y_2,…,y_64000

那么它们夹角的余弦等于:

$$\cos {\theta } = \frac{x_1y_1+x_2y_2+…+x_{64000}y_{64000}}{\sqrt{x_1^2+x_2^2+…+x_{64000}^2}\cdot \sqrt{y_1^2+y_2^2+…+y_{64000}^2}}$$

当两个文本向量夹角的余弦等于1时,这两个文本完全重复;当夹角的余弦接近于一时,两条新闻相似;夹角的余弦越小,两条文本越不相关。

计算文本相似度的大致流程

假设有下面两个句子:

A:我喜欢看电视,不喜欢看电影。

B:我不喜欢看电视,也不喜欢看电影。

第一步:分词

A:我/喜欢/看/电视,不/喜欢/看/电影。

B:我/不/喜欢/看/电视,也/不/喜欢/看/电影。

第二步:列出所有的词、字

我,喜欢,看,电视,电影,不,也

第三步:计算词频

A:我 1,喜欢 2,看 2,电视 1,电影 1,不 1,也 0。

B:我 1,喜欢 2,看 2,电视 1,电影 1,不 2,也 1。

第四步:描述词频向量

A:[1, 2, 2, 1, 1, 1, 0]

B:[1, 2, 2, 1, 1, 2, 1]

第五步:计算夹角余弦

使用这个公式,我们就可以得到,句子A与句子B的夹角的余弦。

余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似,这就叫”余弦相似性”。所以,上面的句子A和句子B是很相似。

实际使用过程需要注意的事项

实际使用中文本长度可能过长,如果采用分词,复杂度较高,可以采用TF-IDF的方式找出文章若干个关键词(比如20个),再进行比较。

文章的长度可能不一致,所以关键词词频率可以使用相对词频率。

由于计算中打乱了关键词出现的顺序,所以即使夹角余弦的值为1,也有可能文本并不重复。比如:

A:我喜欢看电视,不喜欢看电影。

B:我不喜欢看电视,喜欢看电影。

使用Python进行文本相似度计算

#!/usr/bin/env python

# -*- coding: utf-8 -*-

from __future__ import division

import jieba.analyse

from math import sqrt

class Similarity():

def __init__(self, target1, target2, topK=10):

self.target1 = target1

self.target2 = target2

self.topK = topK

def vector(self):

self.vdict1 = {}

self.vdict2 = {}

top_keywords1 = jieba.analyse.extract_tags(self.target1, topK=self.topK, withWeight=True)

top_keywords2 = jieba.analyse.extract_tags(self.target2, topK=self.topK, withWeight=True)

for k, v in top_keywords1:

self.vdict1[k] = v

for k, v in top_keywords2:

self.vdict2[k] = v

def mix(self):

for key in self.vdict1:

self.vdict2[key] = self.vdict2.get(key, 0)

for key in self.vdict2:

self.vdict1[key] = self.vdict1.get(key, 0)

def mapminmax(vdict):

"""计算相对词频"""

_min = min(vdict.values())

_max = max(vdict.values())

_mid = _max - _min

#print _min, _max, _mid

for key in vdict:

vdict[key] = (vdict[key] - _min)/_mid

return vdict

self.vdict1 = mapminmax(self.vdict1)

self.vdict2 = mapminmax(self.vdict2)

def similar(self):

self.vector()

self.mix()

sum = 0

for key in self.vdict1:

sum += self.vdict1[key] * self.vdict2[key]

A = sqrt(reduce(lambda x,y: x+y, map(lambda x: x*x, self.vdict1.values())))

B = sqrt(reduce(lambda x,y: x+y, map(lambda x: x*x, self.vdict2.values())))

return sum/(A*B)

if __name__ == '__main__':

t1 = '''余弦定理和新闻的分类似乎是两件八杆子打不着的事,但是它们确有紧密的联系。具体说,新闻的分类很大程度上依靠余弦定理。Google 的新闻是自动分类和整理的。所谓新闻的分类无非是要把相似的新闻放到一类中。计算机其实读不懂新闻,它只能快速计算。这就要求我们设计一个算法来算出任意两篇新闻的相似性。为了做到这一点,我们需要想办法用一组数字来描述一篇新闻。我们来看看怎样找一组数字,或者说一个向量来描述一篇新闻。回忆一下我们在“如何度量网页相关性”一文中介绍的TF/IDF 的概念。对于一篇新闻中的所有实词,我们可以计算出它们的单文本词汇频率/逆文本频率值(TF/IDF)。不难想象,和新闻主题有关的那些实词频率高,TF/IDF 值很大。我们按照这些实词在词汇表的位置对它们的 TF/IDF 值排序。比如,词汇表有六万四千个词,分别为'''

t2 = '''新闻分类——“计算机的本质上只能做快速运算,为了让计算机能够“算”新闻”(而不是读新闻),就要求我们先把文字的新闻变成一组可计算的数字,然后再设计一个算法来算出任何两篇新闻的相似性。“——具体做法就是算出新闻中每个词的TF-IDF值,然后按照词汇表排成一个向量,我们就可以对这个向量进行运算了,那么如何度量两个向量?——向量的夹角越小,那么我们就认为它们更相似,而长度因为字数的不同并没有太大的意义。——如何计算夹角,那就用到了余弦定理(公式略)。——如何建立新闻类别的特征向量,有两种方法,手工和自动生成。至于自动分类的方法,书本上有介绍,我这里就略过了。很巧妙,但是我的篇幅肯定是放不下的。除余弦定理之外,还可以用矩阵的方法对文本进行分类,但这种方法需要迭代很多次,对每个新闻都要两两计算,但是在数学上有一个十分巧妙的方法——奇异值分解(SVD)。奇异值分解,就是把上面这样的大矩阵,分解为三个小矩阵的相乘。这三个小矩阵都有其物理含义。这种方法能够快速处理超大规模的文本分类,但是结果略显粗陋,如果两种方法一前一后结合使用,既能节省时间,又提高了精确性。'''

topK = 10

s = Similarity(t1, t2, topK)

print s.similar()

参考文章:

python余弦定理_余弦定理与文本相似度相关推荐

  1. python 余弦定理_自己实现文本相似度算法(余弦定理)

    最近由于工作项目,需要判断两个txt文本是否相似,于是开始在网上找资料研究,因为在程序中会把文本转换成String再做比较,所以最开始找到了这篇关于 距离编辑算法 Blog写的非常好,受益匪浅. 于是 ...

  2. java算法余弦定律_自己实现文本相似度算法(余弦定理) - 呼吸的Java - 开源中国社区...

    自己实现文本相似度算法(余弦定理) 52人收藏此文章, 我要收藏 发表于9个月前(2012-03-04 16:59) , 已有5592次阅读 ,共6个评论 最近由于工作项目,需要判断两个txt文本是否 ...

  3. python汉明距离_simhash+汉明距离计算文本相似度

    ****由于最近需要做大规模的文本相似度的计算,所以用到了simhash+汉明距离来快速计算文本的相似度.** **simhash的原理如下图:其中的weight采用的是jieba的tf-idf的结果 ...

  4. python 文本相似度现状_python文本相似度分析

    如何用python计算文本的相似度 同学欢迎来到CSS布局HTML~文本的相似度计算是NLP(自然语言处理)方向的范畴,感兴趣可以找相关的书籍详细学习研究.同学问的这个问题,可以搜索:python文本 ...

  5. java 余弦定理_文本相似度计算之余弦定理

    前言 余弦相似度,又称为余弦相似性,是通过计算两个向量的夹角余弦值来评估他们的相似度.余弦相似度将向量根据坐标值,绘制到向量空间中.用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小.余弦值 ...

  6. python余弦定理求角_python实现的文本相似度算法(余弦定理)

    只对汉字进行相似度分析,以单个字为向量,然后每个字在章节中出现的次数,便是以此字向量的值.现在我们假设: 章节1中出现的字为:Z1c1,Z1c2,Z1c3,Z1c4--Z1cn:它们在章节中的个数为: ...

  7. python 文本相似度_python实现的文本相似度算法(余弦定理)

    只对汉字进行相似度分析,以单个字为向量,然后每个字在章节中出现的次数,便是以此字向量的值.现在我们假设: 章节1中出现的字为:Z1c1,Z1c2,Z1c3,Z1c4--Z1cn:它们在章节中的个数为: ...

  8. Java实现余弦定理计算文本相似度

    相似度度量(Similarity),即计算个体间的相似程度,相似度度量的值越小,说明个体间相似度越小,相似度的值越大说明个体差异越大. 对于多个不同的文本或者短文本对话消息要来计算他们之间的相似度如何 ...

  9. nlp文本相似度_用几行代码在Python中搜索相似文本:一个NLP项目

    nlp文本相似度 自然语言处理 (Natural Language Processing) 什么是自然语言处理? (What is Natural Language Processing?) Natu ...

最新文章

  1. day22_面向对象
  2. jsp 环境配置记录
  3. [转] Zend studio中开发常用
  4. Asp.net的Session和Cookie传值方式
  5. 归并排序之——二路归并(c/c++)
  6. JavaWeb学习总结(九)--JDBC入门
  7. Makefile中的变量和shell变量
  8. 寒窗苦读十多年,我的毕业论文只研究了一个「屁」
  9. python中连续两个小于号_Python语言描述最大连续子序列和
  10. vue v-if 和 v-show 的知识点
  11. Solarwinds实现MSN报警
  12. MySQL数据库入门学习
  13. 网络安全(二)安全基础
  14. NPN和PNP三极管原理以及应用电路设计
  15. SASE 本质探究(1):什么是云化
  16. python进行电子取证
  17. 随记 C#读取TXT文件乱码
  18. 【物联网】23.物联网开发之感测系统 - GPS(GNSS)
  19. L2+ 概念要火!英伟达和英特尔都释放了什么信号?| CES 2019 ...
  20. 通过ONIE安装NOS系统

热门文章

  1. ZigBee 3.0实战教程-Silicon Labs EFR32+EmberZnet-3-01:BootLoader+Application的开发模式
  2. myeclipse 2015 stable2.0破解安装教程
  3. ContraD论文部分翻译与解读(Training GANs with Stronger Augmentations via Contrastive Discriminator)
  4. selenium 自动化测试工具(二)常用定位方式
  5. 用分治法查找数组元素的最大值和最小值
  6. mac重装系统 未能与恢复服务器,Mac系统重装后数据可不可以恢复
  7. MySQL-老杜学习笔记
  8. 282.软件体系结构的风格与模式
  9. 500套优秀简历模板,送给您!
  10. MATLAB基本操作及概念