如何检查输入字符串是否包含街道地址?

How to check an input string contains street address or not?

我们想要识别文档中的地址字段。为了识别地址字段,我们使用 Tesseract 将文档转换为 OCR 文件。从 tesseract 输出我们想检查一个字符串是否包含地址字段。解决这个问题的正确策略是什么?

  1. 无法使用正则表达式解决此问题,因为不同文档和国家/地区的地址字段不同
  2. 尝试使用 NLTK 对单词进行分类,但对地址字段效果不佳。

需要输出

I am staying at 234 23 Philadelphia - Contains address files <234 23 Philadelphia>

I am looking for a place to stay - Not contains address 

提供解决此问题的建议。

在许多 ML 问题中,有多种可能的解决方案,重要的部分(通常影响更大的部分)不是您使用哪种算法或模型,而是特征工程、数据预处理和标准化等像那样。第一个解决方案出现在我的脑海中(这只是一个想法,我会测试它并看看它是如何执行的)它的:

  1. 获取您的训练集示例并列出所有示例中 "N" 个最常用的单词(即您的词汇表),此列表将包含每个 "N" 个最常用的单词,每个单词将由一个数字(列表索引)表示
  2. 转换您的训练示例:阅读每个训练示例并更改其表示,用词汇表中单词的数量替换每个单词。
  3. 最后,为每个训练示例创建一个与词汇表大小相同的特征向量,对于词汇表中的每个单词,你的特征向量将为 0(对应的单词在你的示例中不存在)或 1(它exists),或者这个词出现的次数(再次强调,这是特征工程)
  4. 训练多个分类器、可变算法、参数、训练集大小等,并进行交叉验证以选择最佳模型。

并从那里保持标准的 ML 工作流程...

如果您只想检查是或否而不是提取完整地址,一个简单的解决方案可以是 NER。

您可以尝试检查文本是否包含位置。

例如:

import nltk 
def check_location(text):
    for chunk in nltk.ne_chunk(nltk.pos_tag(nltk.word_tokenize(text))):
        if hasattr(chunk, "label"):
            if chunk.label() == "GPE" or chunk.label() == "GSP":
                return "True"
    return "False"

text="I am staying at 234 23 Philadelphia."
print(text+" - "+check_location(text))

text="I am looking for a place to stay."
print(text+" - "+check_location(text))

输出:

# I am staying at 234 23 Philadelphia. - True 
# I am looking for a place to stay. - False

如果您还想提取完整地址,则需要训练您自己的模型。

您可以查看:NER with NLTK , CRF++.

为什么说正则表达式不起作用?

基本上,以正则表达式的形式定义您可能遇到的所有不同形式的地址。然后,匹配表达式。

你是对的。 Using regex to find an address in a string is messy.

有 API 会尝试为您提取地址。这些 API 并不总能保证从字符串中提取地址,但它们会尽力而为。街道地址提取的一个示例 API 来自 SmartyStreets。 Documentation here and demo here.

需要考虑的一点是,即使您的示例 (I am staying at 234 23 Philadelphia) 也不包含完整地址。它缺少州或邮政编码字段。这使得很难以编程方式确定是否存在地址。一旦将州或邮政编码添加到该示例字符串 (I am staying at 234 23 Philadelphia PA),就可以更容易地以编程方式确定字符串中是否包含地址。

免责声明:我为 SmartyStreets 工作

执行此任务的更好方法如下:

  1. 训练您自己的自定义 NER 模型(扩展预训练的 SpaCy's 模型或构建您自己的 CRF++ / CRF-biLSTM 模型,如果您有注释数据)或使用预训练模型,如 SpaCy's 大型模型或 geopandas 等

  2. 根据您的问题陈述定义加权评分机制。 例如 - 假设每个地址都有 3 个重要组成部分 - 地址、电话 phone 号码和电子邮件 ID。 Text that would have all three of them would get a score of 33.33% + 33.33% + 33.33% = 100 %

  3. 为了确定它是否是 address field,您可以考虑 - SpaCy's 位置标签(GPE、FAC、LOC 等)的百分比文本中的总标记,可以很好地估计文本中存在多少位置标签。然后 运行 邮政编码的正则表达式,并将找到的城市名称与找到的邮政编码之前的 3-4 个单词匹配,如果有重叠,则您已正确识别邮政编码,因此 address field -(获得 33.33% 的分数!)。

  4. 对于 telephone numbers - 某些检查和正则表达式可以做到,但一个重要的标准是它仅在找到 address field 时才执行这些 phone 检查在上面的文字中。

  5. 对于 emails/web address,您可以再次执行名义正则表达式检查,最后将所有这 3 个分数加到一个累积值中。

  6. 一个理想的 address 会得到 100 分,而缺少字段会得到 66% 等。文本的其余部分会得到 0 分。

希望对您有所帮助! :)