SpaCy вопросы о списках списков в Python 2.7 - PullRequest
0 голосов
/ 14 октября 2018

Я думаю, что часть моей проблемы связана с spaCy, а часть связана с непониманием самого элегантного способа работы внутри самого Python.

Я загружаю текстовый файл в Python, разбивая его напредложения, а затем разбить его на слова с помощью nltk:

sent_text = nltk.sent_tokenize(text)
tokenized_text = [nltk.word_tokenize(x) for x in sent_text]

Это дает мне список списков, где каждый список в основном списке является предложением токенизированных слов.Пока все хорошо.

Затем я запускаю его через SpaCy:

text = nlp(unicode(tokenized_text))

Все еще список списков, тоже самое, но в нем есть вся информация о SpaCy.

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

sent11 = []
  for token in sent1:
    if (token.pos_ == 'NOUN' or token.pos_ == 'VERB' or token.pos_ =='ADJ') and (token.dep_ != 'aux') and (token.dep_ != 'conj'):
      sent11.append(token)

Это прекрасно работает для одного предложения, но я не хочу делать это для каждогопредложение в тексте длиной в книгу.

Затем, когда у меня появятся эти новые списки (или любой другой лучший способ сделать это), содержащий только те фрагменты, которые я хочу, я хочу использовать функцию "сходства"SpaCy, чтобы определить, какое предложение семантически ближе всего к некоторому другому, гораздо более короткому тексту, с которым я сделал то же самое для всего, кроме существительных, прилагательных, глаголов и т. Д.

У меня это работает при сравнении одногоодно предложение другому с помощью:

sent1.similarity(sent2)

Итак, я думаю, мои вопросы

1) Как лучше всего превратить список списков в список списков, которые содержат толькокуски, которые я хочу?

и

2) Как мне циклически проходить через этот новый список списков, сравнивать каждый из них с отдельным предложением и возвращать предложение, которое наиболее семантически похоже (using векторы, с которыми поставляется SpaCy)?

1 Ответ

0 голосов
/ 14 октября 2018

Вы задаете здесь кучу вопросов, поэтому я попытаюсь их разбить.

  1. Практически дублирует объем текста книги, добавляя каждое слово в список.плохо?
  2. Как можно эффективно удалять или удалять элементы списка?
  3. Как можно сравнить предложение с каждым предложением в книге, где каждое предложение является списком, а книга - спискомпредложений.

Ответы:

  1. Обычно да, но в современной системе это не имеет большого значения.Книги - это текст, который, вероятно, представляет собой символы UTF-8, если он английский, в противном случае это может быть Unicode.Символ UTF-8 - это байт, и даже длинная книга, такая как Война и мир , выходит за 3,3 Мб.Если вы используете Chrome, Firefox или IE для просмотра этой страницы, у вашего компьютера более чем достаточно памяти, чтобы поместить несколько копий в оперативную память.

  2. В Python вы не можете по-настоящему.

Вы можете выполнить удаление, используя:

l = [1,2,3,4]
del l[-2]
print(l)
[1,2,4]

, но в фоновом режиме питон копирует каждый элемент этого списка по одному.Не рекомендуется для больших списков.Вместо этого, используя dequeue , который реализует себя как список с двойными связями, имеет немного дополнительных издержек, но позволяет эффективно удалять элементы в середине.

Если проблема с памятью, то вытакже можно использовать генераторы везде, где это возможно.Например, вы могли бы изменить:

tokenized_text = [nltk.word_tokenize(x) for x in sent_text]

, который создает список, содержащий токены всей книги, с

tokenized_text = (nltk.word_tokenize(x) for x in sent_text)

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

Я не знаком с SpaCy, и хотя вопрос подходит к SO, вы вряд ли получите здесь хорошие ответы о конкретных библиотеках.

Судя по всему, вы можете просто сделать что-то вроде:

best_match = None
best_similarity_value = 0
for token in parsed_tokenized_text:
    similarity = token.similarity(sent2)
    if similarity > best_similarity_value:
        best_similarity_value = similarity
        best_match = token

И если вы хотите проверить несколько предложений (непоследовательных), то вы можете поставить внешнийцикл, который проходит через те:

for sent2 in other_token_list:
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...