有几个在stackoverflow和网上的问题描述如何计算两个字符串的余弦相似度,甚至是在两个带有TFIDF权重的字符串之间。但像scikit的linear_kernel
这样的函数的输出让我有些困惑。
考虑以下代码:
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
a = ['hello world', 'my name is', 'what is your name?']
b = ['my name is', 'hello world', 'my name is what?']
df = pd.DataFrame(data={'a':a, 'b':b})
df['ab'] = df.apply(lambda x : x['a'] + ' ' + x['b'], axis=1)
print(df.head())
a b ab
0 hello world my name is hello world my name is
1 my name is hello world my name is hello world
2 what is your name? my name is what? what is your name? my name is what?
问题:
我想要一列,该列是 a
中的字符串和 b
中的字符串之间的余弦相似度。
我的尝试:
我在 ab
上训练了一个 TFIDF 分类器,以包含所有单词:
clf = TfidfVectorizer(ngram_range=(1, 1), stop_words='english')
clf.fit(df['ab'])
然后我得到了a
和b
列的稀疏TFIDF矩阵:
tfidf_a = clf.transform(df['a'])
tfidf_b = clf.transform(df['b'])
现在,如果我使用scikit的linear_kernel
,这也是其他人推荐的方法,我会得到一个(nfeatures,nfeatures)的Gram矩阵,正如他们文档中提到的那样。
from sklearn.metrics.pairwise import linear_kernel
linear_kernel(tfidf_a,tfidf_b)
array([[ 0., 1., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])
我需要的是一个简单的向量,其中第一个元素是a
的第一行与b
的第一行之间的余弦相似度,第二个元素是cos_sim(a[1],b[1]),以此类推。
使用Python3和scikit-learn 0.17。