[英]Jaccard Similarity for Texts in a pandas DataFrame
我想測量pandas DataFrame中文本之間的jaccard相似度。 更確切地說,我有一些實體組,並且在一段時間內每個實體都有一些文本。 我想分析每個實體的文本相似度(這里是Jaccard相似度)隨時間的變化。
一個簡單的例子來說明我的觀點:
import pandas as pd
entries = [
{'Entity_Id':'Firm1', 'date':'2001-02-05', 'text': 'This is a text'},
{'Entity_Id':'Firm1', 'date':'2001-03-07', 'text': 'This is a text'},
{'Entity_Id':'Firm1', 'date':'2003-01-04', 'text': 'No similarity'},
{'Entity_Id':'Firm1', 'date':'2007-10-12', 'text': 'Some similarity'},
{'Entity_Id':'Firm2', 'date':'2001-10-10', 'text': 'Another firm'},
{'Entity_Id':'Firm2', 'date':'2005-12-03', 'text': 'Another year'},
{'Entity_Id':'Firm3', 'date':'2002-05-05', 'text': 'Something different'}
]
df = pd.DataFrame(entries)
Entity_Id日期文本
Firm1 2001-02-05 'This is a text'
Firm1 2001-03-07 'This is a text'
Firm1 2003-01-04 'No similarity'
Firm1 2007-10-12 'Some similarity'
Firm2 2001-10-10 'Another firm'
Firm2 2005-12-03 'Another year'
Firm3 2002-05-05 'Something different'
我想要的輸出將是這樣的:
Entity_Id日期文本Jaccard
Firm1 2001-02-05 'This is a text' NaN
Firm1 2001-03-07 'This is a text' 1
Firm1 2003-01-04 'No similarity' 0
Firm1 2007-10-12 'Some similarity' 0.33
Firm2 2001-10-10 'Another firm' NaN
Firm2 2005-12-03 'Another year' 0.33
Firm3 2002-05-05 'Something different' NaN
也就是說,我喜歡比較一組公司中的所有文本元素,而不管文本之間的時間間隔。 我想將它與以前的文本進行比較。 因此,每個公司的第一個條目總是空的,因為沒有可比較的文本。
我的方法是按實體標識符將文本移動一個時間間隔(下一個可用日期)。 然后識別每個實體的第一份報告並標記該報告。 (我在text_shifted中輸入NaNs的原始文本,稍后將其刪除 - >需要對整列進行標記化)
df = df.sort_values(['Entity_Id', 'date'], ascending=True)
df['text_shifted'] = df.groupby(['Entity_Id'])['text'].shift(1)
df['IsNaN'] = df['text_shifted'].isnull().astype(int)
df['text_shifted'] = df['text_shifted'].fillna(df['text'])
在下面我使用jaccard相似性如下:
def jaccard_similarity(query, document):
intersection = set(query).intersection(set(document))
union = set(query).union(set(document))
return len(intersection)/len(union)
但是我必須首先對輸入進行標記。 但如果我做的事情如下:
import nltk
df['text_tokens'] = df.text.apply(nltk.word_tokenize)
df['shift_tokens'] = df.text_shifted.apply(nltk.word_tokenize)
在非簡化的文本示例中需要多年來標記文本,其中每個文本大約有5000個單詞,並且我有大約10萬個文本。
有什么方法可以加快這個過程嗎? 我可以避免標記化還是更好地使用sklearn來計算相似度?
加速該過程的一種方法可以是使用Pandas on Ray進行並行處理。
您可以嘗試使用jaccard_distance的 NLTK實現jaccard相似性。 我找不到處理時間的任何顯着改進(用於計算相似度),可能在更大的數據集上更好地工作。
嘗試將NLTK實現與您的自定義jaccard相似度函數進行比較(平均長度為4個字/令牌的200個文本樣本)
NTLK jaccard_distance:
CPU times: user 3.3 s, sys: 30.3 ms, total: 3.34 s
Wall time: 3.38 s
自定義jaccard相似性實現:
CPU times: user 3.67 s, sys: 19.2 ms, total: 3.69 s
Wall time: 3.71 s
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.