web-dev-qa-db-ja.com

nltkを使用した人間の名前の抽出の改善

テキストから人間の名前を抽出しようとしています。

誰もが推奨する方法を持っていますか?

これは私が試したものです(コードは以下):私はnltkを使用して人としてマークされたすべてのものを見つけ、その人のすべてのNNP部分のリストを生成しています。私は、一人の姓をつかむことを避けるNNPが1つしかない人をスキップしています。

私はまともな結果を得ていますが、この問題を解決するためのより良い方法があるかどうか疑問に思っていました。

コード:

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が人間の名前ではないことを知るのは難しい(不可能な場合もある)部分です。

38
emh

「私のコードを改善する」はこのサイトにはあまり適していないという提案に同意する必要がありますが、Dig in

Stanford Named Entity Recognizer(NER) をご覧ください。そのバインディングはNLTK v 2.0に含まれていますが、いくつかのコアファイルをダウンロードする必要があります。ここに 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

そして、それほど悪くない出力を得ました:

(「Francois」、「PERSON」)(「R。」、「PERSON」)(「Velde」、「PERSON」)(「Richard」、「PERSON」)(「Branson」、「PERSON」)(「Virgin」 、「PERSON」)(「Galactic」、「PERSON」)(「Bitcoin」、「PERSON」)(「Bitcoin」、「PERSON」)(「Paul」、「PERSON」)(「Krugman」、「PERSON」) (「ラリー」、「人」)(「夏」、「人」)(「ビットコイン」、「人」)(「ニック」、「人」)(「コーラ」、「人」)

これが役に立てば幸いです。

20
troyane

他の人にとっては、この記事が役に立つと思いました: 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())
...
7
Curtis Mattoon

見つかった名前の解決を試み、freebase.comなどのデータベースでそれらを見つけることができるかどうかを確認できます。データをローカルで取得してクエリ(RDFにあります)するか、googleのapiを使用します: https://developers.google.com/freebase/v1/getting-started 。ほとんどの大企業、地理的位置など(スニペットによって捕捉される)は、freebaseデータに基づいて破棄できます。

5

Spacyは、テキストから名前を取得するための優れた代替手段です。

https://spacy.io/usage/training#ner

4
neel

@trojaneの答えは私にとってはうまくいきませんでしたが、これには大いに役立ちました。

前提条件

フォルダーを作成するstanford-nerそして、次の2つのファイルをダウンロードします。

スクリプト

#!/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
2
Martin Thoma

私は実際に人の名前だけを抽出したかったので、出力として来るすべての名前をワードネット(英語の大きな字句データベース)に対してチェックすることを考えました。 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 that’s 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']

ラリー・サマーズは別として、すべての名前は正確であり、それは「夏」という姓のためです。

2

@Enthusiastが投げかけた問題を解決するために、ここに残忍で貪欲な解決策を投稿したいと思います:可能であれば人のフルネームを取得します。

各名前の最初の文字の大文字は、Spacy内のPERSONを認識するための基準として使用されます。たとえば、「ジムホフマン」自体は名前付きエンティティとして認識されませんが、「ジムホフマン」は名前付きエンティティとして認識されます。

したがって、タスクが単にスクリプトから人を取り出すことである場合、最初に各Wordの最初の文字を大文字にしてから、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))

#......

このアプローチは、誤検知の増加を犠牲にしてフルネームをカバーすることに注意してください。

0
Maxmoe

これは私にとって非常にうまくいきました。実行するには、1行変更する必要がありました。

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

する必要があります

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

出力に不完全性がありましたが(たとえば、「マネーロンダリング」を個人として識別しました)、私のデータでは、名前データベースは信頼できない場合があります。

0
C.Rider