Извлечение ключевых фраз из текста на основе топи c с Python - PullRequest
2 голосов
/ 02 мая 2020

У меня большой набор данных с 3 столбцами, столбцами являются текст, фраза и топи c. Я хочу найти способ извлечения ключевых фраз (столбец фраз) на основе топи c. Ключевая фраза может быть частью текстового значения или всего текстового значения.

import pandas as pd


text = ["great game with a lot of amazing goals from both teams",
        "goalkeepers from both teams made misteke",
        "he won all four grand slam championchips",
        "the best player from three-point line",
        "Novak Djokovic is the best player of all time",
        "amazing slam dunks from the best players",
        "he deserved yellow-card for this foul",
        "free throw points"]

phrase = ["goals", "goalkeepers", "grand slam championchips", "three-point line", "Novak Djokovic", "slam dunks", "yellow-card", "free throw points"]

topic = ["football", "football", "tennis", "basketball", "tennis", "basketball", "football", "basketball"]

df = pd.DataFrame({"text":text,
                   "phrase":phrase,
                   "topic":topic})

print(df.text)
print(df.phrase)

У меня большие проблемы с поиском пути, чтобы сделать что-то подобное, потому что у меня более 50000 строк в моем набор данных и около 48000 уникальных значений фраз и 3 разных темы.

Я думаю, что создание набора данных по всем темам, касающимся футбола, баскетбола и тенниса, на самом деле не лучшее решение. Так что я думал о создании некоторой модели ML для этого, но опять же это означает, что у меня будет 2 функции (текст и топи c) и один результат (фраза), но у меня будет более 48000 различных классов в мой результат, и это не очень хороший подход.

Я думал об использовании текстового столбца как функции и применении модели классификации, чтобы найти настроение. После этого я могу использовать прогнозируемые настроения для извлечения ключевых функций, но я не знаю, как их извлечь.

Еще одна проблема заключается в том, что я получаю точность только 66%, когда пытаюсь классифицировать чувства, используя CountVectorizer или TfidfTransformer со случайным лесом, деревом решений или любым другим алгоритмом классификации, а также 66% Точность, если я использую TextBlob для анализа настроений.

Любая помощь?

Ответы [ 3 ]

2 голосов
/ 09 мая 2020

Похоже, что хорошим подходом здесь было бы использование модели скрытого распределения Дирихле , которая является примером того, что известно как topi c модели .


A LDA - это модель без присмотра, которая находит похожие группы среди набора наблюдений, которые затем можно использовать для назначения topi c каждому из них. Здесь я расскажу go, что может быть подходом для решения этой проблемы путем обучения модели с использованием предложений в столбце text. Хотя в случае, если phrases достаточно репрезентативны и содержат необходимую информацию для сбора моделями, они также могут быть хорошим (возможно, лучшим) кандидатом для обучения модели, хотя об этом вы лучше судите сами.

Перед тем, как приступить к обучению модели, вам необходимо применить некоторые этапы предварительной обработки, в том числе токенизацию предложений, удаление стоп-слов, лемматизацию и основание. Для этого вы можете использовать nltk:

from nltk.stem import WordNetLemmatizer
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
import lda
from sklearn.feature_extraction.text import CountVectorizer


ignore = set(stopwords.words('english'))
stemmer = WordNetLemmatizer()
text = []
for sentence in df.text:
    words = word_tokenize(sentence)
    stemmed = []
    for word in words:
        if word not in ignore:
            stemmed.append(stemmer.lemmatize(word))
    text.append(' '.join(stemmed))

Теперь у нас есть более подходящий корпус для обучения модели:

print(text)

['great game lot amazing goal team',
 'goalkeeper team made misteke',
 'four grand slam championchips',
 'best player three-point line',
 'Novak Djokovic best player time',
 'amazing slam dunk best player',
 'deserved yellow-card foul',
 'free throw point']

Затем мы можем преобразовать текст в матрицу подсчета токенов. через CountVectorizer, то есть входное значение, которое будет ожидать LDA:

vec = CountVectorizer(analyzer='word', ngram_range=(1,1))
X = vec.fit_transform(text)

Обратите внимание, что вы можете использовать параметр ngram для расширения диапазона n-граммы, который вы хотите рассмотреть, чтобы обучить модель. Например, установив ngram_range=(1,2), вы получите элементы, содержащие все отдельные слова, а также 2-grams в каждом предложении, вот пример, который обучил CountVectorizer с ngram_range=(1,2):

