首页 > 解决方案 > 将权重应用于 Pandas 数据框以识别重复项

问题描述

我有一个非常大的 Pandas 数据框,其中包含在大型文本库中找到的术语列表。列是术语和该术语在文本中出现的次数:

Term                  Hits

volvo car handbrake   300
kelly blue book       20000
mcdonals health       1
dog show cambridge    50
..........

我的目标是对该文件进行 N-gram 分析,以识别活动量最大的 n-gram。但我希望它按文本正文中出现 n-gram 的活动量来排序。例如,我对通常出现在 20000+ Hits 范围内的 n-gram 比那些主要出现在只有几个 Hits 的术语更感兴趣。

考虑到这一点,我认为这里需要进行某种形式的加权分析。他们在 Pandas 或 Sklearn 中的某种形式的功能是否可以帮助我实现这一目标?

我有一个基本的 CountVectorizer 示例,到目前为止我已将其用于 n-gram 分析,但它可能不适用于这种情况。

df = pd.read_csv('terms.csv', names=['Keyword'])

word_vectorizer = CountVectorizer(ngram_range=(3, 3), analyzer='word', stop_words='english')
sparse_matrix = word_vectorizer.fit_transform(df['Keyword'])
frequencies = sum(sparse_matrix).data
output_df = pd.DataFrame(frequencies, index=word_vectorizer.get_feature_names(), columns=['frequency'])
output_df = output_df.sort_values('frequency', ascending=False)
output_df.to_csv('analysis_output.csv')

编辑:

我想另一种思考方式是 Hits 列本身本质上是一个权重列。因此,我正在寻找一种将术语出现的次数与包含在该术语中的 n-gram 出现在我的文档中的频率相加的方法。

标签: pythonpandasscikit-learnn-gramweighted-average

解决方案


我之前已经编写了这些函数来生成ngrams和查找频率:

import nltk

def generate_ngrams(text, n_gram=2):
    token = [token for token in text.strip().lower().split(" ")]
    ngrams = zip(*[token[i:] for i in range(n_gram)])
    return [" ".join(ngram) for ngram in ngrams]

def ngram_freq(column, topn = 50, min_count = None, n_gram = 2):
    ngrams = [ngram for text in column for ngram in generate_ngrams(text, n_gram)]
    if min_count is None:
        return sorted(nltk.FreqDist(ngrams).items(), key = lambda x: x[1], reverse = True)[:topn]
    else:
        return [(x,y) for x,y in  nltk.FreqDist(ngrams).items() if y>=min_count]
#         return sorted(nltk.FreqDist(ngrams).items(), key = lambda x: x[1], reverse = True)[:topn]

generate_ngrams('This is an Example')
> ['this is', 'is an', 'an example']

generate_ngrams('This is an Example', n_gram=3)
> ['this is an', 'is an example']

ngram_freq 将返回一个包含 ngram 及其频率的元组,具体取决于传递的参数:

text_list = ['I am StackOverflow', 'I am StackOverflow not really',
            'Example Statement for StackOverflow',
            'Statement for StackOverflow']

ngram_freq(text_list, min_count=2)

> [('i am', 2),
 ('am stackoverflow', 2),
 ('statement for', 2),
 ('for stackoverflow', 2)]

它还可以返回 top_n 计数:

ngram_freq(text_list, topn=2)
> [('i am', 2), ('am stackoverflow', 2)]

因此,对于您的情况,您可以将 column( df['keyword']) 传递给ngram_freq函数,并将min_count参数添加为 20000 并且ngram可以是您喜欢的任何值。


推荐阅读