【问题标题】:How to check an input string contains street address or not?如何检查输入字符串是否包含街道地址?
【发布时间】:2016-11-24 06:41:31
【问题描述】:

我们想要识别文档中的地址字段。为了识别地址字段,我们使用 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 

提供解决此问题的建议。

【问题讨论】:

    标签: machine-learning neural-network nltk street-address text-classification


    【解决方案1】:

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

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

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

    免责声明:我为 SmartyStreets 工作

    【讨论】:

      【解决方案2】:

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

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

      2. 根据您的问题陈述定义加权评分机制。 例如 - 假设每个地址都有 3 个重要组成部分 - 地址、电话号码和电子邮件 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 位于上述文本中时,它才会执行这些电话检查。

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

      6. 理想的address 将获得 100 分,而缺少字段的收益率为 66%,以此类推。其余文本将获得 0 分。

      希望对您有所帮助! :)

      【讨论】:

        【解决方案3】:

        为什么你说正则表达式行不通?

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

        【讨论】:

        • 世界上所有的地址字段都没有足够的正则表达式,其中邮政编码格式不同,城市名称或缩写可能用于其他国家的其他内容。只有 ML 解决方案才能帮助解决这个问题。
        【解决方案4】:

        如果您只想检查“是”或“否”而不是提取完整地址,那么一种简单的解决方案可以是 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 NLTKCRF++

        【讨论】:

          【解决方案5】:

          与许多机器学习问题一样,有多种可能的解决方案,重要的部分(通常影响更大的部分)不是您使用哪种算法或模型,而是特征工程、数据预处理和标准化等等.我想到了第一个解决方案(它只是一个想法,我会对其进行测试,看看它的表现如何)它:

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

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

          【讨论】:

          • 我不认为矢量化城市名称或位置名称是一个好主意。您使用的 BoW 模型背后的想法是假设您事先知道词汇表,在这种情况下,没有任何词汇表可以包含所有城市名称、州名或邮政编码格式。
          猜你喜欢
          • 2014-07-25
          • 2016-09-24
          • 2012-07-14
          • 2013-05-01
          • 2018-02-16
          • 2016-04-22
          • 1970-01-01
          • 2020-07-12
          • 1970-01-01
          相关资源
          最近更新 更多