我有一个形状为(6, 25931)
的术语文档矩阵(X)。前5个文档是我的源文档,最后一个文档是我的目标文档。该列表示词汇集中不同单词的计数。我想获得最后一个文档与其他每个文档的余弦相似度。
但是由于SVD产生的大小为(min(6, 25931),)
的S,如果我使用S来减少X,我将得到6 * 6的矩阵。但是在这种情况下,由于将大小为(25931,)
的向量减小为(6,)
,因此我会丢失太多信息。
并且通常,文档的数量总是少于词汇单词的数量。在这种情况下,使用SVD减少维数将始终生成大小为(no documents,)
的向量。
根据我已阅读的所有内容,当在术语文档矩阵中像这样使用SVD时,它称为LSA。
(6,)
的情况下,还有其他方法可以降低维数并获得更密集的矢量吗?P.S .:我还尝试使用fit_transform
中的sklearn.decomposition.TruncatedSVD
,它期望矢量的格式为(n_samples, n_components)
,这就是为什么我的学期文件矩阵的形状是(6, 25931)
而不是(25931, 6)
的原因。我一直得到一个(6, 6)
矩阵,这最初使我困惑。但是现在,在我记得SVD背后的数学原理之后,这才有意义。
如果练习的目的是找到余弦相似度,则以下方法可以提供帮助。作者仅试图解决该目标,而不对发问者提到的潜在语义分析的定义或奇异值分解的定义发表评论。
让我们首先调用所有必需的库。如果机器中不存在它们,请安装它们。
from sklearn.metrics.pairwise import cosine_similarity
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
让我们为此练习生成一些样本数据。
df = {'sentence': ['one two three','two three four','four five','six seven eight nine ten']}
df = pd.DataFrame(df, columns = ['sentence'])
第一步是获取所有可能功能的详尽列表。因此,将所有内容放在一个位置。
all_content = [' '.join(df['sentence'])]
让我们构建一个矢量化器并立即安装它。请注意,作者没有解释vectorizer中的参数,因为重点是解决问题。
vectorizer = TfidfVectorizer(encoding = 'latin-1',norm = 'l2', min_df = 0.03, ngram_range = (1,2), max_features = 5000)
vectorizer.fit(all_content)
我们可以检查词汇表是否有意义。如果需要,可以在上面的[[vectorizer中添加停用词,并对其进行抑制,以查看它们是否确实受到抑制。
print(vectorizer.vocabulary_)
让我们对句子进行矢量化处理,以部署余弦相似度。
s1Tokens = vectorizer.transform(df.iloc[1,]) s2Tokens = vectorizer.transform(df.iloc[2,])
最后,相似度的余弦可以如下计算。
cosine_similarity(s1Tokens , s2Tokens)