标签: cosine-similarity

使用具有余弦相似性的K-means - Python


我试图Kmeans在python中实现算法,它将使用cosine distance而不是欧几里德距离作为距离度量.
我知道使用不同的距离函数可能是致命的,应该仔细进行.使用余弦距离作为度量迫使我改变平均函数(根据余弦距离的平均值必须是归一化向量的元素平均值的元素).

我已经看到了这种手动覆盖sklearn的距离函数的优雅解决方案,我想使用相同的技术来覆盖代码的平均部分,但我找不到它.

有谁知道怎么做?
距离度量不满足三角不等式有多重要?
如果有人知道kmeans的不同有效实现,我使用余弦度量或满足距离和平均函数,它也将是真正有用的.
非常感谢你!

编辑:
使用角距离而不是余弦距离后,代码看起来像这样:

def KMeans_cosine_fit(sparse_data, nclust = 10, njobs=-1, randomstate=None):
    # Manually override euclidean
    def euc_dist(X, Y = None, Y_norm_squared = None, squared = False):
        #return pairwise_distances(X, Y, metric = 'cosine', n_jobs = 10)
        return np.arccos(cosine_similarity(X, Y))/np.pi
    k_means_.euclidean_distances = euc_dist
    kmeans = k_means_.KMeans(n_clusters = nclust, n_jobs = njobs, random_state = randomstate)
    _ = kmeans.fit(sparse_data)
    return kmeans
Run Code Online (Sandbox Code Playgroud)

我注意到(通过数学计算)如果向量被归一化,则标准平均值适用于角度量.据我了解,我必须改变_mini_batch_step()k_means_.py.但功能非常复杂,我无法理解如何做到这一点.
有谁知道替代解决方案?
或许,有没有人知道我怎么能用一个总是迫使质心标准化的功能来编辑这个功能?

python k-means cosine-similarity scikit-learn sklearn-pandas

10
推荐指数
3
解决办法
6991
查看次数

在一组向量中找到最佳余弦相似度

我有n个向量,每个向量都有m个元素(实数).我想找到所有对中余弦相似度最大的对.

直接的解决方案需要O(n 2 m)的时间.

有没有更好的解决方案?

更新

余弦相似度/距离和三角方程激励我,我可以用"弦长"代替"余弦相似度",这会损失精度,但会大大提高速度.(有很多现有解决方案解决度量空间中的最近邻,如ANN)

algorithm math cosine-similarity

9
推荐指数
1
解决办法
3414
查看次数

Postgres:用于一对多搜索的浮点数组的余弦相似性索引

两个相等大小的矢量(实数)之间的余弦相似性被定义为点积乘以规范的乘积.

为了表示向量,我有一个大型float数组表,例如CREATE TABLE foo(vec float[])'.给定一个特定的float数组,我需要快速(使用索引,而不是seqscan)通过余弦相似性找到该表中最接近的数组,例如SELECT * FROM foo ORDER BY cos_sim(vec, ARRAY[1.0, 4.5, 2.2]) DESC LIMIT 10; 但我该怎么用?

pg_trgm余弦相似度的支持是不同的.它比较文本,我不确定它究竟是做什么的.称为smlar(此处)的扩展也对浮点数组具有余弦相似性支持,但是又做了不同的事情.我所描述的通常用于数据分析以比较文档的特征,所以我认为Postgres会支持它.

postgresql cosine-similarity

8
推荐指数
2
解决办法
2115
查看次数

matlab中的余弦相似度内置函数

我想在matlab中计算矩阵的不同行之间的余弦相似度.我在matlab中编写了以下代码:

for i = 1:n_row
    for j = i:n_row
        S2(i,j) = dot(S1(i,:), S1(j,:)) / (norm_r(i) * norm_r(j));
        S2(j,i) = S2(i,j);
Run Code Online (Sandbox Code Playgroud)

矩阵S1为11000*11000,代码执行非常耗时.所以,我想知道matlab中是否有任何函数可以比上面的代码更快地计算矩阵行之间的余弦相似度?

