余弦cos计算相似度

余弦计算相似度度量

相似度度量(Similarity),即计算个体间的相似程度,相似度度量的值越小,说明个体间相似度越小,相似度的值越大说明个体差异越大。

对于多个不同的文本或者短文本对话消息要来计算他们之间的相似度如何,一个好的做法就是将这些文本中词语,映射到向量空间,形成文本中文字和向量数据的映射关系,通过计算几个或者多个不同的向量的差异的大小,来计算文本的相似度。下面介绍一个详细成熟的向量空间余弦相似度方法计算相似度

向量空间余弦相似度(Cosine Similarity)

余弦相似度用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小。余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似,这就叫"余弦相似性"。

上图两个向量a,b的夹角很小可以说a向量和b向量有很高的的相似性,极端情况下,a和b向量完全重合。如下图:

如上图二:可以认为a和b向量是相等的,也即a,b向量代表的文本是完全相似的,或者说是相等的。如果a和b向量夹角较大,或者反方向。如下图

如上图三: 两个向量a,b的夹角很大可以说a向量和b向量有很底的的相似性,或者说a和b向量代表的文本基本不相似。那么是否可以用两个向量的夹角大小的函数值来计算个体的相似度呢?

向量空间余弦相似度理论就是基于上述来计算个体相似度的一种方法。下面做详细的推理过程分析。

想到余弦公式,最基本计算方法就是初中的最简单的计算公式,计算夹角

 

图(4)

的余弦定值公式为:

但是这个是只适用于直角三角形的,而在非直角三角形中,余弦定理的公式是

图(5)

三角形中边a和b的夹角 的余弦计算公式为:

公式(2)

在向量表示的三角形中,假设a向量是(x1, y1),b向量是(x2, y2),那么可以将余弦定理改写成下面的形式:

图(6)

向量a和向量b的夹角 的余弦计算如下

 

扩展,如果向量a和b不是二维而是n维,上述余弦的计算法仍然正确。假定a和b是两个n维向量,a是  ,b是  ,则a与b的夹角 的余弦等于:

余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似,夹角等于0,即两个向量相等,这就叫"余弦相似性"。

【下面举一个例子,来说明余弦计算文本相似度】

    举一个例子来说明,用上述理论计算文本的相似性。为了简单起见,先从句子着手。

         句子A:这只皮靴号码大了。那只号码合适

句子B:这只皮靴号码不小,那只更合适

怎样计算上面两句话的相似程度?

基本思路是:如果这两句话的用词越相似,它们的内容就应该越相似。因此,可以从词频入手,计算它们的相似程度。

第一步,分词

句子A:这只/皮靴/号码/大了。那只/号码/合适。

句子B:这只/皮靴/号码/不/小,那只/更/合适。

第二步,列出所有的词。

这只,皮靴,号码,大了。那只,合适,不,小,很

第三步,计算词频。

句子A这只1,皮靴1,号码2,大了1。那只1,合适1,不0,小0,更0

句子B这只1,皮靴1,号码1,大了0。那只1,合适1,不1,小1,更1

第四步,写出词频向量。

  句子A:(1,1,2,1,1,1,0,0,0)

  句子B:(1,1,1,0,1,1,1,1,1)

到这里,问题就变成了如何计算这两个向量的相似程度。我们可以把它们想象成空间中的两条线段,都是从原点([0, 0, ...])出发,指向不同的方向。两条线段之间形成一个夹角,如果夹角为0度,意味着方向相同、线段重合,这是表示两个向量代表的文本完全相等;如果夹角为90度,意味着形成直角,方向完全不相似;如果夹角为180度,意味着方向正好相反。因此,我们可以通过夹角的大小,来判断向量的相似程度。夹角越小,就代表越相似。

使用上面的公式(4)

 

计算两个句子向量

句子A:(1,1,2,1,1,1,0,0,0)

和句子B:(1,1,1,0,1,1,1,1,1)的向量余弦值来确定两个句子的相似度。

计算过程如下:

计算结果中夹角的余弦值为0.81非常接近于1,所以,上面的句子A和句子B是基本相似的

由此,我们就得到了文本相似度计算的处理流程是:

    (1)找出两篇文章的关键词;

 (2)每篇文章各取出若干个关键词,合并成一个集合,计算每篇文章对于这个集合中的词的词频

 (3)生成两篇文章各自的词频向量;

 (4)计算两个向量的余弦相似度,值越大就表示越相似。


转自: http://blog.youkuaiyun.com/u012160689/article/details/15341303

