Разделите предложение на слова и небелые символы для POS-тегов

Это был вопрос, который я получил во время собеседования с технической фирмой, и я думаю, что в конечном итоге это убило мои шансы.

Вам дано предложение и словарь, в котором слова являются ключами, а части речи — значениями.

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

Например, предположим, что нам даны следующие входные данные:

sentence='I am done; Look at that, cat!' 

dictionary = {'!': 'sentinel', ',': 'sentinel', 
            'I': 'pronoun', 'am': 'verb', 
            'Look': 'verb', 'that': 'pronoun', 
             'at': 'preposition', ';': 'preposition', 
             'done': 'verb', ',': 'sentinel', 
             'cat': 'noun', '!': 'sentinel'}

output='pronoun verb verb sentinel verb preposition pronoun sentinel noun sentinel'

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

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
0
463
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Пакет Python Регулярное выражение можно использовать для разделения предложения на токены.

import re
sentence='I am done; Look at that, cat!' 

dictionary = {'!': 'sentinel', ',': 'sentinel', 
            'I': 'pronoun', 'am': 'verb', 
            'Look': 'verb', 'that': 'pronoun', 
             'at': 'preposition', ';': 'preposition', 
             'done': 'verb', ',': 'sentinel', 
             'cat': 'noun', '!': 'sentinel'}

tags = list()
for word in re.findall(r"[A-Za-z]+|\S", sentence):
    tags.append(dictionary[word])

print (' '.join(tags))

Выход

pronoun verb verb preposition verb preposition pronoun sentinel noun sentinel

Регулярное выражение [A-Za-z]+|\S в основном выбирает все алфавиты (заглавные и строчные) с одним или несколькими их вхождениями с помощью [A-Za-z]+, а также (выполнено с помощью |, что означает изменение) все небелые пробелы с помощью \s.

"[A-Za-z]+|\S" <-- что он делает?

user98235 22.05.2019 06:21

@user98235 user98235 Объяснено в самом ответе.

Divyanshu Srivastava 22.05.2019 06:26

Это регулярное выражение. Регулярное выражение — это специальная текстовая строка для описания шаблона поиска. Вы можете думать о регулярных выражениях как о подстановочных знаках на стероидах.

MichaelD 22.05.2019 06:27

Вот менее впечатляющее, но более понятное решение:

Давайте начнем с определения примера словаря и предложения в вашем вопросе:

sentence = 'I am done; Look at that, cat!' 

dictionary = {
    '!':    'sentinel', 
    ',':    'sentinel', 
    ',':    'sentinel', 
    'I':    'pronoun', 
    'that': 'pronoun', 
    'cat':  'noun', 
    'am':   'verb', 
    'Look': 'verb', 
    'done': 'verb', 
    'at':   'preposition', 
    ';':    'preposition', 
}

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

def parse(sentence, dictionary):
  # split the words apart by whitespace
  # some tokens may still be stuck together. (i.e. "that,")
  words = sentence.split() 

  # this is a list of strings containing the 'category' of each word
  output = [] 

  for word in words:
    if word in dictionary:
      # base case, the word is in the dictionary
      output.append(dictionary[word])
    else:
      # recursive case, the word still has tokens attached

      # get all the tokens in the word
      tokens = [key for key in dictionary.keys() if key in word]

      # sort all the tokens by length - this makes sure big words are more likely to be preserved. (scat -> s, cat or sc, at) check 
      tokens.sort(key=len)

      # this is where we'll store the output 
      sub_output = None

      # iterate through the tokens to find if there's a valid way to split the word
      for token in tokens:
        try: 

          # pad the tokens inside each word
          sub_output = parse(
            word.replace(token, f" {token} "), 
            dictionary
          )

          # if the word is parsable, no need to try other combinations
          break
        except: 
          pass # the word couldn't be split

      # make sure that the word was split - if it wasn't it's not a valid word and the sentence can't be parsed
      assert sub_output is not None

      output.append(sub_output)

  # put it all together into a neat little string
  return ' '.join(output)

Вот как вы будете его использовать:

# usage of parse
output = parse(sentence, dictionary)

# display the example output
print(output)

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

Тада! ?

Если вы ищете подход, основанный не на регулярных выражениях, вы можете попробовать следующее:

def tag_pos(sentence):
    output = []
    for word in sentence.split():
        if word not in dictionary:
            literal = ''.join([char for char in word if not char.isalpha()])
            word = ''.join([char for char in word if char.isalpha()])
            output.append(dictionary[word])
            if not len(literal)>1:

                output.append(dictionary[literal])
            else:

                for literal in other:
                    output.append(dictionary[literal])
        else:
            output.append(dictionary[word])

    return " ".join(output)


output = tag_pos(sentence)
print(output)

Другие вопросы по теме