matlab matrix cosine-similarity

8
推荐指数
2
解决办法
3111
查看次数

在使用余弦相似度之前是否有任何理由(不)对向量进行 L2 归一化?

我正在阅读 Levy 等人的论文“Improving Distributional Comparison\nwith Lessons Learned from Word Embeddings”,在讨论他们的超参数时,他们说:

\n\n
\n

向量归一化 (nrm)正如第 2 节中提到的,所有向量(即 W\xe2\x80\x99s 行)都归一化为单位长度(L2 归一化),使点积运算等效于余弦相似度。

\n
\n\n

然后我想起sim2Rtext2vec包中向量相似度函数的默认值首先是 L2 范数向量:

\n\n
sim2(x, y = NULL, method = c("cosine", "jaccard"), norm = c("l2", "none"))\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以我想知道,归一化余弦(无论是在 text2vec 方面还是一般情况下)的动机可能是什么。我尝试阅读 L2 范数,但大多数情况下它是在使用欧几里德距离之前进行标准化的背景下出现的。我(令人惊讶地)找不到任何关于在词向量空间/嵌入的余弦相似性的情况下是否推荐或反对 L2 范数的任何信息。而且我不太具备计算分析差异的数学技能。

\n\n

所以这里有一个问题,意味着在从文本数据学习的词向量空间的背景下(要么只是可能由 tfidf、ppmi 等加权的共现矩阵;或者像 GloVe 这样的嵌入),并计算词相似度(目标是当然使用最能反映现实世界单词相似性的向量空间+度量)。
简而言之,在计算向量/单词之间的余弦相似度之前,是否有任何理由(不)在单词特征矩阵/术语共现矩阵上使用 L2 范数?

\n

normalization cosine-similarity vector-space text2vec

8
推荐指数
2
解决办法
1万
查看次数

如何有效地计算数百万字符串之间的余弦相似度

我需要计算列表中字符串之间的余弦相似度.例如,我有一个超过1000万个字符串的列表,每个字符串必须确定它自己与列表中的每个其他字符串之间的相似性.什么是我可以用来有效和快速完成这项任务的最佳算法?分而治之算法是否适用?

编辑

我想确定哪些字符串与给定字符串最相似,并且能够获得与相似性相关的度量/分数.我认为我想做的事情与群集相符合,群集的数量最初并不为人所知.

python java algorithm divide-and-conquer cosine-similarity

7
推荐指数
1
解决办法
1684
查看次数

用户之间通过选择的远程属性加权相似性的算法/实现方法是什么?

数据结构:

User has many Profiles
    (Limit - no more than one of each profile type per user, no duplicates)
Profiles has many Attribute Values
    (A user can have as many or few attribute values as they like)
Attributes belong to a category
    (No overlap. This controls which attribute values a profile can have)
Run Code Online (Sandbox Code Playgroud)

实施例/上下文:

我相信通过堆栈交换,您可以为一个用户提供许多配置文件,因为它们因交换站点不同而不同?在这个问题:

  • 配置文件:视频,因此视频配置文件仅包含视频类别的属性
  • 属性,因此视频类别中的属性可以是流派
  • 属性值,例如喜剧,动作,惊悚都是属性值

配置文件和属性只是在两个级别上对属性值进行分组的方法.如果没有分组(在2.之后加权需要),关系就是User hasMany Attribute Values.

问题:

为每个用户提供其他用户相似的评级.

  1. 基于与用户关联的所有属性值的相似性.
    • 平/一层
    • 两个用户之间的属性值数量不等
    • 每个用户只能选择一次属性值,因此不能重复
    • 因此,具有余弦相似性的二进制字符串/布尔数组?
  2. 1 +重量配置文件 …

algorithm similarity match weighted cosine-similarity

7
推荐指数
1
解决办法
2191
查看次数

word2vec,总和或平均字嵌入?

