【Python机器学习】NLP信息提取——值得提取的信息
目录
提取GPS信息
提取日期
如下一些关键的定量信息值得“手写”正则表达式:
- GPS位置;
- 日期;
- 价格;
- 数字。
和上述可以通过正则表达式轻松捕获的信息相比,其他一些重要的自然语言信息需要更复杂的模式:
- 问题触发词;
- 问题目标词;
- 命名实体。
提取GPS信息
GPS位置时我们希望正则表达式从文本中提取的各种数值类型数据的典型代表。GPS位置具有成对的经纬度数值。它们有时还包括第三个数值,如高度或海拔高度,但暂时先忽略它。我们只提取十进制的经纬度对,用度数表示。这么模式适用于许多谷歌地图的URL地址。虽然严格说URL不是自然语言,但它们通常是非结构化文本数据的一部分,并且我们希望提取这种信息,从而让聊天机器人能够像了解事物一样了解位置信息。
我们使用十进制数字模式,但增加更多约束,确保该值在纬度和经度的有效范围内。最北到北极(+90度),最高到南极(-90度),具体代码:
import relat=r'([-]?[0-9]?[0-9][.][0-9]{2,10})'
lon=r'([-]?1?[0-9]?[0-9][.][0-9]{2,10})'sep=r'[,/ ]{1,3}'
re_gps=re.compile(lat+sep+lon)print(re_gps.findall('http://...maps/@34.0551066,-118.2496763'))
print(re_gps.findall("Zig Zag Cafe is at 45.344, -121.9323 on my GPS"))

数值类数据很容易提取,特别是当数字式可机读字符串的一部分的时候。URL和其他可机读字符串以可推测的顺序、格式或单位放置纬度和经度等数字,为提取提供了方便。上述模式还可以处理一些超出真实世界的经度和维度值,它可以较好的处理从地图Web应用程序中复制的大部分URL。
提取日期
提取日期比提取GPS坐标要难很多。日期更接近自然语言,可以通过不同的方言表达类似的事物。在美国,17年圣诞节的表示是“12/25/17”,而在欧洲,却表示为“25/12/17”。我们可以检查用户区域设置,并假设在同一个区域,日期表示方式是一样的。但这种假设可能在实际中是不成立的。
因此,大多数日期和时间提取器尝试适配上面两种日/月的表示顺序,并检查以确保是有效的日期。这也是当我们看到这样的日期时大脑的工作方式。即使是美国英语使用者,圣诞节在欧洲,也能认出“25/12/17”是一个假期。
这种在计算机编程中适用的“鸭子类型”方法也适用于自然语言。如果它看起来像一只鸭子并且表现得像是一一只鸭子,那么它可能就是一只鸭子。如果它看起来像日期并且表现得像日期,那么它可能就是日期。我们将在其他自然语言处理任务重也使用这种“先斩后奏”的方法。下面将尝试一系列方法并选择结果正确的方法,这里将尝试使用提取器或生成器,然后在其上运行验证器来判断它是否合理。
对聊天机器人来说,这是一种特别强大的方法,允许我们组合多个自然语言生成器的最佳结果。为了改善体验,可以生成大量回复并选择具备最佳拼写、语法和情感的回复,例如:
us=r'((([01]?\d)[-/]([0123]?\d))([-/]([0123]\d)\d\d)?)'
mdy=re.findall(us,"Santa came 12/25/2017.An elf appeared 12/12")
print(mdy)
![]()
通过把月、日和年转换成整数并使用有意义的名称标注这些数字信息,我们可以使用列表解析式为提取的数据提供结构化表示,如下所示:
dates=[{'mdy':x[0],'my':x[1],'m':int(x[2]),'d':int(x[3]),'y':int(x[4].lstrip('/') or 0),'c':int(x[5] or 0)} for x in mdy]
print(dates)

即使对于这些简单的日期,也不可能设计一个可以处理“12/12”这个日期中存在的奇异的正则表达式。日期表示中往往存在含糊不清的情况,只有人可以通过使用圣诞节相关的知识或作者的意图来猜测。例如,“12/12”可能表示:
- 2017年12月12日——基于指代消解估计得到的年份的月/日格式;
- 2018年12月12日——出版时当年年份的月/日格式;
- 2012年12月——2012年的月/年格式。
因为月/日在美国日期和正则表达式中都出现在年份的前面,所以“12/12”被认为是某个未知年份的12月12日。我们可以使用在内存的结构化数据的上下文中最近读取到的年份来填充任何缺失的数字字段:
for i,d in enumerate(dates):for k,v in d.items():if not v:d[k]=dates[max(i-1,0)][k]
print(dates)
from datetime import date
datetimes=[date(d['y'],d['m'],d['d']) for d in dates]
print(datetimes)

