Применение весов к кадру данных Pandas для определения повторяющихся терминов - PullRequest
0 голосов
/ 04 июня 2019

У меня есть очень большой Pandas Dataframe со списком терминов, найденных в большой библиотеке текста. Столбцы представляют собой термин и количество раз, которое этот термин появляется в тексте:

Term                  Hits

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

Моя цель - провести анализ N-граммов в этом файле, чтобы определить n-граммы с наибольшей активностью. Но я хочу, чтобы это было отсортировано по СКОЛЬКО активности в тексте тела появился n-грамм. например Меня больше интересуют n-граммы, которые обычно появляются в терминах в диапазоне 20000+ хитов, чем те, которые чаще всего появляются в терминах, имеющих только несколько хитов.

Имея это в виду, я думаю, что здесь необходимо провести некоторую форму взвешенного анализа. Есть ли какая-то форма их функциональности в Pandas или Sklearn, которая поможет мне в этом?

У меня есть базовый пример CountVectorizer, который я использовал для анализа n-грамм до сих пор, но в этом случае он может не применяться.

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')

EDIT:

Я полагаю, что другой способ думать об этом состоит в том, что столбец Hits по сути является столбцом весов сам по себе. Таким образом, я ищу способ добавления количества раз, когда термин появляется к частоте, которую n-грамм, содержащийся в этом термине, будет появляться в моем документе.

1 Ответ

1 голос
/ 04 июня 2019

Я написал эти функции ранее для генерации 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)]

Таким образом, для вашего случая вы можете передать столбец (df['keyword']) в функцию ngram_freq и добавить параметр min_count в качестве 20000, и ngram может быть любым, что вы предпочитаете.

...