因实验需要,需要在文本中提取出地区信息,也算是 NER 中的一部分。
在经过查阅后,基本上都是推荐 geotext 或者 geograpy3 工具包,或者使用数据库自己匹配。都有缺点吧,geotext 据说 USA 这样的缩写也识别不出来。
在这里的话,我自己是推荐 flashgeotext ,经过实验,是可以识别出 USA, US 这种缩写的。
缺点
1.识别不了中文,还好我处理的都是英文数据集。
2.识别出来的都是标准的国家英文,比如说 Saudi Arabia 可以识别出,Saudi 就识别不出来了。
解决办法就是可以自己添加,具体可以看官方文档,我还没看完,目前就不写了。
from flashgeotext.geotext import GeoText
import json
geotext = GeoText()
input_text = '''USA and US are the abbreviations of American English, the United States and China are enemies'''
dic = geotext.extract(input_text=input_text)
data = json.dumps(dic, indent=4)
print(data)
# 输出
'''
{
"cities": {},
"countries": {
"United States": {
"count": 3,
"span_info": [
[
0,
3
],
[
8,
10
],
[
58,
71
]
],
"found_as": [
"USA",
"US",
"United States"
]
},
"China": {
"count": 1,
"span_info": [
[
76,
81
]
],
"found_as": [
"China"
]
}
}
}
'''
举例
以官方的说明为例 usage - flashgeotext (iwpnd.pw):
from flashgeotext.geotext import GeoText
geotext = GeoText()
input_text = '''Shanghai. The Chinese Ministry
of Finance in Shanghai said that
China plans to cut tariffs on
$75 billion worth of goods that
the country imports from the US.
Washington welcomes the decision.'''
geotext.extract(input_text=input_text)
>> {
'cities': {
'Shanghai': {
'count': 2,
'span_info': [(0, 8), (45, 53)],
'found_as': ['Shanghai', 'Shanghai']
},
'Washington, D.C.': {
'count': 1,
'span_info': [(175, 185)],
'found_as': ['Washington']
}
},
'countries': {
'China': {
'count': 1,
'span_info': [(64, 69)],
'found_as': ['China']
},
'United States': {
'count': 1,
'span_info': [(171, 173)],
'found_as': ['US'],
}
}
}
每次会得到 cities 和 countries 结果,我自己是需要拿到原文的字符串,即 found_as 的结果。写成一个方法调用它。对嵌套字典操作不太熟悉,先这样写了,要是有简洁的方法可以评论里说一下。
def get_area(input_text):
geotext = GeoText()
dic = geotext.extract(input_text=input_text) # 得到city,country
# data = json.dumps(dic, indent=4)
# print(data) # data是list类型
city = dic['cities']
country = dic['countries']
cities_lst = []
countries_lst = []
if city:
city_lst = list(city.values())
for i in city_lst:
ci = i['found_as']
cities_lst.extend(ci) # 直接添加到一个列表
else:
print('没有识别到city信息')
if country:
country_lst = list(country.values())
for i in country_lst:
co = i['found_as']
countries_lst.extend(co)
else:
print('没有识别到country信息')
return list(set(cities_lst)), list(set(countries_lst)) # 返回提取到的city,country
if __name__ == '__main__':
str3 = '''Shanghai. The Chinese Ministry
of Finance in Shanghai said that
China plans to cut tariffs on
$75 billion worth of goods that
the country imports from the US.
Washington welcomes the decision.'''
ci, co = get_area(str3)
print(ci, co)
ci.extend(co)
print(ci)
>> ['Shanghai', 'Washington'] ['US', 'China']
>> ['Shanghai', 'Washington', 'US', 'China']
我个人是需要合并到一起,只要能识别出来就行。
有个缺点是文本里的名称都要标准的写法,打算后续用文本相似度看看能不能优化一下这个识别,不要这么死板。当然权威的消息渠道肯定也是很标准的,所以近期不会及时处理这个任务了。