vec.get_feature_names()
['amazing',
 'amazing goal',
 'amazing slam',
 'best',
 'best player',
 ....

Преимущество использования n-grams состоит в том, что вы также можете найти Key-Phrases, кроме простых слов.

Затем мы можем обучить LDA с любым количеством тем, которые вы хотите, в этом случае я ' Я просто выберу темы 3 (обратите внимание, что это не имеет никакого отношения к столбцу topics), который вы можете считать Key-Phrases - или words в данном случае - который вы упомянули. Здесь я буду использовать lda, хотя есть несколько вариантов, таких как gensim . Каждому топи c будет соответствовать набор слов из словаря, с которым он был обучен, причем каждое слово имеет оценку , измеряющую релевантность слова в топи c.

model = lda.LDA(n_topics=3, random_state=1)
model.fit(X)

Через topic_word_ теперь мы можем получить эти баллы , связанные с каждым топи c. Мы можем использовать argsort для сортировки вектора оценок и использовать его для индексации вектора имен объектов, который мы можем получить с помощью vec.get_feature_names:

topic_word = model.topic_word_

vocab = vec.get_feature_names()
n_top_words = 3

for i, topic_dist in enumerate(topic_word):
    topic_words = np.array(vocab)[np.argsort(topic_dist)][:-(n_top_words+1):-1]
    print('Topic {}: {}'.format(i, ' '.join(topic_words)))

Topic 0: best player point
Topic 1: amazing team slam
Topic 2: yellow novak card

Печатные результаты в этом случае он действительно много значит, так как модель была обучена с использованием образца из вопроса, однако вы должны увидеть более ясные и содержательные темы , тренируясь со всем своим корпусом.

Также обратите внимание, что для этого примера я использую весь словарный запас для обучения модели. Однако, похоже, что в вашем случае более разумным было бы разделить текстовый столбец на группы в соответствии с различными topics, которые у вас уже есть, и обучить отдельную модель для каждой группы . Но, надеюсь, это даст вам хорошее представление о том, как действовать.

0 голосов
/ 09 мая 2020

Я думаю, что то, что вы ищете, называется "Topi c моделирование" в НЛП. Вы должны попробовать использовать LDA для моделирования topi c. Это один из самых простых способов применения. также, как упоминал @Mike, у преобразования слова в вектор есть много подходов. Сначала вы должны попробовать простые подходы, такие как счетчик векторов, а затем постепенно перейти к чему-то вроде word-2-vect или glove.

Я прилагаю некоторые ссылки для применения LDA к корпусу. 1. https://towardsdatascience.com/nlp-extracting-the-main-topics-from-your-dataset-using-lda-in-minutes-21486f5aa925 2. https://www.machinelearningplus.com/nlp/topic-modeling-visualization-how-to-present-results-lda-models/

0 голосов
/ 09 мая 2020

Похоже, вы хотите сгруппировать короткие фрагменты текста по topi c. Вам придется так или иначе маркировать данные. Существует множество кодировок, которые вы можете рассмотреть:

Мешок слов, который классифицируется путем подсчета частоты каждого слова в вашем словаре.

TF-IDF: делает то, что описано выше, но делает слова, появляющиеся в большем количестве записей, менее важными

n_grams / bigrams / trigrams, которые по существу используют метод мешка слов, но также поддерживают некоторый контекст вокруг каждого слова , Таким образом, вы будете иметь кодировки для каждого слова, но у вас также будут токены для "great_game", "game_with" и "great_game_with" et c.

Orthogonal Sparse Bigrams (OSB) s Также создайте функции, которые разделяйте слова, например, «great__with»

Любой из этих вариантов может быть идеальным для вашего набора данных (последние два, вероятно, являются вашей лучшей ставкой). Если ни один из этих вариантов не работает, есть несколько вариантов, которые вы можете попробовать:


Сначала вы можете использовать вложения слов. Это векторные представления каждого слова, которые в отличие от однократного кодирования по сути содержат значение слова. Вы можете суммировать слова в предложении вместе, чтобы получить новый вектор, содержащий общее представление о том, о чем идет речь, и который затем может быть декодирован.

Вы также можете использовать вложения слов вместе с двунаправленным LSTM. Это наиболее ресурсоемкий вариант, но если другие варианты не работают, это может быть хорошим выбором. БиЛСТМ пытаются интерпретировать предложения, рассматривая контекст вокруг слов, чтобы понять, что слово может означать в этом контексте.

Надеюсь, это поможет

...