【Python机器学习】NLP——一个简陋的聊天机器人

news2024/11/30 2:51:18

目录

正则表达式

一个简答的聊天机器人

另一种方法


正则表达式就是一种FSM,同时它也给出了一种可能的NLP方法,即基于模式的方法。

正则表达式

现实生活中,密码锁其实就是一台简单的语言处理机。密码锁不能阅读和理解课本,但是它可以理解“锁的语言”。当试图“告诉”它一个“密码”组合时,它可以理解。挂锁密码是与锁语言的“语法”(模式)匹配的任何符号序列。更重要的是,挂锁可以判断“锁语句”是否匹配一条特别有意义的语句,该语句只有一条正确的“回复”:松开锁扣。

正则表达式正是如此,它特别简单,但又不那么简单,我们在聊天机器人中还不能使用它,但是希望它能识别关键短语或指令来解锁特定的动作或行为。这种语言就像锁语言一样,是一种形式语言,这是因为它对如何编写和解释一条可接受的语句有着严格的规定。

形式语言是自然语言的子集。很多自然语言中的语句都可以用形式语言的语法(如正则表达式)来匹配或生成。

正则表达式使用了一类特殊的称为正则语法的形式语言语法。正则语法的行为可预测也可以证明,而且足够灵活,可以支持市面上一些最复杂的对话引擎和聊天机器人。Amazon Alexa和Google Now都是依赖正则语法的主要基于模式的对话引擎。深奥、复杂的正则语法规则通常可以用一行称为正则表达式的代码来表示。

Python中有一些成功的聊天机器人框架,比如will,它们完全依赖这种语言来产生一些有用和有趣的行为。

正则表达式虽然主要用于搜索和序列匹配,但任何可以在文本中查找匹配的方法都非常适合用于对话,一些聊天机器人(比如will),对于知道如何恢复的语句,会使用搜索方式在用户语句中查找字符序列。然后,这些识别出的序列会触发一段事先设置好的回复,该回复满足这个特定正则表达式的匹配。同样的正则表达式也可以用来从语句中提取有用的信息。聊天机器人可以把这些信息添加到知识库中,而该知识库收集了有关用户或用户所描述世界的知识。

处理这种语言的机器可以被看作是一个形式化的数学对象,称为有限状态机FSM)或确定性有限自动机DFA)。下图是FSM在“嵌套”的自动机世界中所处的位置:

下面是形式语言的形式数学解释:

(from 凯尔-戈尔曼)

1、大多数编程语言都来自上下文无关语言这一类;

2、上下文无关语言使用上下文无关语法进行高效的解析;

3、正则语言也可以有效地进行解析,并广泛用于字符串匹配的计算中;

4、字符串匹配应用程序基本不需要上下文无关的表达能力;

5、有很多类型的形式语言,下面是其中的一些(按复杂性从高到低):

        递归可枚举的

        上下文有关的

        上下文无关的

        正则

而对自然语言是想下面的这样的:

1、不是正则的;

2、不是上下文无关的;

3、用任何形式语法都无法定义。

一个简答的聊天机器人

下面粗略的构建一个聊天机器人,需要手工编写正则表达式,以匹配人们可能的说话方式。基于模式匹配的聊天机器人是严格受控的聊天机器人的一个例子。在基于现代机器学习的聊天机器人技术发展之前,基于模式匹配的聊天机器人十分普遍。

现在我们来构建一个FSM,也就是一个可以“说”正则语言的正则表达式,我们可以通过编程来理解诸如“01-02-03”这样的正则语言语句。更高的一点是,我们希望它能理解诸如“open sesame”或者“hello lily”之类的问候语。亲社会聊天机器人的一个重要特点是能够回复别人的问候。

在机器通信协议中,我们定义了一个简单的握手协议,每条消息在两台机器之间来回传递之后,都有一个ACK(确认)信号。但是,我们这里的机器将会和那些说“good morning,lily.”之类的用户进行互动。我们不希望它想对话或web浏览会话开始时同步调制解调器或http链接而发出一串ACK消息,相反,我们在对话握手开始时使用正则表达式来识别几种不同的问候语:

import re
r='(hi|hello|hey)[ ]*([a-z]*)'
print(re.match(r,'hello Tom',flags=re.IGNORECASE))
print(re.match(r,'hi ho,hi hi,it`s off to work ...',flags=re.IGNORECASE))
print(re.match(r,'hey, what`s up',flags=re.IGNORECASE))

在正则表达式中,我们可以使用方括号指定某个字符类,还可以使用短横线(-)来表示字符的范围而不需要逐个输入。因此,正则表达式"[a-z]"将匹配任何单个小写字母,即"a"到"z"。字符类后面的星号(*)表示可以匹配任意数量的属于该字符类的连续字符。

下面我们把正则表达式写得更细致,以匹配更多的问候语:

r=r"[^a-z]*([y]o|[h']?ello|ok|hey|(good[ ])?(morn[gin']{0,3}|afternoon|even[gin']{0,3}))[\s,;:]{1,3}([a-z]{1,20})"
re_greeting=re.compile(r,flags=re.IGNORECASE)
print(re_greeting.match('Hello Tom'))
print(re_greeting.match('Hello Tom').groups())
print(re_greeting.match('Good morning Tom'))
print(re_greeting.match('Good evening Tom jerry').groups())

上述代码的第一行(正则表达式)包含了很多逻辑,可以匹配很多问候语。但是如果有人打招呼的语句是“Good manning...”就无法匹配,在机器学习和医学诊断中,这被称为假阴性分类错误。它也会与人类不太可能说的话相匹配,即出现了假阳性的错误。假阳性错误和假阴性错误的同时存在意味着我们的正则表达式既过于宽松又过于严格。我们必须做更多的努力来改进匹配的短语,使机器人表现得更像人类。

下面,通过添加一个输出生成器最终得到一个只用一种技巧(正则表达式)的聊天机器人:

my_names=set(['tom','jerry','rose','bot','tom','robot','chatbot'])
curt_names=set(['hal','you','u'])
greeter_name=''
match=re_greeting.match(input())
if match:
    at_name=match.groups()[-1]
    if at_name in curt_names:
        print('Good one.')
    elif at_name.lower() in my_names:
        print('Hi {},How are you'.format(greeter_name))

运行这个脚本,用“Hello Tom”这样的短语和机器人聊天,它会回答“Hi ,How are you”。如果用一个不礼貌的名字来称呼机器人,它就会不回答。

受计算资源所限,早期的NLP研究人员不得不使用人类大脑的计算能力来设计和手动调整复杂的逻辑规则从自然语言字符串中提取信息。这成为基于模式的NLP方法。这些模式就像正则表达式那样,可以不仅仅是字符序列模式。NLP还经常涉及词序列、词性或者其他高级的模式。核心的NLP构建模块(如词干还原工具和分词器)以及复杂的端到端NLP对话引擎(聊天机器人)都是通过这种方式,即基于正则表达式和模式匹配来构建的。基于模式匹配NLP方法的艺术技巧在于,使用优雅的模式来获取想要的内容,而不需要太多的正则表达式代码行。

另一种方法

如果我们有一个巨大的数据库,该数据库由数千甚至上百万人类的对话数据构成,这些数据包括用户所说的语句和回复。那我们构建聊天机器人的一种方法是,在数据库中搜索与用户对聊天机器人刚刚“说过”的话完全相同的字符。

但是,如果有书写错误或者变异,那么就会出问题。位和字符序列都是离散的,它们要么匹配,要么不匹配,然而我们希望机器人能够度量字符序列之间的意义差异

当使用字符序列匹配来度量自然语言短语之间的距离时,具有相似含义的短语(比如good、okey)通常会有不同的字符序列,当我们通过清点逐个字符的匹配总数来计算距离时,它们反而会得到较大的距离。但对于具有完全不同含义的序列(比如bad和bar),反而会得到过于接近的结果。

有一些方法有时可以为结果添加足够的“模糊性”,以放置聊天机器人犯微小的拼写错误。但两个字符串不相似时,这些度量方法无法捕捉它们之间关系的本质。它们有时也会把拼写上存在小差异的词紧密联系在一起,而这些小差异可能并不是真正的拼写错误,比如bad和bar。

为数值序列和向量设计的距离度量方法对一些NLP应用程序来说非常有用,如拼写校正器和专有名词识别程序。所以,当这些距离度量方法有意义时,我们可以使用这些方法。但是,针对那些我们对自然语言的含义比对拼写更感兴趣的NLP应用程序来说,有更好的方法。对应NLP应用程序,我们使用自然语言词和文本的向量表示以及这些向量的一些距离度量方法。

如果我们收到一个语句,我们可以计数、在字典中查找短序列,这部字典收集了所有我们以前见过的词,每次查找到序列就在字典中的该条目旁边做一个标记。我们还可以在其他记录本中做一个标记来表明词出现在哪条消息中,并为以前读过的所有文档创建百科全书式的索引,这个文档称为语料库,在索引中累出的词或者序列的集合称为词库

在努力统计收到消息中的词信息时,我们将词装箱并将他们存储为位向量,就像硬币或词条分拣器一样,后者将不同种类的词条定向到一边或另一边,形成一个级联决策,将它们堆积在底部的箱子中。我们的分拣机必须考虑数十万种可能的词条“面额”,每种面额对应说话人或作家可能使用的一个词。我们将每个短语、句子或文档输入词条分拣机,其底部都会出来一个向量,向量的每个槽中都有词条的计数值。其中的大多数计数值都为0,即使对于冗长的大型文档也是如此。把语言中的每个词的计数值呈现出来,而不把它们按照任何序列和顺序排列,这可能也有问题。当然,如果只是一个简短的句子,那么可能在大多数情况下我们都能把它们重新排列成其原始或期望的顺序和意义。