我使用word2vec来表示一个小短语(3到4个单词)作为一个独特的向量,通过添加每个单独的嵌入或通过计算单词嵌入的平均值.

从我做过的实验中,我总是得到相同的余弦相似度.我怀疑它与训练后word2vec生成的单词长度(单位长度(Euclidean norm))有关吗?或者我在代码中有BUG,或者我遗漏了一些东西.

这是代码:

import numpy as np
from nltk import PunktWordTokenizer
from gensim.models import Word2Vec
from numpy.linalg import norm
from scipy.spatial.distance import cosine

def pattern2vector(tokens, word2vec, AVG=False):
    pattern_vector = np.zeros(word2vec.layer1_size)
    n_words = 0
    if len(tokens) > 1:
        for t in tokens:
            try:
                vector = word2vec[t.strip()]
                pattern_vector = np.add(pattern_vector,vector)
                n_words += 1
            except KeyError, e:
                continue
        if AVG is True:
            pattern_vector = np.divide(pattern_vector,n_words)
    elif len(tokens) == 1:
        try:
            pattern_vector = word2vec[tokens[0].strip()]
        except KeyError:
            pass
    return pattern_vector


def main():
    print "Loading …
Run Code Online (Sandbox Code Playgroud)

cosine-similarity word2vec sentence-similarity

7
推荐指数
1
解决办法
3842
查看次数

当 Word2Vec 使用点积相似度训练时,为什么要在 Word2Vec 中使用余弦相似度

根据我在 stackoverflow 上找到的几篇文章(例如,为什么 word2Vec 使用余弦相似度?),通常的做法是在我们训练好 word2vec(CBOW 或 Skip-gram)模型后计算两个词向量之间的余弦相似度。然而,这对我来说似乎有点奇怪,因为该模型实际上是用点积作为相似性分数进行训练的。一个证据是我们训练后得到的词向量的范数实际上是有意义的。那么为什么人们在计算两个词之间的相似度时仍然使用余弦相似度而不是点积呢?

nlp dot-product cosine-similarity word2vec word-embedding

7
推荐指数
1
解决办法
1442
查看次数

0 和 1 之间的余弦相似度

我对计算向量之间的相似度很感兴趣,但是这种相似度必须是 0 到 1 之间的数字。关于 tf-idf 和余弦相似度有很多问题,都表明该值介于 0 和 1 之间。来自维基百科

在信息检索的情况下,两个文档的余弦相似度将在 0 到 1 的范围内,因为术语频率(使用 tf-idf 权重)不能为负。两个词频向量之间的夹角不能大于 90°。

特殊之处在于我希望计算来自两个不同 word2vec 模型的两个向量之间的相似性。但是,这些模型已经对齐,因此它们实际上应该在相同的向量空间中表示它们的单词。我可以像这样计算单词 inmodel_a和单词 in之间的相似度model_b

import gensim as gs
from sklearn.metrics.pairwise import cosine_similarity

model_a = gs.models.KeyedVectors.load_word2vec_format(model_a_path, binary=False)
model_b = gs.models.KeyedVectors.load_word2vec_format(model_b_path, binary=False)

vector_a = model_a[word_a].reshape(1, -1)
vector_b = model_b[word_b].reshape(1, -1)

sim = cosine_similarity(vector_a, vector_b).item(0)
Run Code Online (Sandbox Code Playgroud)

但是sim是 [-1,1] 范围内的相似性度量。是否有科学合理的方法将其映射到 [0,1] 范围?直觉上我会认为像

norm_sim = (sim + 1) / 2
Run Code Online (Sandbox Code Playgroud)

没关系,但我不确定这对于余弦相似度的实际含义是否是好的做法。如果没有,是否建议使用其他相似性指标?

我试图让值介于 0 和 1 之间的原因是因为数据将传输给一位同事,该同事将使用它作为她的机器学习系统的特征,该系统期望所有值都在 0 和 1 …

python similarity cosine-similarity gensim scikit-learn

7
推荐指数
1
解决办法
7946
查看次数