【问题标题】:Differentiate between countries and cities in spacy NER区分空间NER中的国家和城市
【发布时间】:2020-04-14 01:52:19
【问题描述】:

我正在尝试使用 spacy NER 从组织地址中提取国家/地区,但是,它使用相同的标签 GPE 标记国家和城市。有什么方法可以区分它们吗?

例如:

nlp = en_core_web_sm.load()

doc= nlp('Resilience Engineering Institute, Tempe, AZ, United States; Naval Postgraduate School, Department of Operations Research, Monterey, CA, United States; Arizona State University, School of Sustainable Engineering and the Built Environment, Tempe, AZ, United States; Arizona State University, School for the Future of Innovation in Society, Tempe, AZ, United States')

for ent in doc.ents:
    if ent.label_ == 'GPE':
        print(ent.text)

回馈

Tempe
AZ
United States
United States
Tempe
AZ
United States
Tempe
AZ
United States

【问题讨论】:

  • Spacy 的文档指出 GPE 实体类型适用于国家、城市和州。
  • 那么有什么解决办法吗?

标签: python spacy


【解决方案1】:

正如其他答案所提到的,预训练 Spacy 模型的 GPE 适用于国家、城市和州。但是,有一种解决方法,我确信可以使用多种方法。

一种方法:您可以向模型添加自定义标签。 Towards Data Science 上有一篇很好的文章可以帮助你做到这一点。为此收集训练数据可能会很麻烦,因为您需要根据句子中各自的位置标记城市/国家。我引用Stack Overflow的答案:

Spacy NER 模型训练包括提取其他“隐式”特征,例如 POS 和周围词。

当您尝试对单个单词进行训练时,它无法获得足够的泛化特征来检测这些实体。

更简单的解决方法如下:

安装geonamescache

pip install geonamescache

然后使用以下代码获取国家和城市列表

import geonamescache

gc = geonamescache.GeonamesCache()

# gets nested dictionary for countries
countries = gc.get_countries()

# gets nested dictionary for cities
cities = gc.get_cities()

文档指出,您还可以获得许多其他位置选项。

使用以下函数从嵌套字典中获取具有特定名称的键的所有值(从此answer获得)

def gen_dict_extract(var, key):
    if isinstance(var, dict):
        for k, v in var.items():
            if k == key:
                yield v
            if isinstance(v, (dict, list)):
                yield from gen_dict_extract(v, key)
    elif isinstance(var, list):
        for d in var:
            yield from gen_dict_extract(d, key)

分别加载citiescountries的两个列表。

cities = [*gen_dict_extract(cities, 'name')]
countries = [*gen_dict_extract(countries, 'name')]

然后用下面的代码来区分:

nlp = spacy.load("en_core_web_sm")

doc= nlp('Resilience Engineering Institute, Tempe, AZ, United States; Naval Postgraduate School, Department of Operations Research, Monterey, CA, United States; Arizona State University, School of Sustainable Engineering and the Built Environment, Tempe, AZ, United States; Arizona State University, School for the Future of Innovation in Society, Tempe, AZ, United States')

for ent in doc.ents:
    if ent.label_ == 'GPE':
        if ent.text in countries:
            print(f"Country : {ent.text}")
        elif ent.text in cities:
            print(f"City : {ent.text}")
        else:
            print(f"Other GPE : {ent.text}")

输出:

City : Tempe
Other GPE : AZ
Country : United States
Country : United States
City : Tempe
Other GPE : AZ
Country : United States
City : Tempe
Other GPE : AZ
Country : United States

【讨论】:

    【解决方案2】:

    如前所述,GPE 实体预测 Countries, cities and states,因此您将无法使用给定模型仅检测国家实体。

    我建议简单地创建一个国家/地区列表,然后检查GPE 实体是否在此列表中。

    nlp = en_core_web_sm.load()
    
    doc= nlp('Resilience Engineering Institute, Tempe, AZ, United States; Naval Postgraduate School, Department of Operations Research, Monterey, CA, United States; Arizona State University, School of Sustainable Engineering and the Built Environment, Tempe, AZ, United States; Arizona State University, School for the Future of Innovation in Society, Tempe, AZ, United States')
    
    # create a list of country names that possibly appear in the text
    countries = ['US', 'USA', 'United States']
    
    for ent in doc.ents:
        if ent.label_ == 'GPE':
            # check if the value is in the list of countries
            if ent.text in countries:
                print(ent.text, '-- Country')
            else:
                print(ent.text, '-- City or State')
    

    这将输出以下内容:

    坦佩 -- 城市或州

    美国 -- 国家

    蒙特雷 -- 城市或州

    美国 -- 国家

    坦佩 -- 城市或州

    美国 -- 国家

    美国 -- 国家

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-14
      • 2015-11-18
      • 1970-01-01
      • 1970-01-01
      • 2011-04-28
      • 2011-10-12
      相关资源
      最近更新 更多