上面是从自然语言文本中提取日期信息的基本但相当鲁棒的方法。如果将该方法用作生产系统的日期提取器,还需要做的主要工作是添加一些适用于我们应用程序的异常捕获和上下文管理。
我们可以通过一些硬编码逻辑来处理极端情况以及月甚至日的自然语言名称。但是再复杂的逻辑也无法处理“12/11”中存在的日期歧义,它可能是:
- 某个看到或听到过年份的12月11日;
- 11月12日;
- 2011年12月;
- 2012年11月。
即使是人脑也无法解决一些自然语言的歧义问题。但是,需要确保日期提取器可以通过在正则表达式中颠倒月和日来处理欧洲日/月顺序的日期:
eu=r'((([0123]?\d)[-/]([01]?\d))([-/]([0123]\d)?\d\d)?)'
dmy=re.findall(eu,"Alan Mathison Turing OBE FRS(23/6/1912-7/6/1954) as an English computer scientist.")
print(dmy)
dmy=re.findall(eu,"Alan Mathison Turing OBE FRS(23/6/12-7/6/54) as an English computer scientist.")
print(dmy)

正则表达式能够正确的从文字中提取日期。但上面的例子中已经把“June”转换成了数字“6”。我们希望聊天机器人能够从没有经过人工预处理的文章中提取日期,从而可以研读信息并学习导入日期。如果希望正则表达式能够处理更自然的像是百科文档中出现的日期信息,就需要再日期提取正则表达式中添加诸如“June”(及其所有缩写)之类的单词。
我们不需要任何特殊的符号来表示词组(按顺序组合在一起的字符),完全按照这些词组在输入中的拼写顺序,可以直接把它们写到正则表达式中,包括大小写。我们所要做的就是在正则表达式中使用一个OR符号(|)隔开这些词组。而且需要确保这个正则表达式既可以处理美国月/日的日期格式,也可以处理欧洲的日期格式。将这两个等同的日期“拼写”添加到正则表达式中,并在它们之间使用一个OR(|)作为正则表达式中决策树的分支。
我们使用一些命名分组来帮助我们识别像1984年的“84”和2008年的“08”这样的年份。尝试更准确地表示想要匹配的4位数年份,从过去的0年到未来的2999年:
yr_19xx=(r'\b(?P<yr_19xx>'+'|'.join('{}'.format(i) for i in range(30,100))+r'?\b'
)
yr_20xx=(r'\b(?P<yr_20xx>' +'|'.join('{:02d}'.format(i) for i in range(10)) + '|' +'|'.join('{}'.format(i) for i in range(10,30))+r')\b'
)
yr_cent=r'\b(?P<yr_cent>'+'|'.join('{}'.format(i) for i in range(1,40))+r')'
yr_ccxx=r'(?P<yr_ccxx>'+'|'.join('{:02d}'.format(i) for i in range(0,100))+r')\b'
yr_xxxx=r'\b(?P<yr_xxxx>'+yr_cent+')('+yr_ccxx+r'))\b'
yr=(r'\b(?P<yr>'+yr_19xx+'|'+yr_20xx+'|'+yr_xxxx+r')\b'
)
groups=list(re.finditer(yr,"0,2000,01,'08,99,1984,2030/1970 85 47 `66"))
full_years=[g['yr'] for g in groups]
print(full_years)
![]()
仅仅是使用正则表达式中一些简单的年份规则,还没有用到Python,工作量就很大了。但是软件包可用于识别常见的日期格式,它们更精确、更通用。所以不需要自己编写复杂的正则表达式。上面的示例仅是提供了一种可以遵循的模式,以防将来需要使用正则表达式提取特定类型的数字。在货币数值和IP地址提取的例子中,带有命名分组的更复杂的正则表达式可能会派上用场。
在百科文章的日期中,在提取日期时添加月份名称对应的模式“June”或者“Jun”,来完成正则表达式以提取日期:
mon_words='January February March April May June July August September October November December'
mon=(r'\b('+'|'.join('{}|{}|{}|{}|{:02d}'.format(m,m[:4],m[:3],i+1,i+1) for i,m in enumerate(mon_words.split()))+r')\b')
print(re.findall(mon,"January has 31 days,February the 2nd month of 12, has 28,except in a Leap Year."))
![]()
将这些正则表达式组合成一个可以处理所有日期格式的大型表达式的难点在于我们不能为分组(正则表达式中的括号内的部分)复用相同的名称。所以不能再不同格式对应的月份和年份的命名正则表达式之间使用OR。此外,表达式中需要包含日、月和年之间任意分隔符的模式。
下面是一个满足上述需求的例子:
day=r'|'.join('{:02d}|{}'.format(i,i) for i in range(1,32))
eu=(r'\b('+day+r')\b[-,/ ]{0,2}\b('+mon+r')\b[-,/ ]{0,2}\b('+yr.replace('<yr','<eu_yr')+r')\b')
us=(r'\b('+mon+r')\b[-,/ ]{0,2}\b('+day+r')\b[-,/ ]{0,2}\b('+yr.replace('<yr','<us_yr')+r')\b')
date_pattern=r'\b('+eu+'|'+us+r')\b'
print(list(re.finditer(date_pattern,'31 Oct, 1970 25/12/2017')))