下图是NLP流水线中如何在分词器之后加入词条分拣机的过程,这里的词条分拣机草图中包含了一个停用词过滤器和一个罕见词分类器。字符串从顶部流入,词袋向量从底部词条栈中词条的高低堆叠中创建。

事实证明,机器可以很好的处理这种词袋,通过这种方式能够收集即便是中等长度的文档的大部分信息内容。在词条排序和计数之后,每篇稳定都可以表示为一个向量,即该文档中每个词或词条的整数序列。

这是一个语言的向量空间模型。这些栈和它们包含的每个词的数目被表示成一个长向量,该向量包含了许多0、1或2,这些数字散落在词所属栈出现的位置。这些词的所有组合方式构成的向量称为向量空间。该空间中向量之间的关系构成了我们的模型,这个模型视图预测这些词出现在各种不同的词序列集合(通常是句子或文档)中的组合。在Python中,我们可以将这些稀疏向量表示为字典。Python中的Counter是一种特殊的字典,它存储对象(包括字符串),并按我们想要的方式为对象计数:

from collections import Counter
print(Counter("Guten Morgen Tom".split()))
print(Counter("Good morning Tom!".split()))

可以想象,我们把能找到的所有文档、语句、句子甚至单个词,一个一个地输入到这台机器。我们会在每个语句处理完之后,对底部每个槽汇总的词条计数,我们称之为该语句的向量表示。机器以这种方式产生的所有可能的向量称为向量空间。这种表示文档、语句和词的模型称为向量空间模型。它允许我们使用线性代数来对这些向量进行运算,计算距离和自然语言语句的统计信息,这些信息有助于我们用更少的人工代码来解决更广泛的问题,同时也使得NLP流水线更加强大。

一个关于词袋向量序列的统计学问题是:在特定的词袋下最可能出现的词组合是什么?或者,如果用户输入一个词序列,那么数据库中最接近用户提供的词袋向量的词袋是什么?这其实是一个搜索查询。输入词是用户可能在搜索框中输入的词,最接近的词袋向量对应于要查找的目标文档或网页。高效回答上述两个问题的能力足以构建一个机器学习聊天机器人,随着我们给它提供的数据越来越多,它也会变得越来越好。

也许这些向量不像以前用过的任何向量,它们的维度非常高。从一个大型语料库汇总得到的3-gram词汇表可能有数百万个维度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2059766.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高性能web服务器nginx

