Подтвердить что ты не робот

Улучшение извлечения человеческих имен с помощью nltk

Я пытаюсь извлечь человеческие имена из текста.

Есть ли у кого-нибудь метод, который они рекомендуют?

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

Я получаю приличные результаты, но мне было интересно, есть ли способы решить эту проблему.

код:

import nltk
from nameparser.parser import HumanName

def get_human_names(text):
    tokens = nltk.tokenize.word_tokenize(text)
    pos = nltk.pos_tag(tokens)
    sentt = nltk.ne_chunk(pos, binary = False)
    person_list = []
    person = []
    name = ""
    for subtree in sentt.subtrees(filter=lambda t: t.node == 'PERSON'):
        for leaf in subtree.leaves():
            person.append(leaf[0])
        if len(person) > 1: #avoid grabbing lone surnames
            for part in person:
                name += part + ' '
            if name[:-1] not in person_list:
                person_list.append(name[:-1])
            name = ''
        person = []

    return (person_list)

text = """
Some economists have responded positively to Bitcoin, including 
Francois R. Velde, senior economist of the Federal Reserve in Chicago 
who described it as "an elegant solution to the problem of creating a 
digital currency." In November 2013 Richard Branson announced that 
Virgin Galactic would accept Bitcoin as payment, saying that he had invested 
in Bitcoin and found it "fascinating how a whole new global currency 
has been created", encouraging others to also invest in Bitcoin.
Other economists commenting on Bitcoin have been critical. 
Economist Paul Krugman has suggested that the structure of the currency 
incentivizes hoarding and that its value derives from the expectation that 
others will accept it as payment. Economist Larry Summers has expressed 
a "wait and see" attitude when it comes to Bitcoin. Nick Colas, a market 
strategist for ConvergEx Group, has remarked on the effect of increasing 
use of Bitcoin and its restricted supply, noting, "When incremental 
adoption meets relatively fixed supply, it should be no surprise that 
prices go up. And that’s exactly what is happening to BTC prices."
"""

names = get_human_names(text)
print "LAST, FIRST"
for name in names: 
    last_first = HumanName(name).last + ', ' + HumanName(name).first
        print last_first

Вывод:

LAST, FIRST
Velde, Francois
Branson, Richard
Galactic, Virgin
Krugman, Paul
Summers, Larry
Colas, Nick

Помимо Virgin Galactic, это все допустимый выход. Конечно, зная, что Virgin Galactic не является человеческим именем в контексте этой статьи, это трудная (может быть, невозможная) часть.

4b9b3361

Ответ 1

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

Взгляните на именуемый указатель Entity Recognizer (NER) в Стэнфорде. Его привязка включена в NLTK v 2.0, но вы должны загрузить некоторые основные файлы. Вот script, который может сделать все это для вас.

Я написал этот script:

import nltk
from nltk.tag.stanford import NERTagger
st = NERTagger('stanford-ner/all.3class.distsim.crf.ser.gz', 'stanford-ner/stanford-ner.jar')
text = """YOUR TEXT GOES HERE"""

for sent in nltk.sent_tokenize(text):
    tokens = nltk.tokenize.word_tokenize(sent)
    tags = st.tag(tokens)
    for tag in tags:
        if tag[1]=='PERSON': print tag

и получил не очень плохой результат:

( "Франсуа", "ПЕРСОН" ) ('R.', 'PERSON') ( "Вельде", "ЧЕЛОВЕК" ) ( "Ричард", "ЧЕЛОВЕК" ) ( "Брэнсон", "ЧЕЛОВЕК" ) ( "Дева", "ЧЕЛОВЕК" ) ( "Галактика", "ЧЕЛОВЕК" ) ( "Биткойн" , "ЧЕЛОВЕК" ) ( "Биткойн" , "ЧЕЛОВЕК" ) ( "Павел", "ЧЕЛОВЕК" ) ( "Кругман", "ЧЕЛОВЕК" ) ( "Ларри", "ЧЕЛОВЕК" ) ( "Саммерс", "ЧЕЛОВЕК" ) ( "Биткойн" , "ЧЕЛОВЕК" ) ( "Ник", "ЧЕЛОВЕК" ) ('Colas', 'PERSON')

