如何检查输入字符串是否包含街道地址?
How to check an input string contains street address or not?
我们想要识别文档中的地址字段。为了识别地址字段,我们使用 Tesseract 将文档转换为 OCR 文件。从 tesseract 输出我们想检查一个字符串是否包含地址字段。解决这个问题的正确策略是什么?
- 无法使用正则表达式解决此问题,因为不同文档和国家/地区的地址字段不同
- 尝试使用 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 问题中,有多种可能的解决方案,重要的部分(通常影响更大的部分)不是您使用哪种算法或模型,而是特征工程、数据预处理和标准化等像那样。第一个解决方案出现在我的脑海中(这只是一个想法,我会测试它并看看它是如何执行的)它的:
- 获取您的训练集示例并列出所有示例中 "N" 个最常用的单词(即您的词汇表),此列表将包含每个 "N" 个最常用的单词,每个单词将由一个数字(列表索引)表示
- 转换您的训练示例:阅读每个训练示例并更改其表示,用词汇表中单词的数量替换每个单词。
- 最后,为每个训练示例创建一个与词汇表大小相同的特征向量,对于词汇表中的每个单词,你的特征向量将为 0(对应的单词在你的示例中不存在)或 1(它exists),或者这个词出现的次数(再次强调,这是特征工程)
- 训练多个分类器、可变算法、参数、训练集大小等,并进行交叉验证以选择最佳模型。
并从那里保持标准的 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 工作
执行此任务的更好方法如下:
训练您自己的自定义 NER 模型(扩展预训练的 SpaCy's
模型或构建您自己的 CRF++
/ CRF-biLSTM
模型,如果您有注释数据)或使用预训练模型,如 SpaCy's
大型模型或 geopandas 等
根据您的问题陈述定义加权评分机制。
例如 - 假设每个地址都有 3 个重要组成部分 - 地址、电话 phone 号码和电子邮件 ID。
Text that would have all three of them would get a score of 33.33% + 33.33% + 33.33% = 100 %
为了确定它是否是 address field
,您可以考虑 - SpaCy's
位置标签(GPE、FAC、LOC 等)的百分比文本中的总标记,可以很好地估计文本中存在多少位置标签。然后 运行 邮政编码的正则表达式,并将找到的城市名称与找到的邮政编码之前的 3-4 个单词匹配,如果有重叠,则您已正确识别邮政编码,因此 address field
-(获得 33.33% 的分数!)。
对于 telephone numbers
- 某些检查和正则表达式可以做到,但一个重要的标准是它仅在找到 address field
时才执行这些 phone 检查在上面的文字中。
对于 emails/web address
,您可以再次执行名义正则表达式检查,最后将所有这 3 个分数加到一个累积值中。
一个理想的 address
会得到 100 分,而缺少字段会得到 66% 等。文本的其余部分会得到 0 分。
希望对您有所帮助! :)
我们想要识别文档中的地址字段。为了识别地址字段,我们使用 Tesseract 将文档转换为 OCR 文件。从 tesseract 输出我们想检查一个字符串是否包含地址字段。解决这个问题的正确策略是什么?
- 无法使用正则表达式解决此问题,因为不同文档和国家/地区的地址字段不同
- 尝试使用 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 问题中,有多种可能的解决方案,重要的部分(通常影响更大的部分)不是您使用哪种算法或模型,而是特征工程、数据预处理和标准化等像那样。第一个解决方案出现在我的脑海中(这只是一个想法,我会测试它并看看它是如何执行的)它的:
- 获取您的训练集示例并列出所有示例中 "N" 个最常用的单词(即您的词汇表),此列表将包含每个 "N" 个最常用的单词,每个单词将由一个数字(列表索引)表示
- 转换您的训练示例:阅读每个训练示例并更改其表示,用词汇表中单词的数量替换每个单词。
- 最后,为每个训练示例创建一个与词汇表大小相同的特征向量,对于词汇表中的每个单词,你的特征向量将为 0(对应的单词在你的示例中不存在)或 1(它exists),或者这个词出现的次数(再次强调,这是特征工程)
- 训练多个分类器、可变算法、参数、训练集大小等,并进行交叉验证以选择最佳模型。
并从那里保持标准的 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 工作
执行此任务的更好方法如下:
训练您自己的自定义 NER 模型(扩展预训练的
SpaCy's
模型或构建您自己的CRF++
/CRF-biLSTM
模型,如果您有注释数据)或使用预训练模型,如SpaCy's
大型模型或 geopandas 等根据您的问题陈述定义加权评分机制。 例如 - 假设每个地址都有 3 个重要组成部分 - 地址、电话 phone 号码和电子邮件 ID。
Text that would have all three of them would get a score of 33.33% + 33.33% + 33.33% = 100 %
为了确定它是否是
address field
,您可以考虑 -SpaCy's
位置标签(GPE、FAC、LOC 等)的百分比文本中的总标记,可以很好地估计文本中存在多少位置标签。然后 运行 邮政编码的正则表达式,并将找到的城市名称与找到的邮政编码之前的 3-4 个单词匹配,如果有重叠,则您已正确识别邮政编码,因此address field
-(获得 33.33% 的分数!)。对于
telephone numbers
- 某些检查和正则表达式可以做到,但一个重要的标准是它仅在找到address field
时才执行这些 phone 检查在上面的文字中。对于
emails/web address
,您可以再次执行名义正则表达式检查,最后将所有这 3 个分数加到一个累积值中。一个理想的
address
会得到 100 分,而缺少字段会得到 66% 等。文本的其余部分会得到 0 分。
希望对您有所帮助! :)