2017-01-04 3 views
2

を持つ2つのドキュメントが共有するトークンのパーセントを見つけ、それはようなものになるだろう:スペイシーが速くなるので、イムは、スペイシーでそれをやろうとしますが、トークンオブジェクトはいないようだNLTKのためスペイシー

def symm_similarity(textA,textB): 
    textA = set(word_tokenize(textA)) 
    textB = set(word_tokenize(textB))  
    intersection = len(textA.intersection(textB)) 
    difference = len(textA.symmetric_difference(textB)) 
    return intersection/float(intersection+difference) 

このための迅速なソリューションを提供します。何か案は?

ありがとうございます。

答えて

1

あなたの関数は、トークンではなく、共有されている単語タイプの割合を取得します。あなたは自分のカウントに敏感でなく、言葉のセットを取っている。あなたがトークンのカウントをしたい場合は、私は次のように(あなたがインストールされたデータを持っている場合、それは、デフォルトでされる)ので、限り、あなたは語彙ファイルがロードされてきたように、非常に高速であることを期待

from spacy.attrs import ORTH 

def symm_similarity_types(nlp, textA,textB): 
    docA = nlp.make_doc(textA) 
    docB = nlp.make_doc(textB) 
    countsA = Counter(docA.count_by(ORTH)) 
    countsB = Counter(docB.count_by(ORTH) 
    diff = sum(abs(val) for val in (countsA - countsB).values()) 
    return diff/(len(docA) + len(docB)) 

上記のコードとまったく同じものを計算したい場合は、spaCyに相当するコードを以下に示します。 Docオブジェクトを使用すると、オブジェクトTokenを反復処理できます。次に、文字列の整数IDであるtoken.orth属性に基づいてカウントします。あなたが整数の集合ではなく、文字列で作業しているので、

def symm_similarity_types(nlp, textA,textB): 
    docA = set(w.orth for w in nlp(textA) 
    docB = set(w.orth for w in nlp(textB) 
    intersection = len(textA.intersection(textB)) 
    difference = len(textA.symmetric_difference(textB)) 
    return intersection/float(intersection+difference) 

これは、もう少し効率的なNLTKのバージョンよりも次のようになります。私は、整数での作業は、文字列のセットよりも少し速くなります期待しています。

本当に効率を心配しているのであれば、Pythonが何をしているのかを推測するのではなく、ちょうどCythonで作業する方が便利なことがよくあります。ここでは基本的なループです:

# cython: infer_types=True 
for token in doc.c[:doc.length] 
    orth = token.lex.orth 

doc.cあなたは連続したメモリを反復処理し、単一のポインタを参照解除しているので、感謝の三段論法

+0

token.lexconst LexemeC*である)、TokenC*です!あなたは正しいです、私は言葉をしていたが、私のアプリケーションの言葉やトークンは正常に動作します。これは間違いなく私自身以外の多くの人にも役立ちます。あなたの助けに感謝! –