目录 nginx简介 服务端 I/O 流程 Nginx 进程结构 Nginx启动流程 nginx的源码编译下载 nginx命令常见参数 nginx的配置文件详解 全局配置优化 nginx的平滑升级和回滚 nginx目录匹配优先级测试(因为只支持访问文件,所有不比对匹配目录优先级&…

STM32GPIO引脚八种工作模式

1. GPIO简述 GPIO(General-purpose input/output),通用型输入输出。简单理解就是我们可以控制输入输出的STM32引脚,统称为GPIO。 GPIO存在的意义就是用程序控制或读取它们的输出或输入。 2. 功能描述 每个GPI/O端口有两个32位配…

代码随想录算法训练营day50:图论01:图论理论基础;深度优先搜索理论基础;98. 所有可达路径;广度优先搜索理论基础

图论理论基础 分类:有向图,无向图,有无权重 度:【无向图】:有几条边连接该节点,该节点就有几度。 【有向图】:每个节点有出度和入度。出度:从该节点出发的边的个数。入度&#xf…

.net maui安卓开发中适用明文传输(一)

背景:最近在做一个pad上的项目,目的是执行每日点检功能(就是检查设备的各项保养指标);前期用HBuilder做了一个,但是现场的触摸屏选用的是TouchPie 安卓版本是6.0版本,上次开发的软件可以在安卓7.0上完美兼容,但由于触摸屏安卓版本太低不能兼容;询问厂商才知道这款触摸…

前端性能优化的指标

性能优化指标的出现,谷歌在2020年提出的Core Web Vitals 和 Web Vitals 了解谷歌浏览器自带的性能调试工具DCL、L、FP、FCP、LCP,图层(有layout布局就是回流,painting绘制就是重绘) 回流和重绘的理解 页面第一次打开一定回流和重绘,回流一定重绘,回流出现一般是位置改变…

BEV世界:通过统一的BEV潜在空间实现自动驾驶的多模态世界模型

BEVWorld: A Multimodal World Model for Autonomous Driving via Unified BEV Latent Space BEV世界:通过统一的BEV潜在空间实现自动驾驶的多模态世界模型 Abstract World models are receiving increasing attention in autonomous driving for their ability t…

【数据结构】PTA 求链表的倒数第m个元素 C语言

请设计时间和空间上都尽可能高效的算法,在不改变链表的前提下,求链式存储的线性表的倒数第m(>0)个元素。 函数接口定义: ElementType Find( List L, int m ); 其中List结构定义如下: typedef struct…

什么是机器人快换盘?

机器人快换盘,行业内也称作工具快换盘、换枪盘、快换工具盘、快速更换器、快换器、 快换夹具、治具快换等。是末端执行器快速更换装置(End-Of-Arm Tooling,简称EOAT),是工业自动化领域中用于机器人手臂上的一种重要设备…

短视频矩阵工具种类繁多,一招教你轻松做选择!

在当下竞争日益激烈的市场中,选择一个稳定且高效的矩阵营销系统对于企业和实体店来说至关重要,然而众多的工具往往让人难以抉择,今天笔者给大家四个关键筛选点,帮你快速筛选出最合适自己的矩阵营销工具: 1. 功能全面性…

探索AI工作流工具:提升编程效率的三大利器

问题:面对屎山代码,你是如何处理的? 今天我将为你推荐三个强大的AI工作流工具,它们将彻底改变你的编程体验,让你在工作中如鱼得水,事半功倍! 1. 代码解释器:解读复杂代码的利器 初…

[CISCN 2023 华北]ez_date

[CISCN 2023 华北]ez_date 点开之后是一串php代码&#xff1a; <?php error_reporting(0); highlight_file(__FILE__); class date{public $a;public $b;public $file;public function __wakeup(){if(is_array($this->a)||is_array($this->b)){die(no array);}if( (…

初级python代码编程学习----简单的图形化闹钟小程序

我们来创建一个简单的图形化闹钟程序通常需要使用图形用户界面&#xff08;GUI&#xff09;库。以下是使用Python的Tkinter库创建一个基本闹钟程序的步骤&#xff1a; 环境准备 确保已安装Python。安装Tkinter库&#xff08;Python 3.8及以上版本自带Tkinter&#xff0c;无需…

计算机毕业设计选题推荐-餐馆满意度分析-Python爬虫-K-means算法-nlp情感分析

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

亿玛科技:TiDB 6.1.5 升级到 7.5.1 经验分享

作者&#xff1a; foxchan 原文来源&#xff1a; https://tidb.net/blog/6e628afd 为什么要升级&#xff1f; 本次升级7.5的目的如下&#xff1a; 1、tidb有太多的分区表需要归档整理。7.5版本这个功能GA了。 2、之前集群tikv节点的region迁移过慢&#xff0c;影响tikv节…

http连接未释放导致生产故障

凌晨4点运维老大收到报警&#xff08;公司官网页面超时&#xff0c;上次故障因为运维修改nginx导致官网域名下某些接口不可用后&#xff0c;运维在2台nginx服务器上放了检测程序&#xff0c;检测官网页面&#xff09;&#xff0c;运维自己先看了看服务器相关配置&#xff0c;后…

linux 安装MAT(MemoryAnalyzerTool),并且分析java dump的方法

当我们的java进程出现异常的时候&#xff0c;我们第一件想做的事情是什么呢&#xff1f;应该就是要分析java的内存了。假如说&#xff0c;我们已经有了一个java内存的dump文件&#xff0c;有哪些的方法&#xff0c;可以对这个导出的dump文件进行分析呢&#xff1f; 比如&#…

Vue插值:双大括号标签、v-text、v-html、v-bind 指令

创建应用程序实例后&#xff0c;需要通过插值进行数据绑定。数据绑定是 Vue.js 最核心的一个特性。建立数据绑定后&#xff0c;数据和视图会相互关联&#xff0c;当数据发生变化时&#xff0c;视图会自动进行更新。这样就无须手动获取 DOM 的值&#xff0c;使代码更加简洁&…

【Python_PyQtGraph 学习笔记(十一)】基于ImageExporter更改导出图片的大小

基于ImageExporter更改导出图片的大小 前言正文1、ImageExporter 类介绍1.1 ImageExporter 类特点1.2 ImageExporter 类用法2、示例代码3、遇到的问题前言 在 基于PyQtGraph设置槽函数,实现保存图片到本地的功能 一文中我们成功地将 PyQtGraph 绘制的图形以图片形式保存到本地…

ChatGPT与Discord的完美结合——团队协作的得力助手

本文将教你如何集成Discord Bot&#xff0c;助力团队在工作中实现更高效的沟通与协作。通过充分发挥ChatGPT的潜力&#xff0c;进一步提升工作效率和团队协作能力。无需编写任何代码即可完成本文所述的操作&#xff0c;进行个性化定制只需对参数进行微调即可。 方案介绍 如果在…

【Python系列】中位数计算

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…