为了提高性能,您应该使用向量化代码来替换列表推导式。这可以通过Numpy的
pdist
和
squareform
轻松实现,如下面的代码片段所示:
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
from scipy.spatial.distance import pdist, squareform
titles = [
'A New Hope',
'The Empire Strikes Back',
'Return of the Jedi',
'The Phantom Menace',
'Attack of the Clones',
'Revenge of the Sith',
'The Force Awakens',
'A Star Wars Story',
'The Last Jedi',
]
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(titles)
cs_title = squareform(pdist(X.toarray(), 'cosine'))
演示:
In [87]: X
Out[87]:
<9x21 sparse matrix of type '<type 'numpy.int64'>'
with 30 stored elements in Compressed Sparse Row format>
In [88]: X.toarray()
Out[88]:
array([[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0],
[0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]], dtype=int64)
In [89]: vectorizer.get_feature_names()
Out[89]:
[u'attack',
u'awakens',
u'back',
u'clones',
u'empire',
u'force',
u'hope',
u'jedi',
u'last',
u'menace',
u'new',
u'of',
u'phantom',
u'return',
u'revenge',
u'sith',
u'star',
u'story',
u'strikes',
u'the',
u'wars']
In [90]: np.set_printoptions(precision=2)
In [91]: print(cs_title)
[[ 0. 1. 1. 1. 1. 1. 1. 1. 1. ]
[ 1. 0. 0.75 0.71 0.75 0.75 0.71 1. 0.71]
[ 1. 0.75 0. 0.71 0.5 0.5 0.71 1. 0.42]
[ 1. 0.71 0.71 0. 0.71 0.71 0.67 1. 0.67]
[ 1. 0.75 0.5 0.71 0. 0.5 0.71 1. 0.71]
[ 1. 0.75 0.5 0.71 0.5 0. 0.71 1. 0.71]
[ 1. 0.71 0.71 0.67 0.71 0.71 0. 1. 0.67]
[ 1. 1. 1. 1. 1. 1. 1. 0. 1. ]
[ 1. 0.71 0.42 0.67 0.71 0.71 0.67 1. 0. ]]
请注意,
X.toarray().shape
的结果为
(9L, 21L)
,因为在上面的示例中有9个标题和21个不同的单词,而
cs_title
是一个
9乘9的数组。
cs_pt = [cosine_similarity(a, b) for a in pre_pt for b in pre_pt]
,会生成一个向量。但是对于每个余弦相似度集合,你不想要一个矩阵吗? - Bill Bell