最后,需要验证日趋的日期,看这个日期是否可以转换为有效的Python datetime对象:
import datetime
dates=[]
for g in groups:#print(g.groupdict())month_num=(g['us_mon'] or g['eu_mon']).strip()try:month_num=int(month_num)except ValueError:month_num=[w[:len(month_num)]for w in month_num].index(month_num)+1date=datetime.date(int(g['us_yr'] or g['eu_yr']),month_num,int(g['us_day'] or g['eu_day']))dates.append(date)
print(dates)
日期提取器看起来运行正常,至少在这几个简单的、无歧义的日期上是这样的。
如果只要想一个最先进的日期提取器,基于统计(机器学习)的方法能够更快的满足需求。
相关文章:
【Python机器学习】NLP信息提取——值得提取的信息
目录 提取GPS信息 提取日期 如下一些关键的定量信息值得“手写”正则表达式: GPS位置;日期;价格;数字。 和上述可以通过正则表达式轻松捕获的信息相比,其他一些重要的自然语言信息需要更复杂的模式: 问…...
代理IP批理检测工具,支持socks5,socks4,http和https代理批量检测是否可用
代理IP批理检测工具,支持socks5,socks4,http和https代理批量检测是否可用 工具使用c编写: 支持ipv4及ipv6代理服务器。 支持http https socks4及socks5代理的批量检测。 支持所有windows版本运行! 导入方式支持手工选择文件及拖放文件。 导入格式支持三…...
AI视觉算法盒是什么?如何智能化升级网络摄像机,守护全方位安全
在智能化浪潮席卷全球的今天,以其创新技术引领行业变革,推出的集高效、智能、灵活于一体的AI视觉算法盒。这款革命性的产品,旨在通过智能化升级传统网络摄像机,为各行各业提供前所未有的安全监控与智能分析能力,让安全…...
【Vue】VueRouter路由
系列文章目录 第七章 VueRouter路由 文章目录 系列文章目录第一节:VueRouter基础一、安装:二、基本使用:1. 创建路由代码:Single Page Application:SPA2. 使用路由3. 展示路由: 二、嵌套路由三、路由传参1…...
idea多模块启动
文章目录 idea多模块启动2018版本的idea2019版本的idea idea多模块启动 2018版本的idea 1.首先看一下view> Tool Windows下有没有Run Dashboard 如果有,点击一下底部的窗口就会出现 如果不存在,执行下一步 2.查看自己项目的工作空间位置 点击 File&…...
23:SPI二:W25Q64存储器模块的使用
W25Q64存储器模块的使用 1、W25Q64的简介2、模块内部结构2.1:引脚结构2.2:内部存储结构2.3:此模块的注意事项 3、程序模拟SPI读写W25Q644、片上外设SPI读写W25Q64 1、W25Q64的简介 其中最主要的特点就是掉电不丢失。 由上图所示:…...
论文解读《COMMA: Co-articulated Multi-Modal Learning》
系列文章目录 文章目录 系列文章目录论文细节理解1. 研究背景2. 论文贡献3. 方法框架4. 研究思路5. 实验6. 限制结论 论文细节理解 这段话中,the vision branch is uni-directionally influenced by the text branch only 什么意思?具体举例一下 以下是…...
10款电脑加密软件超好用推荐|2024年常用电脑加密软件排行榜
随着数据隐私和信息安全意识的增强,电脑加密软件已成为日常工作和个人生活中不可或缺的工具之一。无论是保护公司机密文件,还是保障个人数据的安全,合适的加密软件都能提供强有力的保护。本文将推荐2024年超好用的10款电脑加密软件࿰…...
用户态缓存:环形缓冲区(Ring Buffer)
目录 环形缓冲区(Ring Buffer)简介 为什么选择环形缓冲区? 代码解析 1. 头文件与类型定义 1.1 头文件保护符 1.2 包含必要的标准库 1.3 类型定义 2. 环形缓冲区结构体 2.1 结构体成员解释 3. 辅助宏与内联函数 3.1 min 宏 3.2 is…...
Harmony应用 ArkTs AES 加密方法之GCM对称加密
加解密介绍 在数据存储或传输场景中,可以使用加解密操作用于保证数据的机密性,防止敏感数据泄露。 使用加解密操作中,典型的场景有: 使用对称密钥的加解密操作。 使用非对称密钥的加解密操作。 使用RSA(PKCS1_OAEP…...
热成像在战场上的具体作用!!!
1. 探测和跟踪敌人 原理:人体和许多类型的军事设备都会发热,热成像技术通过探测这些红外辐射,能够在远距离探测和跟踪敌人的位置。 应用场景:这一功能在夜间或有覆盖物(如草丛、树林)的情况下尤为有效&am…...
2024年09月20日《每日一练》
1、 根据我国“十三五”规划纲要,()不属于新一代信息技术产业创新发展的重点。 A 人工智能 B 移动智能终端 C 先进传感器 D 4G D P13 此题考察的是新一代信息技术,必须掌握,高频考点 国在“十三五“规划纲要中&#x…...
使用 SSCB 保护现代高压直流系统的优势
在各种应用中,系统效率和功率密度不断提高,这导致了更高的直流系统电压。然而,传统的电路保护解决方案不足以在保持高可靠性和安全性的同时有效保护这些高压配电系统。 固态断路器 (SSCB) 和电熔断器具有众多优点&…...
Linux基础命令——文件系统的日常管理
目录 一.如何查看当前工作目录?(你现在所处的位置路径) 二.命令touch的用途是什么?还有别的方法新建文件吗? (1)创建空文件 (2)如果已经存在这个文件,就会更新创建时间。 (3…...
uniapp使用高德地图设置marker标记点,后续根据接口数据改变某个marker标记点,动态更新
最近写的一个功能属实把我难倒了,刚开始我请求一次数据获取所有标记点,然后设置到地图上,然后后面根据socket传来的数据对这些标记点实时更新,改变标记点的图片或者文字, 1:第一个想法是直接全量替换,事实证明这样不行,会很卡顿,有明显闪烁感,如果标记点比较少,就十几个可以用…...
坦白了,因为这个我直接爱上了 FreeBuds 6i
上个月,华为发布的 FreeBuds 6i 联名了泡泡玛特真的超级惊艳,不少宝子被这款耳机的颜值所吸引,而它的实力更是不容小觑的。FreeBuds 6i 是一款性能强大的降噪耳机,它一直在强调平均降噪深度,但是应该很多人对这个概念很…...
006.MySQL_查询数据
课 程 推 荐我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈虚 拟 环 境 搭 建 :…...
【C#生态园】从图像到视觉:Emgu.CV、AForge.NET、OpenCvSharp 全面解析
C#图像处理库大比拼:功能对比、安装配置、API概览 前言 图像处理和计算机视觉在现代软件开发中扮演着重要角色,而C#作为一种流行的编程语言,拥有许多优秀的图像处理库。本文将介绍几个用于C#的图像处理和计算机视觉库,包括Image…...
1、无线通信的发展概况
无线通信是指双方至少一方使用无线方式进行信息的交换与传输,包括移动体(行人、车辆、船舶以及飞机)和移动体之间的通信,也包括移动体与固定点(固定点的移动电台或有线通信)之间的通信。 随着无线通信的范围…...
虚拟机安装xubuntu
新建一个新的虚拟机,选择自定义安装 默认下一步 选择稍后安装操作系统 选择所要创建的系统及版本 填写虚拟机的名称及创建的虚拟机保存的位置 选择处理器和内核的数量 处理器数量指的是:虚拟的CPU数量。 每个处理器的内核数量指的是:虚拟CPU…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...
