3

这是我的问题。我有一个示例文本文件,通过爬取各种 html 页面来存储文本数据。此文本包含有关各种事件及其时间和地点的信息。我想获取这些位置的坐标。我不知道如何在 python 中做到这一点。我正在使用 nltk 来识别此示例文本中的命名实体。这是代码:

import nltk

with open('sample.txt', 'r') as f:
    sample = f.read()

sentences = nltk.sent_tokenize(sample)
tokenized_sentences = [nltk.word_tokenize(sentence) for sentence in sentences]
tagged_sentences = [nltk.pos_tag(sentence) for sentence in tokenized_sentences]
chunked_sentences = nltk.batch_ne_chunk(tagged_sentences, binary=True)

#print chunked_sentences
#print tokenized_sentences
#print tagged_sentences

def extract_entity_names(t):
    entity_names = []

    if hasattr(t, 'node') and t.node:
        if t.node == 'NE':
            entity_names.append(' '.join([child[0] for child in t]))
        else:
            for child in t:
                entity_names.extend(extract_entity_names(child))

    return entity_names

entity_names = []
for tree in chunked_sentences:
    # Print results per sentence
    # print extract_entity_names(tree)

    entity_names.extend(extract_entity_names(tree))

# Print all entity names
#print entity_names

# Print unique entity names
print set(entity_names)

示例文件是这样的:

考文特花园的波西米亚人

时间:2013 年 1 月 18 日(不同日期),晚上 7:30 地点:伦敦考文特花园,约翰·科普利(John Copley)常年流行的皇家歌剧院作品普契尼(Puccini)的《波西米亚人》(La bohème)在本季两次中的第一次重演,恰逢圣诞节期间。马克·埃尔德爵士指挥罗兰多·维拉宗饰演鲁道夫,麦加·科瓦列夫斯卡饰演咪咪。一个寒冷的平安夜,咪咪在巴黎拉丁区遇到了诗人鲁道夫(Dmytro Popov 于 1 月 5 日至 18 日演唱该角色)。在她的蜡烛熄灭后,他们在黑暗中摸索,坠入爱河。鲁道夫和另外三个小伙子住在一起:哲学家科林(Nahuel di Pierro/Jihoon Kim,1 月 18 日)、音乐家 Schaunard(大卫比齐奇)和喜欢穆塞塔(Stefania Dovhan)的画家马塞洛(奥登艾弗森)。

我想从此文本中获取伦敦考文特花园的坐标。我该怎么做 ?

4

3 回答 3

6

自 2013 年 9 月起,Google Maps API v2不再有效。这是一个用于 API v3 的优秀 @jimhark 代码的更新版本(我省略了这__main__部分):

import urllib
import simplejson

googleGeocodeUrl = 'http://maps.googleapis.com/maps/api/geocode/json?'

def get_coordinates(query, from_sensor=False):
    query = query.encode('utf-8')
    params = {
        'address': query,
        'sensor': "true" if from_sensor else "false"
    }
    url = googleGeocodeUrl + urllib.urlencode(params)
    json_response = urllib.urlopen(url)
    response = simplejson.loads(json_response.read())
    if response['results']:
        location = response['results'][0]['geometry']['location']
        latitude, longitude = location['lat'], location['lng']
        print query, latitude, longitude
    else:
        latitude, longitude = None, None
        print query, "<no results>"
    return latitude, longitude

有关参数和其他信息的完整列表,请参阅官方文档

于 2014-03-14T08:30:54.337 回答
5

你真的有两个问题:

  1. 如何提取位置文本(或潜在位置文本)。
  2. 如何通过使用位置文本调用地理编码服务来获取位置(纬度、经度)。

第二个问题我可以帮忙。(但请参阅下面的编辑以获取有关您的第一个问题的一些帮助。)

使用旧的 Google Maps API(仍在工作),您可以将地理编码降低到一行(一条丑陋的行):

def geocode(address):
    return tuple([float(s) for s in list(urllib.urlopen('http://maps.google.com/maps/geo?' + urllib.urlencode({'output': 'csv','q': address})))[0].split(',')[2:]])

查看Google Maps API 地理编码文档

这是可读的 7 行版本加上一些包装代码(从命令行调用时,请记住将地址括在引号中):

import sys
import urllib

googleGeocodeUrl = 'http://maps.google.com/maps/geo?'

def geocode(address):
    parms = {
        'output': 'csv',
        'q': address}

    url = googleGeocodeUrl + urllib.urlencode(parms)
    resp = urllib.urlopen(url)
    resplist = list(resp)
    line = resplist[0]
    status, accuracy, latitude, longitude = line.split(',')
    return latitude, longitude

def main():
    if 1 < len(sys.argv):
        address = sys.argv[1]
    else:
        address = '1600 Amphitheatre Parkway, Mountain View, CA 94043, USA'

    coordinates = geocode(address)
    print coordinates

if __name__ ==  '__main__':
    main()

解析 CSV 格式很简单,但是 XML 格式有更好的错误报告。

编辑 - 帮助您解决第一个问题

我看着nltk。这不是微不足道的,但我可以推荐自然语言工具包文档,第 7 章 - 从文本中提取信息,特别是7.5 Named Entity Recognition. 在本节的最后,他们指出:

NLTK 提供了一个已经被训练来识别命名实体的分类器,可以通过函数 nltk.ne_chunk() 访问。如果我们设置参数 binary=True ,那么命名实体就被标记为 NE;否则,分类器会添加类别标签,例如 PERSON、ORGANIZATION 和 GPE。

您正在指定True,但您可能需要类别标签,因此:

chunked_sentences = nltk.batch_ne_chunk(tagged_sentences)

这提供了类别标签(命名实体类型),看起来很有希望。但是在你的文本和一些带有位置的简单短语尝试了这个之后,很明显需要更多的规则。阅读文档以获取更多信息。

于 2013-01-29T11:37:24.660 回答
1

您要执行的操作称为地理编码操作。当然,您必须自己在文本信息块中提取“位置”信息。

您可以使用以下服务执行此操作:

请记住,您应该考虑可能适用于您的许可证,具体取决于您的用例。

于 2013-01-29T11:08:27.973 回答