首页 > 解决方案 > 如果在矩阵上运行 SVD,如何使用该 SVD 的结果转换新行?

问题描述

我正在使用 Scipy 运行奇异值分解,以计算数据集中各行之间的余弦相似度。现在,当我得到一个我想比较的新行时,我正在重新初始化 SVD,并添加了新行。有没有办法使用我从初始 SVD 获得的结果(U、S、VT)来转换新行,而不必每次都重新运行它?

# calculating similarity for already existing first row
import scipy
from scipy.sparse.linalg import svds
from sklearn.metrics.pairwise import cosine_similarity
u, s, v = svds(csr_mat.astype('float'))
similarities = cosine_similarity([u[0]], u)

# when I encounter a new row I want to calculate similarities for, I append it to the original matrix and recalculate SVD
csr_matrix = scipy.sparse.vstack((csr_mat, new_row_to_compare))
u, s, v = svds(csr_mat.astype('float'))
similarities = cosine_similarity([u[-1]], u)

是否有某种类型的线性代数运算可以使用 u、s 和 v 将其转换new_row_to_compare为与 u 中其他行相同的格式?

标签: pythonscipylinear-algebracosine-similaritysvd

解决方案


您希望您的查询与 csr_matrix 位于同一“空间”中。

  1. 制作一个与您的“s”矩阵具有相同等级的零向量(使用高度 b/c“s”是一个正方形)。这在下面被称为query_vector

  2. 对于空的每一行query_vector添加更改01有“匹配”的地方...例如,如果您csr_matrix在句子中表示单词的行,那么您query_vector1在出现单词的任何地方出现也表示在csr_matrix

                       sentence1 sentence2 sentence3 query
                 cat       0        0          1       0
                 dog       1        1          0       1
                 mouse     0        1          0       0
                 gopher    0        0          1       0
                 squirrel  0        0          0       0
    
  3. 现在您可以找到查询与其他列(在此示例中为句子)之间的余弦距离。

抱歉,我在 Python 中没有一个工作示例,但是有一个关于如何在 Python 中使用 gensim 包执行此操作的很棒的教程,这里:https ://radimrehurek.com/gensim/auto_examples/core/run_similarity_queries.html# sphx-glr-auto-examples-core-run-similarity-queries-py

即使您不使用 gensim 包,我建议您查看他们的文档,它也很出色,我认为会非常清楚地回答您的问题。

这是我在 R 中如何做到这一点。

  # Query Matrix: count the number of times that
  # the word appears - put the counts in the tdm$dimnames$Terms
  # vector.

  query_vector <- rep(0, length(tdm$dimnames$Terms))

  for(i in 1:length(query_split)){
    query_vector[which(tdm$dimnames$Terms == query_split[i])] <- 1
  }

  query_matrix <- as.matrix(query_vector)
  
  # Calculate the cosine similarity between the query and each document.
  full_lsa <- cbind(t(lsa), query_lsa)
  query_scores <- cosine(full_lsa)

推荐阅读