2

我正在研究他们提到位置的用户评论数据集。我正在使用nltk( StanfordNERTagger) 并spacy拉出位置。问题是它们有许多不同的形式。例如:(纽约市与纽约市,乔治亚州与佐治亚州等)。此外,我希望检索给定城市的状态。是否有库或方法可以在 Python 中对这些进行规范化?例如,一个像这样工作的库:

g = geo_classify('New York City')
g.cities() => ['New York City']
g.states() => ['New York']
g.countries() => ['United States']

我尝试使用Geograpy3,但它没有检测到某些城市、任何缩写,也没有给我特定城市的状态。有什么建议么?

4

1 回答 1

2

@Big_Mac - 我是 Geograpy 的提交者之一。感谢您试用 Geograpy3。您可能想要使用定位器界面和最近发布的 geograpy3 的最新版本。现在有一个 CityLookup、RegionLookup 和 CountryLookup,它们根据 wikidata 考虑不同的标签。

这是预期的“预览”。在内部,将使用以下 SQL 数据库查询:

纽约示例

询问

select * from cityLookup where label='New York City'

结果

标签 等级 位置种类 维基数据 姓名 地理名称标识 区域标识 国家标识 流行音乐 纬度 partOfRegionId gndId 区域名称 区域Iso 地区流行 地区纬度 区域L​​on 国家的名字 国家ISO 国家纬度 国家/地区
纽约市 5 城市 Q60 纽约市 5128581 Q1384 Q30 8398748 41 -74 Q1384 4042011-5 纽约 美国-纽约 19795791 43 -75 美国 我们 40 -99

这是我目前用来测试geograpy3当前状态的一些示例代码:

'''
Created on 2021-08-11

@author: wf
'''
#from lodstorage.entity import EntityManager
from geograpy.locator import LocationContext
import OSMPythonTools
from OSMPythonTools.nominatim import Nominatim 
import os
import logging

class LocationLookup:
    '''
    lookup locations
    '''
    preDefinedLocations={
        "Not Known": None,
        "Online": None,
    }
    other={
        "Washington, DC, USA": "Q61",
        "Bangalore": "Q1355",
        "Bangalore, India": "Q1355",
        "Xi'an": "Q5826",
        "Xi'an, China": "Q5826",
        "Virtual Event USA": "Q30",
        "Virtual USA": "Q30",
        "London United Kingdom": "Q84",
        "Brno":"Q14960",
        "Cancun":"Q8969",
        "St. Petersburg": "Q656",
        "Gothenburg Sweden": "Q25287",
        "Los Angeles California": "Q65",
        "Zurich, Switzerland": "Q72",
        "Barcelona Spain": "Q1492",
        "Vienna Austria": "Q1741",
        "Seoul Republic of Korea": "Q8684",
        "Seattle WA USA": "Q5083",
        "Singapore Singapore":"Q334",
        "Tokyo Japan": "Q1490",
        "Vancouver BC Canada": "Q24639",
        "Vancouver British Columbia Canada": "Q24639",
        "Amsterdam Netherlands":"Q727",
        "Paris France": "Q90",
        "Nagoya": "Q11751",
        "Marrakech":"Q101625",
        "Austin Texas":"Q16559",
        "Chicago IL USA":"Q1297",
        "Bangkok Thailand":"Q1861",
        "Firenze, Italy":"Q2044",
        "Florence Italy":"Q2044",
        "Timisoara":"Q83404",
        "Langkawi":"Q273303",
        "Beijing China":"Q956",
        "Berlin Germany": "Q64",
        "Prague Czech Republic":"Q1085",
        "Portland Oregon USA":"Q6106",
        "Portland OR USA":"Q6106",
        "Pittsburgh PA USA":"Q1342",
        "Новосибирск":"Q883",
        "Los Angeles CA USA":"Q65",
        "Kyoto Japan": "Q34600"
    }

    def __init__(self):
        '''
        Constructor
        '''
        self.locationContext=LocationContext.fromCache()
        cacheRootDir=LocationContext.getDefaultConfig().cacheRootDir
        cacheDir=f"{cacheRootDir}/.nominatim"
        if not os.path.exists(cacheDir):
            os.makedirs(cacheDir)
            
        self.nominatim = Nominatim(cacheDir=cacheDir)
        logging.getLogger('OSMPythonTools').setLevel(logging.ERROR)
        
        
    def getCityByWikiDataId(self,wikidataID:str):
        '''
        get the city for the given wikidataID
        '''
        citiesGen=self.locationContext.cityManager.getLocationsByWikidataId(wikidataID)
        if citiesGen is not None:
            cities=list(citiesGen)
            if len(cities)>0:
                return cities[0]
        else:
            return None
        
    def lookupNominatim(self,locationText:str):
        location=None
        nresult=self.nominatim.query(locationText,params={"extratags":"1"})
        nlod=nresult._json
        if len(nlod)>0:
            nrecord=nlod[0]
            if "extratags" in nrecord:
                extratags=nrecord["extratags"]
                if "wikidata" in extratags:
                    wikidataID=extratags["wikidata"]
                    location=self.getCityByWikiDataId(wikidataID)
        return location
        
    def lookup(self,locationText:str):
        lg=self.lookupGeograpy(locationText)
        ln=self.lookupNominatim(locationText)
        if ln is not None and lg is not None and not ln.wikidataid==lg.wikidataid:
            print(f"❌{locationText}→{lg}!={ln}")
            return None
        return lg
        
    def lookupGeograpy(self,locationText:str):
        '''
        lookup the given location by the given locationText
        '''
        if locationText in LocationLookup.preDefinedLocations:
            locationId=LocationLookup.preDefinedLocations[locationText]
            if locationId is None:
                return None
            else:
                location=self.getCityByWikiDataId(locationId)
                return location
        locations=self.locationContext.locateLocation(locationText)
        if len(locations)>0:
            return locations[0]
        else:
            return None
于 2021-08-19T20:35:04.277 回答