2017-03-23 18 views
1

私はPandasデータフレームの2つの列間のtf-idfベクトル余弦類似度を計算しようとしています。一方の列には検索クエリが含まれ、もう一方の列には製品タイトルが含まれます。コサイン類似度値は、検索エンジン/ランキング機械学習アルゴリズムの「特徴」であることが意図されている。Python:Pandasの2つの列間のtf-idf余弦類似度を計算するときのMemoryError

私はiPythonノートブックでこれをやっていて、残念なことにMemoryErrorsを実行していて、数時間の掘り下げがなぜ起こったのか分かりません。

マイセットアップ:

  • レノボE560ノートPC
  • コアi7-6500U 2.50 GHz帯の新鮮な更新とアナコンダ3.5カーネルを使用して
  • 16ギガバイトのRAM
  • のWindows 10
  • @すべてのライブラリ

私は自分のコードや目標を小さなおもちゃでテストしましたデータセットthusly同様のstackoverflowの質問ごとに:私はデータフレーム(df_all_export)に同じ方法を適用しようとすると、しかし

    a     b tfidf_cosine_similarity 
0   hello world  my name is     0.000000 
1   my name is  hello world     0.000000 
2 what is your name? my name is what?     0.725628 
3  max cosine sim max cosine sim     1.000000 

:これは、次の(!良い)出力を与える

import pandas as pd 
from sklearn.feature_extraction.text import TfidfVectorizer 
from scipy import spatial 

clf = TfidfVectorizer() 

a = ['hello world', 'my name is', 'what is your name?', 'max cosine sim'] 
b = ['my name is', 'hello world', 'my name is what?', 'max cosine sim'] 

df = pd.DataFrame(data={'a':a, 'b':b}) 

clf.fit(df['a'] + " " + df['b']) 

tfidf_a = clf.transform(df['a']).todense() 
tfidf_b = clf.transform(df['b']).todense() 

row_similarities = [1 - spatial.distance.cosine(tfidf_a[x],tfidf_b[x]) for x in range(len(tfidf_a)) ] 

df['tfidf_cosine_similarity'] = row_similarities 

print(df) 

寸法186154×5(のような場所5列のクエリ(SEARCH_TERM)の2及び文書(PRODUCT_TITLE):

clf.fit(df_all_export['search_term'] + " " + df_all_export['product_title']) 

tfidf_a = clf.transform(df_all_export['search_term']).todense() 
tfidf_b = clf.transform(df_all_export['product_title']).todense() 

row_similarities = [1 - spatial.distance.cosine(tfidf_a[x],tfidf_b[x]) for x in range(len(tfidf_a)) ] 
df_all_export['tfidf_cosine_similarity'] = row_similarities 

df_all_export.head() 

私が手...(ここでは全体の誤差を与えていますが、アイデアを得るていません):絶対にこの1に失ったが、私は解決策は非常にシンプルかつエレガントになる恐れ:)

MemoryError        Traceback (most recent call last) 
<ipython-input-27-8308fcfa8f9f> in <module>() 
    12 clf.fit(df_all_export['search_term'] + " " + df_all_export['product_title']) 
    13 
---> 14 tfidf_a = clf.transform(df_all_export['search_term']).todense() 
    15 tfidf_b = clf.transform(df_all_export['product_title']).todense() 
    16 

は、事前にありがとうございます!あなたはまだsklearn.metrics.pairwise方法を使用して、散在マトリクス/配列を扱うことができます

+0

エラーが発生した場所からわかるように、常に完全なスタックトレースを投稿してください。 –

答えて

2

# I've executed your example up to (including): 
# ... 
clf.fit(df['a'] + " " + df['b']) 

A = clf.transform(df['a']) 

B = clf.transform(df['b']) 

from sklearn.metrics.pairwise import * 

paired_cosine_distancesはあなたの文字列(2列に「行単位」の値を比較)されているどのくらいか、どのように異なるかを示します

0 - 完全一致

In [136]: paired_cosine_distances(A, B) 
Out[136]: array([ 1.  , 1.  , 0.27437247, 0.  ]) 

cosine_similarityはの最初の文字列を比較することを意味します列列内のすべての文字列はb行1)です。第二カラムb内のすべての文字列(行2)を用いたカラムaの文字列のように...

In [137]: cosine_similarity(A, B) 
Out[137]: 
array([[ 0.  , 1.  , 0.  , 0.  ], 
     [ 1.  , 0.  , 0.74162106, 0.  ], 
     [ 0.43929881, 0.  , 0.72562753, 0.  ], 
     [ 0.  , 0.  , 0.  , 1.  ]]) 

In [141]: A 
Out[141]: 
<4x10 sparse matrix of type '<class 'numpy.float64'>' 
     with 12 stored elements in Compressed Sparse Row format> 

In [142]: B 
Out[142]: 
<4x10 sparse matrix of type '<class 'numpy.float64'>' 
     with 12 stored elements in Compressed Sparse Row format> 

注:すべての計算は、を使用してdonwていたが、マトリクスを散在 - 私たちはそれらを解凍しませんでした記憶!

+0

ありがとうございました!私はあなたのソリューションを実装し、それは魅力的です。私は解決策を待っていましたが、リストや他の方法で回避策を試みましたが、どこにもありませんでした。あなたの解決策は素早く実行されます:) – Bango

+0

@Bango、私が助けることができてうれしい:) – MaxU

0

上記のMaxUによって投稿された種類のヘルプとソリューションを使用して、ここで私が達成しようとしていたタスクを完了した完全なコードを提示します。 MemoryErrorに加えて、私はいくつかの "ハッキー"な回避策を試したときにコサイン類似度の計算に現れる奇妙な乱数を避けます。

サイズが186,134 x 5の大きなデータフレームdf_all_exportが既にフルコードで構成されているという意味で、以下のコードには部分的な抜粋があります。

これは、検索クエリと一致するドキュメントの間で、tf-idfベクトルを使用してコサイン類似度を計算しようとしている他の人に役立つことを望みます。このような共通の「問題」に対して、私はSKLearnとPandasで実装された明確なソリューションを見つけるのに苦労しました。

import pandas as pd 
from sklearn.feature_extraction.text import TfidfVectorizer 
from sklearn.metrics.pairwise import paired_cosine_distances as pcd 

clf = TfidfVectorizer() 

clf.fit(df_all_export['search_term'] + " " + df_all_export['product_title']) 

A = clf.transform(df_all_export['search_term']) 
B = clf.transform(df_all_export['product_title']) 

cosine = 1 - pcd(A, B) 

df_all_export['tfidf_cosine'] = cosine 
関連する問題