Надеюсь, что это будет полезно.

Ответ 2

Для всех, кто ищет, я нашел эту статью полезной: http://timmcnamara.co.nz/post/2650550090/extracting-names-with-6-lines-of-python-code

>>> import nltk
>>> def extract_entities(text):
...     for sent in nltk.sent_tokenize(text):
...         for chunk in nltk.ne_chunk(nltk.pos_tag(nltk.word_tokenize(sent))):
...             if hasattr(chunk, 'node'):
...                 print chunk.node, ' '.join(c[0] for c in chunk.leaves())
...

Ответ 3

Вы можете попытаться разрешить найденные имена и проверить, можете ли вы найти их в базе данных, например freebase.com. Получите данные локально и запросите его (в RDF) или используйте google api: https://developers.google.com/freebase/v1/getting-started. Большинство крупных компаний, географические местоположения и т.д. (Которые были бы уловлены вашим фрагментом) можно было бы отбросить на основе данных freebase.

Ответ 5

Я на самом деле хотел извлечь только имя человека, поэтому подумал, чтобы проверить все имена, которые приходят в качестве результата, против wordnet (большая лексическая база данных на английском языке). Дополнительную информацию о Wordnet можно найти здесь: http://www.nltk.org/howto/wordnet.html.

import nltk
from nameparser.parser import HumanName
from nltk.corpus import wordnet

person_names=person_list
person_list = []
def get_human_names(text):
    tokens = nltk.tokenize.word_tokenize(text)
    pos = nltk.pos_tag(tokens)
    sentt = nltk.ne_chunk(pos, binary = False)

    person = []
    name = ""
    for subtree in sentt.subtrees(filter=lambda t: t.label() == 'PERSON'):
        for leaf in subtree.leaves():
            person.append(leaf[0])
        if len(person) > 1: #avoid grabbing lone surnames
            for part in person:
                name += part + ' '
            if name[:-1] not in person_list:
                person_list.append(name[:-1])
            name = ''
        person = []
#     print (person_list)

text = """

Some economists have responded positively to Bitcoin, including 
Francois R. Velde, senior economist of the Federal Reserve in Chicago 
who described it as "an elegant solution to the problem of creating a 
digital currency." In November 2013 Richard Branson announced that 
Virgin Galactic would accept Bitcoin as payment, saying that he had invested 
in Bitcoin and found it "fascinating how a whole new global currency 
has been created", encouraging others to also invest in Bitcoin.
Other economists commenting on Bitcoin have been critical. 
Economist Paul Krugman has suggested that the structure of the currency 
incentivizes hoarding and that its value derives from the expectation that 
others will accept it as payment. Economist Larry Summers has expressed 
a "wait and see" attitude when it comes to Bitcoin. Nick Colas, a market 
strategist for ConvergEx Group, has remarked on the effect of increasing 
use of Bitcoin and its restricted supply, noting, "When incremental 
adoption meets relatively fixed supply, it should be no surprise that 
prices go up. And thats exactly what is happening to BTC prices."
"""

names = get_human_names(text)
for person in person_list:
    person_split = person.split(" ")
    for name in person_split:
        if wordnet.synsets(name):
            if(name in person):
                person_names.remove(person)
                break

print(person_names)

ВЫХОД

['Francois R. Velde', 'Richard Branson', 'Economist Paul Krugman', 'Nick Colas']

Кроме Ларри Саммерса все имена верны, и это из-за фамилии "Саммерс".

Ответ 6

Ответ @trojane для меня не совсем сработал, но он помог мне в этом.

Prerequesites

Создайте папку stanford-ner и загрузите в нее следующие два файла:

Script

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import nltk
from nltk.tag.stanford import StanfordNERTagger

