2017-01-06 3 views
0

私はスキーマ(app、text_id、title、text)を持つ4つのテーブルを持っています。今、すべての可能なテキストペア(タイトル&のテキストを連結)間のコサインの類似性を計算し、最終的にフィールド(app1、app2、text_id1、text1、text_id2、text2、cosine_similarity)を含むcsvファイルに保存したいとします。4つのmysqlテーブルから取り出されたすべての可能なテキストペアのコサイン類似度を計算する

可能な組み合わせがたくさんあるので、非常に効率的に動作するはずです。ここで最も一般的なアプローチは何ですか?私はどんな指針にも感謝します。

編集: 提供されたリファレンスが私の問題に触れるかもしれませんが、私はまだこれにアプローチする方法を見つけることはできません。誰かがこの作業を達成するための戦略についてもっと詳しく説明できますか?計算された余弦類似度の次に、対応するテキストペアも出力として必要です。

+0

[疎行列データ与えられたコサイン類似度を計算するためのPythonで最速の方法は何ですか?](http://stackoverflow.com/questions/17627219/whats-the-fastest-way-in-pythonの可能性のある重複計算上のコサイン類似性が与えられたスパースマット) –

答えて

4

以下は、ドキュメントセット間のペアワイズコサイン類似度を計算するための最小限の例です(データベースからタイトルとテキストを正常に取得したと仮定して)。

from sklearn.feature_extraction.text import TfidfVectorizer 
from sklearn.metrics.pairwise import cosine_similarity 

# Assume thats the data we have (4 short documents) 
data = [ 
    'I like beer and pizza', 
    'I love pizza and pasta', 
    'I prefer wine over beer', 
    'Thou shalt not pass' 
] 

# Vectorise the data 
vec = TfidfVectorizer() 
X = vec.fit_transform(data) # `X` will now be a TF-IDF representation of the data, the first row of `X` corresponds to the first sentence in `data` 

# Calculate the pairwise cosine similarities (depending on the amount of data that you are going to have this could take a while) 
S = cosine_similarity(X) 

''' 
S looks as follows: 
array([[ 1.  , 0.4078538 , 0.19297924, 0.  ], 
     [ 0.4078538 , 1.  , 0.  , 0.  ], 
     [ 0.19297924, 0.  , 1.  , 0.  ], 
     [ 0.  , 0.  , 0.  , 1.  ]]) 

The first row of `S` contains the cosine similarities to every other element in `X`. 
For example the cosine similarity of the first sentence to the third sentence is ~0.193. 
Obviously the similarity of every sentence/document to itself is 1 (hence the diagonal of the sim matrix will be all ones). 
Given that all indices are consistent it is straightforward to extract the corresponding sentences to the similarities. 
''' 
+0

これは素晴らしい、ありがとう。それに基づいて私は別の2つの質問を持っています: まず、配列を繰り返し、コサインが> 0.8であるかどうかを確認してから、何らかの形でドキュメントのペアを取得する必要があります(配列内の位置だけでなく、書類の名前)。あなたはどうしますか? 第二に、私は多くのデータを持っているため、計算コストが問題になります。それはとにかく対称であるので、行列の半分だけを計算することは可能ですか? –

+0

@EmanuelGeorgeあなたは 'np.where(S> = 0.8)'を実行するか、 'S [S <0.8] = 0'を実行して配列全体をしきい値処理することによって' S'からインデックスを得ることができます。 a sim = 0.8〜0である。「S」の1つのエントリは、ドキュメントの対(インデックス0/1)がドキュメント0とドキュメント1との間の類似性であることを表す)。 Sからドキュメント名のリストへのマッピングよりも、ドキュメント名のリストがある場合は簡単です。 'sklearn'は非常に効率的ですが、何も2回計算するとは思いません。 – tttthomasssss

関連する問題