核心知识点
参考代码:https://github.com/alanhou/pytorch-chatbot
聊天机器人综合介绍
什么是聊天机器人?
- Chatbot
- 微软小冰
- 主要分布于电商、新闻、财经、娱乐、医疗、旅游、餐饮行业
聊天机器人起源发展
- 诞生于20世纪80年代(阿尔贝特,Basic 编写)
- 用于模拟人类对话或聊天的程序
- Eliza(1966年) 和 Parry(1972年) 是早期非常著名的聊天机器人
- 1996年 A.L.I.C.E.弱 AI NLP 领域
- 对话系统 实时通讯工具 教育系统
- 图灵机器人
- 是否智能
- 学习能力如何
- 自升级的能力
聊天机器人的分类
- 按领域分类为固定领域和开放领域
- 固定领域:技术支持、天气查询、疾病诊治…
- 开放领域:娱乐助手
- 按模式分检索模式和生成模式
- 检索模式:预定义响应数据库,构建 FAQ;
- 生成模式:生成式模型从零开始生成新的响应,通常基于机器“翻译”技术:ENCODER, DECODER
构建最简单的聊天机器人
基于规则的简单聊天机器人 nltk 库
NLP 基础
人机交互,Natural Language Processing,是 AI 重要分支之一
主要范畴
- 文本朗读(Text to speech)
- 语音合成(Speech synthesis)
- 语音识别(Speech recognition)
- 中文自动分词(Chinese word segmentation)
- 词性标注(Part-of-speech tagging)
- 句法分析(Parsing)
- 自然语言生成(Natural language generation)
- 文本分类(Text categorization)
- 信息检索(Information retrieval)
- 信息抽取(Information extraction)
- 文字校对(Text-proofing)
- 问答系统(Question answering)
- 机器翻译(Machine translation)
- 自动摘要(Automatic summarization)
- 文字蕴涵(Textual entailment)
发展历程:
1950年开始
1954年 乔治城自动翻译超过60句俄文成为英文
1960年代 SHRDLU
1980年代引入机器学习
研究难点:
单词的边界界定
词义的消歧
不规范的输入
句法的模糊性
语言行为与计划
NLP 涉及知识
- 词处理:分词、词性标注、实体识别、词义消歧
- 语句处理:句法分析(Syntactic Analysis)、语义分析(Semantic Analysis)、机器翻译、语音合成
- 篇章处理:自动文摘
- 统计语言模型:
- N-Gram 统计模型
- 马尔科夫模型
- 隐马尔科夫模型
NTTK库
- Natural Language Toolkit
- 诞生于20世纪80年代http://www.nltk.org/
- NLTK能干什么
- Python 上著名的自然语言处理库
- 自带语料库、词性分类库
1from nltk.corpus import (gutenberg, genesis, inaugural, nps_chat, webtext, treebank, wordnet) - 自带分类、分词等功能
- 强大的社区支持
- 还有 N 多的简单版 wrapper
语料及词性标注
语料,即语言材料。
词性标注:给每个词或者词语打词类标签,如形容词、动词、名称等。
中文词性编码:
词性编码 | 词性名称 | 注 解 |
---|---|---|
Ag | 形语素 | 形容词性语素。形容词代码为 a,语素代码g前面置以A。 |
a | 形容词 | 取英语形容词 adjective的第1个字母。 |
ad | 副形词 | 直接作状语的形容词。形容词代码 a和副词代码d并在一起。 |
an | 名形词 | 具有名词功能的形容词。形容词代码 a和名词代码n并在一起。 |
b | 区别词 | 取汉字“别”的声母。 |
c | 连词 | 取英语连词 conjunction的第1个字母。 |
dg | 副语素 | 副词性语素。副词代码为 d,语素代码g前面置以D。 |
d | 副词 | 取 adverb的第2个字母,因其第1个字母已用于形容词。 |
e | 叹词 | 取英语叹词 exclamation的第1个字母。 |
f | 方位词 | 取汉字“方” |
g | 语素 | 绝大多数语素都能作为合成词的“词根”,取汉字“根”的声母。 |
h | 前接成分 | 取英语 head的第1个字母。 |
i | 成语 | 取英语成语 idiom的第1个字母。 |
j | 简称略语 | 取汉字“简”的声母。 |
k | 后接成分 | |
l | 习用语 | 习用语尚未成为成语,有点“临时性”,取“临”的声母。 |
m | 数词 | 取英语 numeral的第3个字母,n,u已有他用。 |
Ng | 名语素 | 名词性语素。名词代码为 n,语素代码g前面置以N。 |
n | 名词 | 取英语名词 noun的第1个字母。 |
nr | 人名 | 名词代码 n和“人(ren)”的声母并在一起。 |
ns | 地名 | 名词代码 n和处所词代码s并在一起。 |
nt | 机构团体 | “团”的声母为 t,名词代码n和t并在一起。 |
nz | 其他专名 | “专”的声母的第 1个字母为z,名词代码n和z并在一起。 |
o | 拟声词 | 取英语拟声词 onomatopoeia的第1个字母。 |
p | 介词 | 取英语介词 prepositional的第1个字母。 |
q | 量词 | 取英语 quantity的第1个字母。 |
r | 代词 | 取英语代词 pronoun的第2个字母,因p已用于介词。 |
s | 处所词 | 取英语 space的第1个字母。 |
tg | 时语素 | 时间词性语素。时间词代码为 t,在语素的代码g前面置以T。 |
t | 时间词 | 取英语 time的第1个字母。 |
u | 助词 | 取英语助词 auxiliary |
vg | 动语素 | 动词性语素。动词代码为 v。在语素的代码g前面置以V。 |
v | 动词 | 取英语动词 verb的第一个字母。 |
vd | 副动词 | 直接作状语的动词。动词和副词的代码并在一起。 |
vn | 名动词 | 指具有名词功能的动词。动词和名词的代码并在一起。 |
w | 标点符号 | |
x | 非语素字 | 非语素字只是一个符号,字母 x通常用于代表未知数、符号。 |
y | 语气词 | 取汉字“语”的声母。 |
z | 状态词 | 取汉字“状”的声母的前一个字母。 |
un | 未知词 | 不可识别词及用户自定义词组。取英文Unkonwn首两个字母。(非北大标准,CSW分词中定义) |
词性标注的分类
- 基于规则的词性标注
- 基于隐马尔科夫模型 HMM 的词性标注
- 基于转移的词性标注
- 基于转移与隐马尔科夫模型相结合的词性标注
词性标注的方法: NLTK、Jieba
分词
把句子分成词
分词难点:
- 分词标准:花草、花/草
- 切分歧义:分词细粒度造成、存在歧义的句子、交集型歧义
- 新词
分词的算法:
- 基于词典的分词算法
- 正向最大匹配法
- 逆向最大匹配法
- 双向匹配分词
- 全切分路径选择
- 基于统计的分词算法
- HMM,隐马尔科夫模型
- CRF,条件随机场
- 深度学习
Jieba 分词:https://github.com/fxsjy/jieba
注:jieba 从0.4版本开始支持paddle 模式,但这里有个坑,正常安装如果使用Python 3.8及以上版本会报
Could not find a version that satisfies the requirement paddlepaddle-tiny
。很多人会说只支持 Python 3.7,事实上Python 3.8也可通过直接安装 paddlepaddle来使用:
1 pip install paddlepaddle==1.8.5
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import jieba seg_list = jieba.cut("我来到北京清华大学", cut_all=True) print("Full Mode: " + "/ ".join(seg_list)) # 全模式 seg_list = jieba.cut("我来到北京清华大学", cut_all=False) print("Default Mode: " + "/ ".join(seg_list)) # 精确模式 seg_list = jieba.cut("他来到了网易杭研大厦") # 默认为精确模式 print(",".join(seg_list)) seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造") # 搜索引擎模式 print(",".join(seg_list)) |
TF-IDF
TF: Term frequency,衡量一个 term 在文档中出现得多频繁
$$TF(t)={(t出现在文档中的次数) \over (文档中的term总数)} $$
IDF: Inverse document frequency,衡量一个 term 有多重要
$$IDF(t) = log_e{(文档总数/含有t的文档总数)}$$
TF-IDF = TF * IDF
TF-IDF的作用:提取文本向量的特征
1 2 3 4 5 |
sudo pip install -U nltk sudo pip install -U numpy >>> import nltk >>> nltk.download() |
https://scikit-learn.org/stable/
NLP 文本处理
- 分词
- 提取文本向量
- 语义理解
文本处理的方法
- TF-IDF
- Jieba
- OneHot(独热):将类别变量转换为数字型变量 稀疏
- Word2Vec
- 2013年 Mikolov 提出
- 用神经网络把词转成向量的模型(CBOW,Skip-Gram)
- CBOW-Continuous Bag of Words Model 连续词袋
- 没有隐层
- 结合双向上下文 上下文词序无关
- 输入低维稠密 映射层求和
- 给定上下文来预测input word
- Skip-Gram
- 没有隐层
- 映射层可以省略
- 给定 input word 来预测上下文
- 分层 Softmax
$$p(w|w_I) = \prod_{j=1}^{L(w)-1}{\sigma([n(w,j+1) = ch(n(w,j))]\cdot v_{n(w,j)}^\prime{\top v_{w_I}})}$$ - 负采样
$$len(w) = {counter(w) \over \sum\limits_{u\in D}{counter(u)}}$$ - 不足
- 使用了唯一的词向量 对于多义词没有很好的效果
- context 很小,没有使用全局的 cooccur,对 cooccur 的利用少
- 改进GloVe
$$J = \sum_{i,j=1}^V{f(x_ji)(w_i^T\tilde{w}_j + b_i + \tilde{b}_j – logX_{ij})^2}$$
- Stopwords: https://www.ranks.nl/stopwords
示例教程:https://radimrehurek.com/gensim/auto_examples/tutorials/run_word2vec.html#sphx-glr-auto-examples-tutorials-run-word2vec-py
检索类机器人
- 需要数据库比较大
- 回答比较自然
提问->检索->答案抽取
关键技术-检索匹配
- 基于检索的技术
- 基于模式匹配的技术
- 基于自然语言理解的技术
- 基于统计翻译模型的技术
关键技术-计算相似度
- 余弦相似度(Cosine Similarity)
$$similarity = \cos(\theta) = \frac{A\cdot B}{||A||||B||} = \frac{\sum_{i=1}^n A_i\times B_i}{\sqrt{\sum_{i=1}^n(A_i)^2}\times \sqrt{\sum_{i=1}^n(B_i)^2}}$$ - 皮尔森相关系数(Pearson Correlation Coefficient)
- 信息检索-词频-逆文档频率(TF-IDF)
关键技术-分类
- 贝叶斯分类
- KNN
- SVM
- CNN
- LSTM
贝叶斯分类
什么是分类:分类就是构造一个分类器,把用户提供的数据项映射到给定类别集中的某一个类
先验概率与后验概率
- 先验概率:根据历史资料或主观判断,未经实验证实所确定的概率
- 后验概率:通过 Bayes 定理,用先验概率计算出来
$$p(A|B)={p(B|A)p(A)\over p(B)}$$
其中 p(A)是先验概率,p(B|A)为条件概率也称为似然
朴素贝叶斯:加上条件独立假设的贝叶斯方法就是朴素贝叶斯方法(Natve Bayes)
多项式模型、伯努利模型、混合模型
朴素贝叶斯的实际应用:垃圾邮件分析、文本情感分析、拼写纠错
朴素贝叶斯工程中的技巧:取对数、转换为权重、选择 topk 的关键词、分割样本、位置权重
Chatterbot
Chatterbot 是一个基于机器学习的聊天机器人引擎,构建在 Python 上,主要特点是可以自己从已有的对话中进行学习。
1 |
pip install chatterbot |
https://chatterbot.readthedocs.io/en/stable/
训练类 通过列表数据进行训练
1 |
chatterbot.trainers.ListTrainer(storage, **kwargs) |
训练类 使用语料库数据进行训练
1 |
chatterbot.trainers.ChatterBotCorpusTrainer(storage, **kwargs) |
训练类 指定语料范围
1 2 3 4 |
chatterbot.train( "chatterbot.corpus.english.greetings", "chatterbot.corpus.english.conversations" ) |
训练类 使用 Twitter API进行训练
1 |
chatterbot.trainers.TwitterTrainer(storage, **kwargs) |
生成式机器人
生成类聊天机器人
- ENCODER
- DECODER
RNN LSTM语言模型
语言模型:
Language Model,最常用的 N-Gram
语言模型简单来说就是一串词序列的概率分布
语言模型的计算:
$$P(w_1,w_2,…w_T) = \prod_{t=1}^TP(w_t|w_1,…,w_{t-1})$$
语言模型的应用
- 语音识别
- 机器翻译
- 句法分析
- 短语识别
- 词性标注
- 手写体识别
- 拼写纠错
语言模型的方法
- 基于统计学习的
- 基于机器学习和深度学习的
RNN 存在的问题:梯度消失、梯度爆炸
RNN的结构:one to one, one to many, many to one, many to many
LSTM缓解梯度消失、缓解梯度爆炸,核心思想-细胞状态流动
$$f_t = \sigma(W_f\cdot[h_{t-1},x_t] + b_f)$$
$$i_t = \sigma(W_i\cdot[h_{t-1},x_t] + b_i)$$
$$\tilde{C}_t = \sigma(W_C\cdot[h_{t-1},x_t] + b_C)$$
$$C_t = f_t*C_{t-1}+i_t*\tilde{C}_t$$
$$o_t = \sigma(W_o[h_{t-1},x_t] + b_o)$$
$$h_t = o_t*\tanh(C_t)$$
Seq2Seq
最早应用于机器翻译
逐字翻译->基于统计学的机器翻译->循环网络和编码->解码和翻译
应用场景:
- 机器翻译
- 图像描述(Image captioning)
- 代码实例
- 聊天机器人
训练过程
- Softmax
$$S_i = \frac{e^{vi}}{\sum_i^Ce^{vi}}$$ - $$h_{(t)} = f(h_{(t-1)},y_{t-1},c)$$
$$P(y_t|y_{t-1},y_{t-2},…,y_1,c) = g(h_{(t)},y_{t-1},c)$$
$$\max\limits_\theta{1\over N}\sum_{n=1}^Nlogp_\theta(y_n | x_n)$$
不足:长度限制、压缩损失信息
Attention
关注序列中的一些内容
应用:机器翻译、语音识别、图像描述
分类
- Soft Attention(论文:Neural machine translation by jointly learning to align and translate)
- Hard Attention(论文:Show ,Attend and Tell: Neural Image Caption Generation with Visual Attention)
- Global Attention
- Local Attention(论文:Effective Approaches to Attention-based Neural Machine Translation)
- 静态 Attention(论文:Teaching Machines to Read and Comprehend Supervised Sequence Labelling with Recurrent Neural Networks)
- Self Attention(也叫做 intra-attention)
- Key-value Attention
- Multi-head Attention
Pytorch 基础
Pytorch入门
使用 Lua的torch的基础上
特点:
- 动态生成网络
- 源码简单易懂
- 扩展方便
安装使用
https://github.com/pytorch/pytorch
原理机制
- Tensor: Strided Representation
- AutoGrad(自动求导)
- 并行
数据载入
Dataset(torch.utils.data.Dataset)
DataLoader(torch.utils.data.DataLoader)
Dataloaderlter(torch.utils.data.dataloader.Dataloaderlter)
https://github.com/pytorch/vision/tree/master/torchvision/datasets
训练模型
- 定义网络
- 定义数据
- 定义损失函数和优化器
- 计算重要指标
- 开始训练
- 训练网络
验证测试
验证:模型置于验证模式(model.eval()),验证完成后还需要将其置回为训练模式(model.train())
测试:测试时需要自己加载模型和数据
聊天机器人发展方向
基于 Pytorch 聊天机器人代码实战