Python(まだnoob!)で、tfidfスコアの内積順に並べられたドキュメントのインデックスとスコアを返す関数を作成しようとしています。手順は次のとおりです。
idx
と他のすべてのドキュメント間の内積のベクトルを計算します私が現在持っているコードは次のとおりです。
_import h5py
import numpy as np
def get_related(tfidf, idx) :
''' return the top documents '''
# calculate inner product
v = np.inner(tfidf, tfidf[idx].transpose())
# sort
vs = np.sort(v.toarray(), axis=0)[::-1]
scores = vs[1:,]
# sort indices
vi = np.argsort(v.toarray(), axis=0)[::-1]
idxs = vi[1:,]
return (scores, idxs)
_
ここで、tfidf
は_sparse matrix of type '<type 'numpy.float64'>'
_です。
ソートが2回実行され(sort()
then argsort()
)、結果を逆にする必要があるため、これは非効率的です。
toarray()
を使用してスパース行列を変換せずに実行できますか?toarray
をスキップする必要はないと思います。 v
配列の長さはn_docs
のみであり、実際の状況ではn_docs
×n_terms
tf-idf行列のサイズよりも小さくなります。また、2つのドキュメントで共有される用語は、ゼロ以外の類似性を与えるため、非常に密度が高くなります。スパース行列表現は、格納している行列がveryスパースである場合にのみ効果があります(Matlabで80%を超える数値を確認し、Scipyも同様であると想定していますが、正確なものはありません図)。
二重ソートを行うことでスキップできます
v = v.toarray()
vi = np.argsort(v, axis=0)[::-1]
vs = v[vi]
ところで、スパース行列でのnp.inner
の使用は、最新バージョンのNumPyでは機能しません。 2つのスパース行列の内積を取る安全な方法は次のとおりです。
v = (tfidf * tfidf[idx, :]).transpose()