<think>好的,用户想用夹角余弦计算相似度矩阵的Matlab代码。首先,我需要回忆一下夹角余弦法的定义和公式。夹角余弦相似度是通过计算两个向量的余弦值来衡量它们的相似性,公式是cosθ = (A·B)/(||A|| ||B||)。这个值在-1到1之间,值越大表示越相似。 接下来,用户需要的是Matlab实现。我应该先考虑如何将这一公式转化为代码。Matlab中矩阵运算很方便,特别是向量化操作可以避免循环,提高效率。假设输入数据是一个矩阵,每行代表一个样本,每列是特征。那么相似度矩阵的计算应该是每两个样本之间的余弦相似度。 首先,我需要计算每个向量的模长。可以用sqrt(sum(A.^2, 2)),这样得到一个列向量。然后,点积可以通过矩阵乘法实现,比如A乘以A的转置,这样得到的矩阵每个元素就是对应行的点积。最后,将点积矩阵除以模长向量的外积,也就是模长向量乘以模长向量的转置,得到一个归一化的矩阵。 不过,用户提供的引用中提到了调整余弦相似度,需要减去均值。用户的问题是否也需要调整呢?根据用户的问题描述,他直接提到夹角余弦法,可能不需要调整,但可能需要确认。不过示例引用中有调整余弦的代码,比如引用[2]中的adjusted_cos_distance_matrix函数,但用户现在可能只需要基础版本。因此,我应该先提供基础的余弦相似度代码,然后如果有需要再补充调整后的版本。 另外,用户提供的引用[3]提到余弦相似度对数值不敏感的问题,调整余弦可以解决这个问题。所以,在回答中可能需要提到两种方法,但用户当前的需求是基础版,所以代码应该以基础为主,然后补充说明调整余弦的方法作为扩展。 接下来,编写Matlab代码。假设数据矩阵data的每一行是一个样本,计算相似度矩阵的步骤: 1. 计算每个样本的模长:norm_rows = sqrt(sum(data.^2, 2)); 2. 计算点积矩阵:dot_product = data * data'; 3. 计算模长乘积矩阵:norm_matrix = norm_rows * norm_rows'; 4. 余弦相似度矩阵:cos_sim = dot_product ./ norm_matrix; 5. 处理分母为零的情况,将NaN替换为0。 这样得到的cos_sim矩阵就是相似度矩阵。需要注意的是,当两个向量的模长为零时,分母为零会导致NaN,这种情况下相似度可以设为0或者根据具体情况处理。 然后,在代码示例中展示如何实现这一点。同时,根据引用[3],可以提到调整余弦相似度的做法,即先对每个特征减去均值,然后再计算余弦相似度。这可能作为优化或改进的部分。 用户可能还需要了解如何应用这个相似度矩阵,比如在推荐系统或聚类分析中的使用,但根据问题,主要需求是代码实现。不过,按照系统指令,需要生成相关问题,可能包括应用场景、不同相似度方法的比较,以及如何处理数据预处理等。 最后,检查代码是否符合Matlab语法,使用合适的函数,比如bsxfun或者直接矩阵运算。在旧版Matlab中,bsxfun可能更高效,但现代版本支持隐式扩展,所以直接使用./即可。同时,处理分母为零的情况,可以使用isnan函数替换为0。 总结步骤,写出代码示例,并解释关键步骤。然后根据引用内容,指出调整余弦相似度的必要性,并给出相应的代码调整。最后,生成相关问题,帮助用户进一步了解相关主题。</think>### 基于夹角余弦法的相似度矩阵计算实现 #### 1. 基本原理 夹角余弦法通过计算向量间夹角的余弦值衡量相似度,公式为: $$ \cos(\theta) = \frac{\mathbf{A} \cdot \mathbf{B}}{\|\mathbf{A}\| \|\mathbf{B}\|} $$ 值域为$[-1,1]$,值越大表示向量方向越接近[^3][^4]。 #### 2. MATLAB代码实现 ```matlab function similarity_matrix = cosine_similarity_matrix(data) % 计算每行向量的L2范数 norms = sqrt(sum(data.^2, 2)); % 计算点积矩阵 dot_products = data * data'; % 计算范数外积矩阵(避免除零错误) norm_matrix = norms * norms'; norm_matrix(norm_matrix == 0) = eps; % 极小值替换零 % 计算余弦相似度矩阵 similarity_matrix = dot_products ./ norm_matrix; % 处理特殊值 similarity_matrix(isnan(similarity_matrix)) = 0; end ``` #### 3. 代码说明 - **输入参数**:`data`为$m \times n$矩阵,每行表示一个样本,每列表示特征 - **输出结果**:$m \times m$相似度矩阵,对角线为1 - **关键步骤**: 1. 计算每个向量的L2范数:$\sqrt{\sum x_i^2}$ 2. 通过矩阵乘法高效计算所有向量对的点积 3. 使用外积生成范数乘积矩阵 4. 处理零分母问题(出现于全零向量) #### 4. 改进方法(调整余弦相似度) 针对评分数据需进行均值中心化处理[^3]: ```matlab adjusted_data = data - mean(data, 2); % 行均值中心化 similarity_matrix = cosine_similarity_matrix(adjusted_data); ``` #### 5. 应用示例 ```matlab % 生成测试数据(用户-商品评分矩阵) data = [4 5 0 2; 3 4 4 1; 5 0 3 3]; % 计算相似度矩阵 sim_matrix = cosine_similarity_matrix(data); % 可视化结果 imagesc(sim_matrix); colorbar; ``` #### 6. 结果解读 输出为$3 \times 3$矩阵,对角线为1,其他元素表示样本间相似度。例如`sim_matrix(1,2)=0.83`表示样本1与样本2的余弦相似度为83%[^4]。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值