text = u"""
Some economists have responded positively to Bitcoin, including
Francois R. Velde, senior economist of the Federal Reserve in Chicago
who described it as "an elegant solution to the problem of creating a
digital currency." In November 2013 Richard Branson announced that
Virgin Galactic would accept Bitcoin as payment, saying that he had invested
in Bitcoin and found it "fascinating how a whole new global currency
has been created", encouraging others to also invest in Bitcoin.
Other economists commenting on Bitcoin have been critical.
Economist Paul Krugman has suggested that the structure of the currency
incentivizes hoarding and that its value derives from the expectation that
others will accept it as payment. Economist Larry Summers has expressed
a "wait and see" attitude when it comes to Bitcoin. Nick Colas, a market
strategist for ConvergEx Group, has remarked on the effect of increasing
use of Bitcoin and its restricted supply, noting, "When incremental
adoption meets relatively fixed supply, it should be no surprise that
prices go up. And that’s exactly what is happening to BTC prices.
"""

st = StanfordNERTagger('stanford-ner/english.all.3class.distsim.crf.ser.gz',
                       'stanford-ner/stanford-ner.jar')

for sent in nltk.sent_tokenize(text):
    tokens = nltk.tokenize.word_tokenize(sent)
    tags = st.tag(tokens)
    for tag in tags:
        if tag[1] in ["PERSON", "LOCATION", "ORGANIZATION"]:
            print(tag)

Результаты

(u'Bitcoin', u'LOCATION')       # wrong
(u'Francois', u'PERSON')
(u'R.', u'PERSON')
(u'Velde', u'PERSON')
(u'Federal', u'ORGANIZATION')
(u'Reserve', u'ORGANIZATION')
(u'Chicago', u'LOCATION')
(u'Richard', u'PERSON')
(u'Branson', u'PERSON')
(u'Virgin', u'PERSON')         # Wrong
(u'Galactic', u'PERSON')       # Wrong
(u'Bitcoin', u'PERSON')        # Wrong
(u'Bitcoin', u'LOCATION')      # Wrong
(u'Bitcoin', u'LOCATION')      # Wrong
(u'Paul', u'PERSON')
(u'Krugman', u'PERSON')
(u'Larry', u'PERSON')
(u'Summers', u'PERSON')
(u'Bitcoin', u'PERSON')        # Wrong
(u'Nick', u'PERSON')
(u'Colas', u'PERSON')
(u'ConvergEx', u'ORGANIZATION')
(u'Group', u'ORGANIZATION')     
(u'Bitcoin', u'LOCATION')       # Wrong
(u'BTC', u'ORGANIZATION')       # Wrong

Ответ 7

Это работало очень хорошо для меня. Мне просто нужно было изменить одну строку, чтобы она могла работать.

    for subtree in sentt.subtrees(filter=lambda t: t.node == 'PERSON'):

должно быть

    for subtree in sentt.subtrees(filter=lambda t: t.label() == 'PERSON'):

На выходе были недостатки (например, он идентифицировал "Отмывание денег" как человека), но с моими данными база данных имен не может быть надежной.

Ответ 8

Я хотел бы опубликовать здесь жестокое и жадное решение, чтобы решить проблему, поставленную @Enthusiast: по возможности получите полное имя человека.

Прописная Spacy первого символа в каждом имени используется в качестве критерия для распознавания ЛИЦА в Spacy. Например, сам Джим Хоффман не будет распознан как именованная сущность, в то время как Джим Хоффман будет.

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

import spacy

def capitalizeWords(text):

  newText = ''

  for sentence in text.split('.'):
    newSentence = ''
    for word in sentence.split():
      newSentence += word+' '
    newText += newSentence+'\n'

  return newText

nlp = spacy.load('en_core_web_md')

doc = nlp(capitalizeWords(rawText))

#......

Обратите внимание, что этот подход охватывает полные имена за счет увеличения ложных срабатываний.