【一文讲解深度学习】语言自然语言处理(NLP)
- 博主介绍
- 自然语言处理概述
* - NLP 的定义
- NLP的主要任务
- - NLP的发展历程
- - NLP的困难与挑战
- - NLP相关知识构成
- 语料库
- - 传统NLP处理技术
* - 中文分词
- 正向最大匹配法
- 逆向最大匹配法
- 最大匹配法
- Jieba库分词
- 词性标注
- 命名实体识别(NER)
- 关键词提取
- TF-IDF 算法
- TextRank 算法
- 综合案例
- - 文本表示
- 词袋模型
- 💫点击直接资料领取💫
博主介绍
🌊 作者主页:苏州程序大白
🌊 作者简介:🏆CSDN人工智能域优质创作者🥇,苏州市凯捷智能科技有限公司创始之一,目前合作公司富士康、歌尔等几家新能源公司
💬如果文章对你有帮助,欢迎关注、点赞、收藏(一键三连)和C#、Halcon、python+opencv、VUE、各大公司面试等一些订阅专栏哦
💅 有任何问题欢迎私信,看到会及时回复
💅关注苏州程序大白,分享粉丝福利
自然语言处理概述
NLP 的定义
NLP(Nature Language Processing,自然语言处理)
是计算机及人工智能领域的一个重要的子项目,它研究计算机如何处理、理解及应用人类语言。是人类在漫长的进化过程中形成的计算机语言复杂的符号等系统(类似C/Java的符号等系统)。以下是关于自然处理的常见定义:
- 语言处理是科学与自然语言中关于计算机与人类语言转换的领域。
- 语言处理是人工智能领域中一个重要的方向。它研究实现人与计算机之间用自然语言进行有效运作的各种理论和方法。
- 语言处理研究这些方法在交际条件和交际条件下与人交际的一门中及人与计算机网络中的语言问题的语言问题。不断完善这些语言模型,并根据系统的实用性,以及对系统的实用性评测技术。
自然语言处理还有其他一些名称,例如: 自然语言(Natural Language Understanding)
、 计算机语言学(Computational Linguistics)
、 人类语言技术(Human Language Technology)
等等。
NLP的主要任务
NLP 可以分成两类,是生成主要基于新文本或语料的分析,另一种 文本
或 语料
。
; 分词
该任务将文本或语言对日料分隔成更多语言特征单元(单词)。对于拉丁系,词之间有重要的空格等文字,对于中文语言,分词就是例如的,分词直接影响文本的理解。
文本:苏州市姑苏区超市
分词1:苏州市/姑苏区/超市
分词2:苏州/市长/零食/店
词义消歧
例如,在" The dog barked at the mailman”(狗对邮递递员吠叫)
和 正确的树皮“用作药物”(树皮有时用作药物)
中,对于不同的含义。词义消歧类诸如此类的任务。
识别物体识别(NER)
NER尝试从给定的文本或文本语料库中提取实体(例如,人物、位置和组织)。例如,句子:
周一,约翰在学校给了玛丽两个苹果
将转换为:
词性标注(PoS)
PoS 常用的两种称呼分别是名词、动词、形容词、词、词、词等、也可以是词性的词、词、词、动词、动词等。
文本分类
例如文本分类有许多应用场景,垃圾邮件检测、新闻文章分类(例如,政治、科技和运动)和产品评论评分(即正向或负向)。我们可以使用数据标记(即人工对评论标上正面)或者是负面的标签)训练一个分类模型来实现这个任务。
语言生成
可以利用 NLP 来生成新的文本或材料,编写机器天气预报(天气预报、新闻、例如唐诗等),生成文本是一段机器合成的"下面的诗":
向塞向芶芶临扇,猛牒来惊。向面炎交好
,若隚。
何人改,松仙绕绮霞。偶笑寒栖咽,长闻暖顶时。
失个亦垂谏,守身丈韦鸿。忆及他年事,应愁一故名。
坐忆山高道,为随夏郭间。到乱唯无己,千方得命赊。
问答(QA)系统
QA 技术具有广泛的商业价值,这些技术是聊天机器人和 VA(例如,Google Assistant 和 Apple Siri)的支持。许多公司已经采用对话机器人来提供客户。以下是一段与聊天机器人的:
; 机器翻译(MT)
机器翻译,MT)指将文本由一种语言翻译成另一种语言,是根据一个序列(机器翻译最接近的另一种语言生成)。
NLP的发展历程
NLP的发展发展为:基于规则→其基于统计→基于深入学习,发展大致经历了4个阶段:1956年的萌芽期;1957年1970年的快速期;1971年1993年的低速期;1994年现在的复苏融合期。
- 萌芽期(
1956年前
) 1946年
:第一台电子计算机诞生148 年
香农 把 离散 商业 年: 描述 于 马尔 可 的 机 器 。156 年
:Chomsky 又提出了当时的自然语言,并将其运用到处理中。
快速发展期(1957~1970)
一个时期是在不同的处理领域中存在的自然规律和基于两种不同的处理方式。基于这种方法的符号(象征性的)另一派(每个派别)。期间,方法派的研究取得了从60年代开始到长足的发展。乔姆斯基为代表的象征派学者开始了语言理论和生成句法的研究,60年代进行了叶逻辑形式的研究。也取得了很大的进步。
1997 年 TDAP 期重要的美国语言研究成果,美国的语言系统的建立与等。知联系起来了。
低速发展期(1971~1993)
语言研究的结果由于人们看到基于自然语言处理的应用并不能在地段中不断涌现解决,而一连的新问题又出现了,于是,很多人对随着语言处理的研究失去了自然的信心。 70 年代开始,自然语言处理在自然低谷时期。
尽管如此,一些研究人员仍然继续进入了他们的研究。由于他们的出色工作,自然语言处理这一低谷时期同样取得了一些成果。70当年,基于隐马尔可夫模型, HMM的马尔可夫模型(Hidden Markov Model,HMM的马尔可夫模型)
统计了最初在语音领域取得重大进展,话语分析(话语分析)也取得了。过去的研究方法进行了反思,有限状态模型和经验主义研究也开始复苏。
复苏融合期(1994年至今)
90年代以后,有两台计算机从根本上发展到促进语言的自然复苏与研究。一件事是90年代以来,计算机的速度和测量量自然增加,为语言处理改善了物质基础,处理事件的事件; 19 可能化是互联网化和网络化 2000 年的另一种商业活动 4 年基于语言的信息和语言的信息和成为自然语言的 00 话题的热门话题。之后 NLP 领域的里程碑事件:
- 2001年:神经语言模型
- 2008年:多任务学习
- 2013年:词嵌入
- 2013年:NLP的神经网络
- 2014年:序列到序列模型
- 2015年:纪律机制
- 2015年:根据记忆的神经网络
- 2018年:预训练语言模型
NLP的困难与挑战
语言歧义
- *不同分词导致的歧义:
例:自动化研究所取得的成就
一:自动化/研究/所/取得/的/成就
成就二:自动化/研究所/取得/的/成就
- *词性歧义:
动物保护警察
"保护" 理解成动词、名词,不一样。
- *结构异义:
喜欢乡下的孩子
关于鲁迅的文章
- *声笑义:
节假日期间,所有博物馆全部(不)开放
- *不同语言结构差异:
- 未知语言不可预测性:
语言不断出现,每年都有大量的新词、出现材料,给一些 NLP 任务造成了困难。以下是 2022 年网络上的新词:
双减
元 宇宙
绝绝子
平躺
- *语言表达的复杂性:
甲:你这人真正的英文?甲:没有英文,英文
?那我就不好意思了。
- *机器语言处理 广泛的背景与常识
中国队最有悬念的是全世界有一个女人也有她和她,他们一个谁也有谁干过球,不过,另一个人打
如果希拉里干过球,只是因为美国总统和美国总统的努力,克林顿也将成为全世界唯一一个干过美国总统和干过美国总统的男人
NLP相关知识构成
; 语料库
什么是语料库
语料库是指语言材料(材料库的我们)。现代的语料是指放在以原始语料库里的语料或文字标注的文字文本。 ,语言反应单位的使用和意义,基本以知识的表现形态——语言的原貌。
语料库的特征
- 语料库中存放的是真实中出现过的材料。
- 语料库是计算机为承重语言知识的资源,但语言知识的资源。
- 真实语料需要经过分析、处理和加工,才能成为有用的资源。
语料库的作用
- 支持语言学研究和语言教学研究。
- 支持 NLP 系统的开发。
常用语料库介绍
北京大学计算机语言所语料库(中文),地址: https://opendata.pku.edu.cn/dataverse/icl
London-Lund 英语口语语料库,地址:http 😕/www.helsinki.fi/varieng/CoRD/copora.LLC/
腾讯中文语每包含800个万个单词。其中每一个词都满足2200个维的库,包括最新的一期新词。采用了一个更先进的工具预测的数据和更好的。
维基百科是编辑和最常用的开放网络数据集之一,作为最常用的材料、内容、格式的文本语言,各种语言的维基百科在 NLP 中广泛应用。
传统NLP处理技术
中文分词
中文分词是具有重要意义的基本任务,对文本分词统计有重要的直接影响,有分词规则的理解。分词主要是基于的分词和分词。基于分词主要是通过维护语句,在切切时,将语句的每个子字符串与表中的词进行匹配则切分,缺少则不切分;根据统计找到的分词,是根据统计规则和语言模型,输出一个特色的最大分词(由于需要的知识尚未讲解,暂且不讨论);混合分词就是各种分词方式混合使用,从而提高分词准确率。下面根据介绍规则的分词顺序。
正向最大匹配法
正向最大匹配法(Forward Maximum Matching,FMM)
是按照从前到后的顺序对语句进行切分,其步骤为:
- 从左向右取字待分汉语句的m个作为匹配字段,m为词典中词的最长长度;
- 查找进行词典匹配;
- 若成功,则作为匹配词切分出去;
- 若不成功,则将派出一个字,进行剩余的字作为新的匹配;
- 重复上述过程,直到切分所有词为止。
逆向最大匹配法
逆向最大匹配法(Reverse Maximum Matching,RMM)
基本原理与FMM基本相同,不同分的方向开始与是相反。RMM是从待分词的右开始,也就是从向左匹配扫描句子,这时句子取m个字作为匹配的地方,找不到匹配的地方,则把前面的一个字,继续匹配。
最大匹配法
进行最大的法匹配, Bi-MM(Bi-MM)
的方向正向匹配最大匹配法向结果的逆向匹配最匹配的规则是:
- 如果正,相反则取分词结果数不同的词数少的那个;
- 分词结果结果没有异义任意任意一个;分词中,返回一个不同的字,返回一个不同的主题,
正向最大匹配分词法
class MM ( object ): def __init__ ( self ): self.window_size = 3
def cut ( self, text ):
result [文本分词结果
= 0
( text_len =)
dic = [ "苏州" , "苏州市" , "姑苏" , "苏锦" , "零食" , "超市" ]
while text_len start: for size in range (self.window_size + start, start, - 1 )
piece = text[start:size]
result.append(piece)
start += len (piece) break else :
if len (piece) == 1 :
result.append(piece)
+= len(片)
break
result.reverse()
返回结果
if __name__ == "__main__":
text = "苏州市苏锦超市"
tk = MM()
result = tk.cut(text)
print(result)
执行结果:
[ '苏州市', '苏锦', '超市']
逆向最大匹配分词法
逆向最大匹配分词示例
class RMM(object):
def __init__(self):
self.window_size = 3
def cut(self, text):
result = [] # 分词结果
start = len(text) # 起始位置
text_len = len(text) # 文本长度
dic = ["苏州", "苏州市", "姑苏", "苏锦", "零食", "超市"]
while start > 0:
for size in range(self.window_size, 0, -1):
piece = text[start-size:start] # 切片
if piece in dic: # 在字典中
result.append(piece) # 添加到列表
start -= len(piece)
break
else: # 没在字典中
if len(piece) == 1:
result.append(piece) # 单个字成词
start -= len(piece)
break
result.reverse()
return result
if __name__ == "__main__":
text = "苏州市姑苏超市"
tk = RMM() # 实例化对象
result = tk.cut(text)
print(result)
执行结果:
[ '苏州', '苏锦', '超市']
Jieba库分词
Jieba 是一款很简单的功能、功能、使用的中文分词工具库,它提供了分词模式:
- 句子合理文本模式:将词最合理,适合分析地。
- 全文:把但中词的所有词组划分出来,速度快,有重复词模式和歧义。
- 搜索引擎模式:在合理模式基础上,对长词再次切分,提高成绩,适合用于搜索引擎分词。
使用 Jieba 库之前,需要进行安装:
pip install jieba== 0.42 . 1
分词代码如下:
jieba分词示例
import jieba
text = "吉林市长春药店"
全模式
seg_list = jieba.cut(text, cut_all=True)
for word in seg_list:
print(word, end="/")
print()
精确模式
seg_list = jieba.cut(text, cut_all=False)
for word in seg_list:
print(word, end="/")
print()
搜索引擎模式
seg_list = jieba.cut_for_search(text)
for word in seg_list:
print(word, end="/")
print()
执行结果:
苏州/苏州市/姑苏/苏锦/零食/超市/
苏州市/姑苏/超市/
苏州/苏州市/姑苏/超市/
文本高频支出
import glob
import random
import jieba
def get_content(path):
with open(path, "r", encoding="gbk", errors="ignore") as f:
content = ""
for line in f.readlines():
line = line.strip()
content += line
return content
def get_tf(words, topk=10):
tf_dict = {}
for w in words:
if w not in tf_dict.items():
tf_dict[w] = tf_dict.get(w, 0) + 1
new_list = sorted(tf_dict.items(), key=lambda x: x[1], reverse=True)
return new_list[:topk]
def get_stop_words(path):
with open(path, encoding="utf8") as f:
return [line.strip() for line in f.readlines()]
if __name__ == "__main__":
fname = "d:\\NLP_DATA\\chap_3\\news\\C000008\\11.txt"
corpus = get_content(fname)
tmp_list = list(jieba.cut(corpus))
stop_words = get_stop_words("d:\\NLP_DATA\\chap_3\\stop_words.utf8")
split_words = []
for tmp in tmp_list:
if tmp not in stop_words:
split_words.append(tmp)
print("\n 分词结果: \n" + "/".join(split_words))
tf_list = get_tf(split_words)
print("\n top10词 \n:", str(tf_list))
执行结果:
分词结果:
焦点/个股/苏宁/电器/002024/该股/早市/涨停/开盘/其后/获利盘/抛/压下/略有/回落/强大/买盘/推动/下该/股/已经/再次/封于/涨停/主力/资金/积极/拉升/意愿/相当/强烈/盘面/解析/技术/层面/早市/指数/小幅/探低/迅速/回升/中石化/强势/上扬/带动/指数/已经/成功/翻红/多头/实力/之强/令人/瞠目结舌/市场/高度/繁荣/情形/投资者/需谨慎/操作/必竟/持续/上攻/已经/消耗/大量/多头/动能/盘中/热点/来看/相比/周二/略有/退温/依然/看到/目前/热点/效应/外扩散/迹象/相当/明显/高度/活跌/板块/已经/前期/有色金属/金融/地产股/向外/扩大/军工/概念/航天航空/操作/思路/短线/依然/需/规避/一下/技术性/回调/风险/盘中/切记/不可/追高
top10词:
[('已经', 4), ('早市', 2), ('涨停', 2), ('略有', 2), ('相当', 2), ('指数', 2), ('多头', 2), ('高度', 2), ('操作', 2), ('盘中', 2)]
top10词:
[( '已经' , 4 ), ( '指数' , 2 ), ( '涨停' , 2 ) , ('突然' , 2 ), ( '相当' , 2 ), ( '指数' , 2 ), ( '多头' , 2 ), ( '高度' , 2 ), ( '操作' , 2 ), ( '盘中' , 2 )]
词性标注
什么是词性标注
词性是词性的语法,通常也被称为词类。词性标注是识别给定文本中各种词性的性质。在词性中不同环境中不同的词性,也就是词性的基本特征,也就是词性标注的基本词性。来性很大的困难。
词性标注的原理
词性标注生成方式,将其输入的相同分词序列作为一个序列生成来处理。
词性标注
有一定的标注规范,如将名词、标注、动词表示为"n"、"adj"、"v"等词性。以下是北大词性标注部分词性表示:
jieba 库词性标注
Jieba 库提供了词性标注功能,采用结合规则和统计的方式,具体为在词性标注的过程中,词典匹配和 HMM 共同作用。词性标注流程如下:
第一步:根据正则表达式判断文本是否为汉字;
第二步:如果判断为汉字,构建 HMM 模型计算最大概率,在词典中查找分出的词性,若在词典中未找到,则标记为 "未知";
第三步:若不如何上面的正则表达式,则继续通过正则表达式进行判断,分别赋予 "未知"、" 数词 "或 "英文"。
Jieba 库实现词性标注代码实现
import jieba.posseg as psg
def pos(text):
results = psg.cut(text)
for w, t in results:
print("%s/%s" % (w, t), end=" ")
print("")
text = "呼伦贝尔大草原"
pos(text)
text = "梅兰芳大剧院里星期六晚上有演出"
pos(text)
运行结果:
呼伦贝尔/nr 大/a 草原/n
梅兰芳/nr 大/a 剧院/n 里/f 星期六/t 晚上/t 有/v 演出/v
命名实体识别(NER)
命名实体识别(Named Entities Recognition,NER)
也是自然语言处理的一个基础任务,是 信息抽取
、 信息检索
、 机器翻译
、 问答系统
等多种自然语言处理技术必不可少的组成部分。其目的是识别语料中人名、地名、组织机构名等命名实体,实体类型包括 3 大类(实体类、时间类和数字类)和 7 小类(人名、地名、组织机构名、时间、日期、货币和百分比)。中文命名实体识别主要有以下难点:
1、各类命名实体的数量众多。
2、命名实体的构成规律复杂。
3、嵌套情况复杂。
4、长度不确定。
命名实体识别方法有:
1、基于规则的命名实体识别。规则加词典是早期命名实体识别中最行之有效的方式。其依赖手工规则的系统,结合命名实体库,对每条规则进行权重赋值,然后通过实体与规则的相符情况来进行类型判断。这种方式可移植性差、更新维护困难等问题。
2、基于统计的命名实体识别。基于统计的命名实体识别方法有:隐马尔可夫模型、最大熵模型、条件随机场等。其主要思想是基于人工标注的语料,将命名实体识别任务作为序列标注问题来解决。基于统计的方法对语料库的依赖比较大,而可以用来建设和评估命名实体识别系统的大规模通用语料库又比较少,这是该方法的一大制约。
3、基于深度学习的方法。利用深度学习模型,预测词(或字)是否为命名实体,并预测出起始、结束位置。
4、混合方法。将前面介绍的方法混合使用。
命名实体识别在深度学习部分有专门案例进行探讨和演示。
关键词提取
关键词提取是提取出代表文章重要内容的一组词,对 文本聚类
、 分类
、 自动摘要
起到重要作用。此外,关键词提取还能使人们便捷地浏览和获取信息。现实中大量文本不包含关键词,自动提取关检测技术具有重要意义和价值。关键词提取包括有监督学习、无监督学习方法两类。
有监督关键词提取
。该方法主要通过分类方式进行,通过构建一个较为丰富完整的词表,然后通过判断每个文档与词表中每个词的匹配程度,以类似打标签的方式,达到关键词提取的效果。该方法能获取较高的精度,但需要对大量样本进行标注,人工成本过高。另外,现在每天都有大量新的信息出现,固定词表很难将新信息内容表达出来,但人工实时维护词表成本过高。所以,有监督学习关键词提取方法有较明显的缺陷。
无监督关键词提取
。相对于有监督关键词提取,无监督方法对数据要求低得多,既不需要人工维护词表,也不需要人工标注语料辅助训练。因此,在实际应用中更受青睐。这里主要介绍无监督关键词提取算法,包括 TF-IDF 算法,TextRank 算法和主题模型算法。
TF-IDF 算法
TF-IDF(Term Frequency-Inverse Document Frequency,词频 - 逆文档频率)
是一种基于传统的统计计算方法,常用于评估一个文档集中一个词对某份文档的重要程度。其基本思想是:一个词语在文档中出现的次数越多、出现的文档越少,语义贡献度越大(对文档区分能力越强)。TF-IDF 表达式由两部分构成, 词频
、 逆文档频率
。词频定义为:
T F i j = n j i ∑ k n k j TF_{ij} = \frac{n_{ji}}{\sum_k n_{kj}}T F i j =∑k n k j n j i
其中,n i j n_{ij}n i j 表示词语 i 在文档 j 中出现的次数,分母∑ k n k j \sum_k n_{kj}∑k n k j 表示所有文档总次数。逆文档频率定义为:
I D F i = l o g ( ∣ D ∣ ∣ D i ∣ + 1 ) IDF_i = log(\frac{|D|}{|D_i| + 1})I D F i =l o g (∣D i ∣+1 ∣D ∣)
其中,∣ D ∣ |D|∣D ∣为文档总数,D i D_i D i 为文档中出现词 i 的文档数量,分母加 1 是避免分母为 0 的情况(称为拉普拉斯平滑),TF-IDF 算法是将 TF 和 IDF 综合使用,表达式为:
T F − I D F = T F i j × I D F i = n j i ∑ k n k j × l o g ( ∣ D ∣ ∣ D i ∣ + 1 ) TF-IDF = TF_{ij} \times IDF_i =\frac{n_{ji}}{\sum_k n_{kj}} \times log(\frac{|D|}{|D_i| + 1})T F −I D F =T F i j ×I D F i =∑k n k j n j i ×l o g (∣D i ∣+1 ∣D ∣)
由公式可知,词频越大,该值越大;出现的文档数越多(说明该词越通用),逆文档频率越接近 0,语义贡献度越低。例如有以下文本:
世界献血日,学校团体、献血服务志愿者等可到血液中心参观检验加工过程,我们会对检验结果进行公示,同时血液的价格也将进行公示。
以上文本词语总数为 30,计算几个词的词频:
假设出现献血、血液、进行、公示文档数量分别为 10、15、100、50,根据 TF-IDF 计算公式,得:
"献血"、"血液" 的 TF-IDF 值最高,所以为最适合这篇文档的关键词。
TextRank 算法
与 TF-IDF
不一样, TextRank 算法
可以脱离于语料库,仅对单篇文档进行分析就可以提取该文档的关键词,这也是 TextRank 算法
的一个重要特点。 TextRank 算法
最早用于文档的自动摘要,基于句子维度的分析,利用算法对每个句子进行打分,挑选出分数最高的 n 个句子作为文档的关键句,以达到自动摘要的效果。
TextRank 算法
的基本思想来源于 Google
的 PageRank 算法
,该算法是 Google 创始人拉里・佩奇和希尔盖・布林于 1997 年构建早期的搜索系统原型时提出的链接分析法,用于评价搜索系统各覆盖网页重要性的一种方法。随着 Google 的成功,该算法也称为其它搜索引擎和学术界十分关注的计算模型。
PageRank 基本思想有两条:
- 链接数量。一个网页被越多的其它网页链接,说明这个网页越重要。
- 链接质量。一个网页被一个越高权值的网页链接,也能表名这个网页越重要。
基于上述思想,一个网页的 PageRank 计算公式可以表示为:
S ( V i ) = ∑ j ∈ I n ( V i ) ( 1 O u t ( V j ) × S ( V j ) ) S(V_i) = \sum_{j \in In(V_i)} \Bigg( \frac{1}{Out(V_j)} \times S(V_j) \Bigg)S (V i )=∑j ∈I n (V i )(O u t (V j )1 ×S (V j ))
其中,I n ( V i ) In(V_i)I n (V i ) 为V i V_i V i 的入链集合,O u t ( V j ) Out(V_j)O u t (V j ) 为V j V_j V j 的出链集合,∣ O u t ( V j ) ∣ |Out(V_j)|∣O u t (V j )∣为出链的数量。因为每个网页要将它自身的分数平均贡献给每个出链,则( 1 O u t ( V j ) × S ( V j ) ) \Bigg( \frac{1}{Out(V_j)} \times S(V_j) \Bigg)(O u t (V j )1 ×S (V j )) 即为V i V_i V i 贡献给V j V_j V j 的分数。将所有入链贡献给它的分数全部加起来,就是V i V_i V i 自身的得分。算法开始时,将所有页面的得分均初始化为 1。
对于一些孤立页面,可能链入、链出的页面数量为 0,为了避免这种情况,对公式进行了改造,加入了一个阻尼系数d d d,这样,即使孤立页面也有一个得分。改造后的公式如下:
S ( V i ) = ( 1 − d ) + d × ∑ j ∈ I n ( V i ) ( 1 O u t ( V j ) × S ( V j ) ) S(V_i) = (1 - d) + d \times \sum_{j \in In(V_i)} \Bigg( \frac{1}{Out(V_j)} \times S(V_j) \Bigg)S (V i )=(1 −d )+d ×∑j ∈I n (V i )(O u t (V j )1 ×S (V j ))
以上就是 PageRank 的理论,也是 TextRank 的理论基础,不同于的是 TextRank 不需要与文档中的所有词进行链接,而是采用一个窗口大小,在窗口中的词互相都有链接关系。例如对下面的文本进行窗口划分:
世界献血日,学校团体、献血服务志愿者等可到血液中心参观检验加工过程,我们会对检验结果进行公示,同时血液的价格也将进行公示。
如果将窗口大小设置为 5,则可得到如下计算窗口:
[世界,献血,日,学校,团体]
[献血,日,学校,团体,献血]
[日,学校,团体,献血,服务]
[学校,团体,献血,服务,志愿者]
......
每个窗口内所有词之间都有链接关系,如 [世界] 和 [献血,日,学校,团体] 之间有链接关系。得到了链接关系,就可以套用 TextRank 公式,计算每个词的得分,最后选择得分最高的 N 个词作为文档的关键词。
关键词提取示例
本案例演示了通过自定义 TF-IDF
、调用 TextRank API
实现关键字提取:
import math
import jieba
import jieba.posseg as psg
from gensim import corpora, models
from jieba import analyse
import functools
import numpy as np
def get_stopword_list():
stop_word_path = '../data/stopword.txt'
with open(stop_word_path, "r", encoding="utf-8") as f:
lines = f.readlines()
stopword_list = [sw.replace('\n', '') for sw in lines]
return stopword_list
def word_filter(seg_list):
filter_list = []
for word in seg_list:
if not word in stopword_list and len(word) > 1:
filter_list.append(word)
return filter_list
def load_data(corpus_path):
doc_list = []
for line in open(corpus_path, 'r', encoding='utf-8'):
content = line.strip()
seg_list = jieba.cut(content)
filter_list = word_filter(seg_list)
doc_list.append(filter_list)
return doc_list
def train_idf(doc_list):
idf_dic = {}
tt_count = len(doc_list)
for doc in doc_list:
doc_set = set(doc)
for word in doc_set:
idf_dic[word] = idf_dic.get(word, 0.0) + 1.0
for word, doc_cnt in idf_dic.items():
idf_dic[word] = math.log(tt_count / (1.0 + doc_cnt))
default_idf = math.log(tt_count / (1.0))
return idf_dic, default_idf
class TfIdf(object):
def __init__(self, idf_dic, default_idf, word_list, keyword_num):
"""
TfIdf类构造方法
:param idf_dic: 训练好的idf字典
:param default_idf: 默认idf值
:param word_list: 待提取文本
:param keyword_num: 关键词数量
"""
self.word_list = word_list
self.idf_dic, self.default_idf = idf_dic, default_idf
self.tf_dic = self.get_tf_dic()
self.keyword_num = keyword_num
def get_tf_dic(self):
tf_dic = {}
for word in self.word_list:
tf_dic[word] = tf_dic.get(word, 0.0) + 1.0
total = len(self.word_list)
for word, word_cnt in tf_dic.items():
tf_dic[word] = float(word_cnt) / total
return tf_dic
def get_tfidf(self):
tfidf_dic = {}
for word in self.word_list:
idf = self.idf_dic.get(word, self.default_idf)
tf = self.tf_dic.get(word, 0)
tfidf = tf * idf
tfidf_dic[word] = tfidf
s_list = sorted(tfidf_dic.items(), key=lambda x: x[1], reverse=True)
top_list = s_list[:self.keyword_num]
for k, v in top_list:
print(k + ", ", end='')
print()
def tfidf_extract(word_list, keyword_num=20):
doc_list = load_data('../data/corpus.txt')
idf_dic, default_idf = train_idf(doc_list)
tfidf_model = TfIdf(idf_dic, default_idf, word_list, keyword_num)
tfidf_model.get_tfidf()
def textrank_extract(text, keyword_num=20):
keywords = analyse.textrank(text, keyword_num)
for keyword in keywords:
print(keyword + ", ", end='')
print()
if __name__ == '__main__':
global stopword_list
text = """在中国共产党百年华诞的重要时刻,在"两个一百年"奋斗目标历史交汇关键节点,
党的十九届六中全会的召开具有重大历史意义。全会审议通过的《决议》全面系统总结了党的百年奋斗
重大成就和历史经验,特别是着重阐释了党的十八大以来党和国家事业取得的历史性成就、发生的历史性变革,
充分彰显了中国共产党的历史自觉与历史自信。"""
stopword_list = get_stopword_list()
seg_list = jieba.cut(text)
filter_list = word_filter(seg_list)
print('TF-IDF模型结果:')
tfidf_extract(filter_list)
print('TextRank模型结果:')
textrank_extract(text)
运行结果:
TF-IDF模型结果:
历史, 中国共产党, 百年, 历史性, 华诞, 一百年, 奋斗目标, 交汇, 节点, 十九, 六中全会, 全会, 奋斗, 重大成就, 着重, 阐释, 十八, 党和国家, 成就, 变革,
TextRank模型结果:
历史, 历史性, 意义, 成就, 决议, 审议, 发生, 系统, 总结, 全面, 节点, 关键, 交汇, 召开, 具有, 全会, 取得, 事业, 自信, 变革,
综合案例
垃圾邮件分类
- 数据集介绍:包含 5000 份正常邮件、5001 份垃圾邮件的样本
- 文本特征处理方式:采用 TF-IDF 作为文本特征值
- 模型选择:朴素贝叶斯、支持向量机模型
- 基本流程:读取数据 → 去除停用词和特殊符号 → 计算 TF-IDF 特征值 → 模型训练 → 预测 → 打印结果
import numpy as np
import re
import string
import sklearn.model_selection as ms
from sklearn.naive_bayes import MultinomialNB
from sklearn.linear_model import SGDClassifier
from sklearn import metrics
import jieba
from sklearn.feature_extraction.text import TfidfVectorizer
label_name_map = ["垃圾邮件", "正常邮件"]
def tokenize_text(text):
tokens = jieba.cut(text)
tokens = [token.strip() for token in tokens]
return tokens
def remove_special_characters(text):
tokens = tokenize_text(text)
pattern = re.compile('[{}]'.format(re.escape(string.punctuation)))
filtered_tokens = filter(None, [pattern.sub('', token) for token in tokens])
filtered_text = ' '.join(filtered_tokens)
return filtered_text
def remove_stopwords(text):
tokens = tokenize_text(text)
filtered_tokens = [token for token in tokens if token not in stopword_list]
filtered_text = ''.join(filtered_tokens)
return filtered_text
def normalize_corpus(corpus):
result = []
for text in corpus:
text = remove_special_characters(text)
text = remove_stopwords(text)
result.append(text)
return result
def tfidf_extractor(corpus):
vectorizer = TfidfVectorizer(min_df=1,
norm='l2',
smooth_idf=True,
use_idf=True)
features = vectorizer.fit_transform(corpus)
return vectorizer, features
def get_data():
'''
获取数据
:return: 文本数据,对应的labels
'''
corpus = []
labels = []
with open("data/ham_data.txt", encoding="utf8") as f:
for line in f.readlines():
corpus.append(line)
labels.append(1)
with open("data/spam_data.txt", encoding="utf8") as f:
for line in f.readlines():
corpus.append(line)
labels.append(0)
return corpus, labels
def remove_empty_docs(corpus, labels):
filtered_corpus = []
filtered_labels = []
for doc, label in zip(corpus, labels):
if doc.strip():
filtered_corpus.append(doc)
filtered_labels.append(label)
return filtered_corpus, filtered_labels
def print_metrics(true_labels, predicted_labels):
accuracy = metrics.accuracy_score(true_labels, predicted_labels)
precision = metrics.precision_score(true_labels,
predicted_labels,
average='weighted')
recall = metrics.recall_score(true_labels,
predicted_labels,
average='weighted')
f1 = metrics.f1_score(true_labels,
predicted_labels,
average='weighted')
print("正确率: %.2f, 查准率: %.2f, 召回率: %.2f, F1: %.2f" % (accuracy, precision, recall, f1))
if __name__ == "__main__":
global stopword_list
with open("dict/stop_words.utf8", encoding="utf8") as f:
stopword_list = f.readlines()
corpus, labels = get_data()
corpus, labels = remove_empty_docs(corpus, labels)
print("总的数据量:", len(labels))
for i in range(10):
print("label:", labels[i], " 邮件内容:", corpus[i])
train_corpus, test_corpus, train_labels, test_labels = \
ms.train_test_split(corpus,
labels,
test_size=0.10,
random_state=36)
norm_train_corpus = normalize_corpus(train_corpus)
norm_test_corpus = normalize_corpus(test_corpus)
tfidf_vectorizer, tfidf_train_features = tfidf_extractor(norm_train_corpus)
tfidf_test_features = tfidf_vectorizer.transform(norm_test_corpus)
print("基于tfidf的贝叶斯模型")
nb_model = MultinomialNB()
nb_model.fit(tfidf_train_features, train_labels)
mnb_pred = nb_model.predict(tfidf_test_features)
print_metrics(true_labels=test_labels, predicted_labels=mnb_pred)
print("")
print("基于tfidf的支持向量机模型")
svm_model = SGDClassifier()
svm_model.fit(tfidf_train_features, train_labels)
svm_pred = svm_model.predict(tfidf_test_features)
print_metrics(true_labels=test_labels, predicted_labels=svm_pred)
print("")
num = 0
for text, label, pred_lbl in zip(test_corpus, test_labels, svm_pred):
print('真实类别:', label_name_map[int(label)], ' 预测结果:', label_name_map[int(pred_lbl)])
print('邮件内容【', text.replace("\n", ""), '】')
print("")
num += 1
if num == 10:
break
运行结果:
基于tfidf的贝叶斯模型
正确率: 0.97, 查准率: 0.97, 召回率: 0.97, F1: 0.97
基于tfidf的支持向量机模型
正确率: 0.98, 查准率: 0.98, 召回率: 0.98, F1: 0.98
真实类别: 正常邮件 预测结果: 正常邮件
邮件内容【 分专业吧,也分导师吧 标 题: Re: 问一个:有人觉得自己博士能混毕业吗 当然很好混毕业了 : 博士读到快中期了,始终感觉什么都不会,文章也没发几篇好的,论文的架构也没有, : 一切跟刚上的时候没有区别。但是事实上我也很辛苦的找资料,做实验,还进公司实习过, : 现在感觉好失败,内心已经放弃了,打算混毕业,不知道过来人有什么高招,请指点一二。 -- 】
真实类别: 垃圾邮件 预测结果: 垃圾邮件
邮件内容【 您好! 我公司有多余的发票可以向外代开!(国税、地税、运输、广告、海关缴款书)。 如果贵公司(厂)有需要请来电洽谈、咨询! 联系电话: 01521025**** 大白 谢谢 顺祝商祺! 】
文本表示
1、One-hot
One-hot(独热)编码是一种最简单的文本表示方式。如果有一个大小为 V 的词表,对于第 i 个词w i w_i w i ,可以用一个长度为 V 的向量来表示,其中第 i 个元素为 1,其它为 0. 例如:
减肥:[1, 0, 0, 0, 0]
瘦身:[0, 1, 0, 0, 0]
增重:[0, 0, 1, 0, 0]
One-hot 词向量构建简单,但也存在明显的弱点:
- 维度过高。如果词数量较多,每个词需要使用更长的向量表示,造成维度灾难;
- 稀疏矩阵。每个词向量,其中只有一位为 1,其它位均为零;
- 语义鸿沟。词语之间的相似度、相关程度无法度量。
词袋模型
词袋模型 (Bag-of-words model,BOW),BOW 模型假定对于一个文档,忽略它的单词顺序和语法、句法等要素,将其仅仅看作是若干个词汇的集合,文档中每个单词的出现都是独立的,不依赖于其它单词是否出现。例如:
我把他揍了一顿,揍得鼻青眼肿
他把我走了一顿,揍得鼻青眼肿
构建一个词典:
{"我":0, "把":1, "他":2, "揍":3, "了":4 "一顿":5, "鼻青眼肿":6, "得":7}
再将句子向量化,维数和字典大小一致,第 i 维上的数值代表 ID 为 i 的词在句子里出现的频次,两个句子可以表示为:
[1, 1, 1, 2, 1, 1, 1, 1]
[1, 1, 1, 2, 1, 1, 1, 1]
词袋模型表示简单,但也存在较为明显的缺点:
- 丢失了顺序和语义。顺序是极其重要的语义信息,词袋模型只统计词语出现的频率,忽略了词语的顺序。例如上述两个句子意思相反,但词袋模型表示却完全一致;
- 高维度和稀疏性。当语料增加时,词袋模型维度也会增加,需要更长的向量来表示。但大多数词语不会出现在一个文本中,所以导致矩阵稀疏。
TF-IDF
TF-IDF(Term Frequency-Inverse Document Frequency,词频 - 逆文档频率)
是一种基于传统的统计计算方法,常用于评估一个文档集中一个词对某份文档的重要程度。其基本思想是:一个词语在文档中出现的次数越多、出现的文档越少,语义贡献度越大(对文档区分能力越强)。其表达式为:
T F − I D F = T F i j × I D F i = n j i ∑ k n k j × l o g ( ∣ D ∣ ∣ D i ∣ + 1 ) TF-IDF = TF_{ij} \times IDF_i =\frac{n_{ji}}{\sum_k n_{kj}} \times log(\frac{|D|}{|D_i| + 1})T F −I D F =T F i j ×I D F i =∑k n k j n j i ×l o g (∣D i ∣+1 ∣D ∣)
该指标依然无法保留词语在文本中的位置关系。该指标前面有过详细讨论,此处不再赘述。
共现矩阵
共现(co-occurrence)矩阵
指通过统计一个事先指定大小的窗口内的词语共现次数,以词语周边的共现词的次数做为当前词语的向量。具体来说,我们通过从大量的语料文本中构建一个共现矩阵来表示词语。例如,有语料如下:
I like deep learning.
I like NLP.
I enjoy flying.
则共现矩阵表示为:
矩阵定义的词向量在一定程度上缓解了 one-hot 向量相似度为 0 的问题,但没有解决数据稀疏性和维度灾难的问题。
💫点击直接资料领取💫
这里有各种学习资料还有有有趣好玩的编程项目,更有难寻的各种资源。
❤️关注苏州程序大白公众号❤️
👇 👇👇
Original: https://blog.csdn.net/weixin_46931877/article/details/123853663
Author: 苏州程序大白
Title: 【一文讲解深度学习】语言自然语言处理(NLP)第一篇
相关阅读1
Title: 在运动控制系统中如何快速入门EtherCAT总线?
本节主要介绍XPLC006E多轴经济型EtherCAT总线运动控制器控制EtherCAT总线驱动器的方法,分别介绍硬件接线方法,控制器与EtherCAT总线驱动器如何通讯,EtherCAT总线驱动器相关参数的配置,EtherCAT总线初始化操作,以及初始化成功以后的运动控制。
一、XPLC006E功能简介
XPLC006E是正运动运动控制器推出的一款多轴经济型EtherCAT总线运动控制器,XPLC系列运动控制器可应用于各种需要脱机或联机运行的场合。
XPLC006E自带6个电机轴,最多12轴运动控制(含虚拟轴数),支持12轴直线插补、电子凸轮、电子齿轮、同步跟随、虚拟轴设置等功能。
XPLC006E支持多任务同时运行,同时可以在PC上直接仿真运行,编程方式多种可选,支持ZDevelop软件的Basic/PLC梯形图/HMI组态和常用上位机软件编程。
XPLC006E只支持EtherCAT总线轴,不支持脉冲轴和编码器轴。采用EtherCAT总线与驱动器通讯,1ms的刷新周期。
XPLC006E支持PLC、Basic、HMI组态三种编程方式。PC上位机API编程支持C#、C++、LabVIEW、VB、matlab、Qt、Linux、.Net、iMAC、Python、 ROS等接口。
→此款产品有XPLC004E、XPLC006E、XPLC008E三个不同轴数的型号可选。
二、XPLC864E功能简介
XPLC864E在XPLC006E的功能基础上做了升级(即上节介绍的XPLC006E的功能都支持),部分资源空间优于XPLC006E,使用方法基本一致,不同之处在于XPLC864E,硬件支持32点输入、32点输出、2个ADC、2个DAC,支持脉冲轴和总线轴混合使用,总实轴轴数为8,除了带EtherCAT接口之外,输出口硬件上可配置为8个轴的脉冲方向信号输出,另带两路编码器输入,可由输入口配置
XPLC864E支持 PLC 、Basic 、HMI组态三种编程方式。PC上位机API编程支持C#、C++、LabVIEW、VB、matlab、Qt、Linux、.Net、iMAC、Python、 ROS等接口。
三、通讯接线
1.EtherCAT总线接线
使用一根网线将XPLC006E控制器的 "Eth erCAT总线端口" 与 "伺服驱动器的EtherCAT总线端口" 相连即可。
注意: 伺服驱动器的EtherCAT接口有两个,有些驱动器这两个口可以随意接,有些分为"EtherCAT IN"和"EtherCAT OUT",IN口接上一级设备,OUT口接下一级设备,二者不能混用,要注意连接顺序。
多轴控制时伺服驱动器的EtherCAT OUT口再连接下一级驱动设备的EtherCAT IN口,依此类推。
slot槽位编号、node节点编号和驱动器编号规则如上图所示,EtherCAT总线接口的槽位号默认是0,节点编号按照与控制器的连接先后顺序从0开始依次编号,驱动器编号则是只给带电机设备编号,其他类型设备忽略,也是按连接顺序从0开始编号,这些编号在总线指令中将会用到。
硬件接线完成后,仍需运行总线初始化程序与驱动程序进行通信。初始化模板程序如下所示。
[En]
After the hardware wiring is completed, you still need to run the bus initialization program to communicate with the driver. The initialization template program can be seen below.
注意: 使用EtherCAT总线扩展模块时,也要执行总线初始化操作,再映射IO的编号后才可操作扩展IO。
2. 控制器与电脑连接
控制器和计算机可以通过串口或网口连接,如网口连接的例子所示。
[En]
The controller and the computer can be connected through a serial port or a network port, which is illustrated by an example of a network port connection.
先将控制器与电脑用一根网线连接好,接通控制器的电源,再打开ZDevelop编程软件,点击菜单栏"控制器"→"连接",打开"连接到控制器"窗口。
通过"连接到控制器"窗口,可以快速查看本机IP,对比控制器与电脑是否处于同一网段。
IP地址列表下拉选择时,会自动查找当前局域网可用的控制器IP地址 (控制器上电POWER灯和RUN灯亮的时候就能查找到该控制器的IP地址) 。
同一个网络有多个控制器的时候,IP的下拉列表若没有显示目标控制器的IP地址,可以采取IP扫描来查看当前所有可用的控制器IP地址,扫描完成之后确定关闭此窗口,重新在IP下拉列表选择。
选择正确的IP地址,点击连接之后,连接成功或失败均有信息提示。
控制器出厂的缺省IP地址为192.168.0.11,"连接到控制器"窗口能显示出本机IP地址,请注意设置有线网卡与无线网卡各自的IP。电脑需要设置IP地址与控制器IP处于同一网段才能连接,即四段的前三段要相同,最后一段不同才能通讯。
若控制器与电脑不处于同一网段,则需要修改控制器或电脑其中之一的IP地址,使二者处于同一网段。
若控制器IP地址遗忘,可通过网口连接控制器,再获取控制器IP。
四、EtherCAT总线驱动器通讯说明
1.通讯周期
使用EtherCAT伺服驱动器时需要保证控制器与伺服周期一致才可正常通讯使用。
EtherCAT伺服驱动器一般支持不同周期,通讯周期主要有250us,500us,1ms,2ms,4ms,连接时自动匹配控制器周期,不需要设置,当通讯周期无法自动匹配时,通讯失败,通过修改控制器周期解决 (SERVO_PERIOD指令或升级固件修改) 。
控制器一般默认为1ms,使用SERVO_PERIOD指令读取控制器周期。 伺服周期越小,位置控制越精细,响应速度也更快。
2.驱动器PDO设置
驱动器的PDO是必要的配置,代表着当前驱动器包含的功能。
PDO全名为(Process Data Object),指在EtherCAT总线网络中周期的进行主站与从站的数据交互的功能,可以看作一个数组空间,每个数组元素存放了不同的功能码,PDO在一个周期中执行这些功能码对应的操作,这些功能码就叫做数据字典,数据字典用4位16进制数来表示。
RxPDO: 主站传送数据给从站。 TxPDO: 从站传送数据给主站。EtherCAT总线上控制器为主站,伺服驱动器为从站。
如6040h控制字 (用于控制伺服轴的使能、启动、停止、报警、复位等运行状态) ,每个数据字典Index可包含32个子字典Sub-Index。数据字典的功能和初始值查看驱动器手册的描述。
数据字典的编号及功能是协议本身就确定好的,用户只需按照数据字典的描述设置数据字典的bit位,所有的标准EtherCAT设备都使用一套数据字典。
松下A6B伺服驱动器的EtherCAT相关说明内容可查看松下文档《技术资料-EtherCAT通讯规格篇》。
EtherCAT初始化过程中必须进行驱动器PDO配置,"DRIVE_PROFILE"指令配置驱动器的PDO列表,目前提供约20几种配置选择,每种配置包含哪些数据字典查看该指令说明确认,如下图,具体内容可以在《ZBasic编程手册》中查看。
DRIVE_PROFILE=-1表示驱动器的内置缺省PDO列表,驱动器内置PDO列表包含哪些数据字典需要查看驱动器手册。
DRIVE_PROFILE已有的配置不能满足需求就自定义PDO,采用SDO相关指令操作数据字典配置驱动器需要的PDO。
驱动器的相关参数修改,同样使用SDO指令读写对应的数据字典进行配置或通过驱动器软件修改。SDO指令包含数据字典读取"SDO_READ"、"SDO_READ_AXIS"和数据字典写入"SDO_WRITE"、"SDO_WRITE_AXIS"。
(1)数据字典读取语法
SDO_READ (槽位号, 设备编号, 数据字典编号, 数据字典子编号, 数据类型, 读取数据存储TABLE位置)
SDO_READ_AXIS (轴号, 数据字典编号, 数据字典子编号, 数据类型, 读取数据存储TABLE位置)
(2)数据字典写入语法
SDO_WRITE (槽位号, 设备编号, 数据字典编号, 数据字典子编号, 数据类型, 写入数据值)
SDO_WRITE_AXIS (轴号, 数据字典编号, 数据字典子编号, 数据类型, 写入数据值)
自定义PDO的配置方法请咨询正运动的销售工程师或者技术工程师。
3. 驱动器参数设置
可使用驱动器软件修改,或控制器端操作SDO指令修改。修改驱动器参数先连接驱动器,可选USB线或WLAN连接驱动器,使用USB线连接电脑与驱动器端的X1端口,给驱动器上电。
打开松下驱动器软件PANATERM,弹出"选择与驱动器通信"窗口,选择与驱动器通过USB连接后,自动获取到驱动器信息显示在窗口内,点击OK连接成功,就能对驱动器进行设置。
点击菜单栏"显示"→"对象编辑器",打开如下窗口,找到需要设置的数据字典,在"Setting Value"一栏直接修改数据字典的内容。
修改完成将参数传送给驱动器,并写入驱动器的EEPROM,驱动器再次上电后参数生效。
例: 设置UNITS脉冲当量,即设置电机转一圈需要发送多少个脉冲。
SPEED速度、ACCEL加速度、DECEL减速度和运动指令等都是以UNITS为基本单位。
如上图,通过数字字典6091h设置电子齿轮比,6091h-01h设置电子齿轮比分子,6091h-02h设置电子齿轮比分母,此时,电子齿轮比=1/1,6092h-01h设为10000表示给电机发10000个脉冲能使电机旋转一圈,对应的脉冲当量UNITS=10000,MOVE(2)表示给电机发送20000个脉冲,此时电机转两圈。
或者使用SDO指令读写数据字典修改参数。修改完成使用驱动器软件读取6092h-01h的值为10000。
示例:
4. 驱动器IO信号
若要使用驱动器的IO口,才会涉及到驱动器的IO映射操作,否则忽略。当驱动器产生IO报警时,可根据驱动器手册的提示,修改IO的设定值。
驱动器自身有输入信号,作用为保护信号,默认使能状态,若不接入外部信号,驱动器就会保护报错,调试阶段可以关闭这些信号方便调试,将输入值设置为0即可,需要使用驱动器IO时要对驱动器的IO编号映射后才能使用,后续根据实际需求接入实际信号。
点击驱动器软件PANATERM主界面的"参数"按钮打开下方窗口,选中要修改的IO信号后,在"设定值"一栏修改。
驱动器IO映射需要PDO包含数据字典60FDh,然后使用DRIVE_IO指令设置驱动器IO地址,映射的编号范围不要与总线上的其他设备的IO编号重复。
DRIVE_IO (轴号)=输入输出IO起始编号。
示例:
5.参数写入驱动器
可使用驱动器软件修改,或控制器端操作SDO指令修改。
驱动器的数据字典参数或其他的参数设置完成后,先点击"传送"将修改的全部参数传入驱动器,再点击EEP,将参数写入驱动器的EEPROM,给驱动器重新上电后修改的参数生效,图片上值修改了输入参数,在上图参数一览中可参看多中类别的参数并修改。
6. 驱动器轴号映射
EtherCAT总线驱动电机设备连上控制器之后,驱动器轴号需要使用指令映射绑定。
EtherCAT总线上连接的设备的设备号按照连接顺序从0开始自动编号,驱动器编号也是按连接顺序给驱动器设备自动从0开始编号的,只算总线上的驱动器设备,其他设备是没有驱动器编号的。
EtherCAT总线上连接的驱动器需要使用指令映射驱动器的轴号,使用AXIS_ADDRESS 指令映射,映射完成之后才能使用BASE指令选择驱动器轴号,发送脉冲,控制驱动器所连的电机运行。
在扫描母线之后和打开母线之前,将轴映射写入母线初始化程序中。
[En]
The axis mapping is written in the bus initialization program, after the bus is scanned and before the bus is opened.
语法:AXIS_ADDRESS(轴号)=(槽位号<
Original: https://www.cnblogs.com/zmtion/p/16616858.html
Author: 正运动技术
Title: 在运动控制系统中如何快速入门EtherCAT总线?
相关阅读2
Title: 【安装学习】安装Cartographer ROS(noetic)
【Cartographer介绍】
2016年10月5日,谷歌宣布开放一个名为cartographer的即时定位与地图建模库,开发人员可以使用该库实现机器人在二维或三维条件下的定位及建图功能。cartograhper的设计目的是在计算资源有限的情况下,实时获取相对较高精度的2D地图。考虑到基于模拟策略的粒子滤波方法在较大环境下对内存和计算资源的需求较高,cartographer采用基于图网络的优化方法。
cartographer是google开发的实时室内SLAM项目,cartographer采用基于google自家开发的ceres非线性优化的方法,cartographer的量点在于代码规范与工程化,非常适合于商业应用和再开发。并且cartographer基于submap子图构建全局地图的思想,能有效的避免建图过程中环境中移动物体的干扰。并且cartographer支持多传感器数据(odometry、IMU、LaserScan等) 建图 ,支持2D_SLAM和3D_SLAM 建图 。
此处感谢:
安装Cartographer功能包有两种方法:
1,ROS集成版,使用命令sudo apt install ros-
2.源码编译的方式进行安装。
参照官网教程:
Compiling Cartographer ROS — Cartographer ROS documentation
【安装编译】
- 创建工作空间
mkdir -p ~/catkin_google_ws/src
cd catkin_google_ws/src
catkin_init_workspace
2.安装工具
sudo apt update
sudo apt install -y python3-wstool python3-rosdep ninja-build stow
3.初始化工作空间
cd catkin_google_ws
wstool init src
wstool merge -t src https://raw.githubusercontent.com/cartographer-project/cartographer_ros/master/cartographer_ros.rosinstall
wstool update -t src
4 .安装依赖并下载cartographer相关功能包
此处推荐使用国内用户用的rosdepc
sudo pip install rosdepc
sudo rosdepc init
rosdepc update
感谢小鱼:
rosdep update
rosdep install --from-paths src --ignore-src --rosdistro=${ROS_DISTRO} -y
此过程可能会出现报错信息,原因可能与ROS版本相关 ,根据提示手动安装缺少的库或依赖即可
5.安装abseil cpp库
src/cartographer/scripts/install_abseil.sh
若与已装库冲突,需要卸载之前的库
sudo apt-get remove ros-${ROS_DISTRO}-abseil-cpp
6.编译与安装
catkin_make_isolated --install --use-ninja
source devel_isolated/setup.bash
7.下载并运行2d demo
wget -P ~/Downloads https://storage.googleapis.com/cartographer-public-data/bags/backpack_2d/cartographer_paper_deutsches_museum.bag
roslaunch cartographer_ros demo_backpack_2d.launch bag_filename:=${HOME}/Downloads/cartographer_paper_deutsches_museum.bag
效果如下图
Original: https://blog.csdn.net/weixin_44362628/article/details/122540297
Author: Howe_xixi
Title: 【安装学习】安装Cartographer ROS(noetic)
相关阅读3
Title: Audio-AIUI语音交互
通过不同平台设置录音API tinyalsa获取到原始音频,经过回声消除、噪声抑制的简单算法处理得到的单声道音频数据,之后进行关键词唤醒、AI交互、语义理解以及各种TTS播报等场景的使用了。下面就对AIUI交互使用场景中的关键节点以及关键状态为的check问题进行一些分析,方便以后定位问题。
https://aiui.xfyun.cn/doc/aiui/3_access_service/access_interact/sdk/msg_event.html
1.AIUI流程分析
项目中用到的一些AIUI关键节点及事件状态,基本一套完整的AIUI交互就是以下事件中的不同状态间的切换并对不同状态进行处理即可。
public class AIUIConstant {
...
public static final int EVENT_CONNECTED_TO_SERVER = 13; //连接服务器成功
public static final int EVENT_ERROR = 2;
public static final int EVENT_RESULT = 1; //返回结果
public static final int EVENT_SERVER_DISCONNECTED = 14; //连接服务器失败
public static final int EVENT_SLEEP = 5; //长时间未交互
public static final int EVENT_STATE = 3; //服务器工作状态
public static final int EVENT_TTS = 15; //TTS播报相关
public static final int EVENT_VAD = 6; //音频输入相关
public static final int EVENT_WAKEUP = 4; //成功唤醒
...
public static final int CMD_RESET_WAKEUP = 8; //AIUI进入SLEEP状态
public static final int CMD_RESULT_VALIDATION_ACK = 20; //AIUI重置interac_timeout
public static final int CMD_TTS = 27; //AIUI进入TTS播报状态
public static final int CMD_WAKEUP = 7; //AIUI进入唤醒状态
public static final int CMD_SET_PARAMS = 10; //手动修改AIUI配置参数
public static final int CMD_WRITE = 2; //手动向AIUI写入音频数据
...
///*服务器具体工作状态
public static final int STATE_IDLE = 1;
public static final int STATE_READY = 2;
public static final int STATE_WORKING = 3;
///*服务器TTS具体状态
public static final int TTS_SPEAK_BEGIN = 1;
public static final int TTS_SPEAK_COMPLETED = 5;
public static final int TTS_SPEAK_PAUSED = 2;
public static final int TTS_SPEAK_PROGRESS = 4;
public static final int TTS_SPEAK_RESUMED = 3;
///*服务器VAD具体状态
public static final int VAD_BOS = 0; //语音输入开始前端点检测
public static final int VAD_BOS_TIMEOUT = 3; //语音输入在检测到前端点之后长时间未说话
public static final int VAD_EOS = 2; //语音输入结束后端点检测
public static final int VAD_VOL = 1; //语音输入过程
...
}
1.Connect to Server
2.Trigger WakeUp
3.Change AIUI State to Working
4.Trigger TTS and play "你好"
5. AIUI TTS: begin -> progress -> completed,播报时间1.6s
6.AIUI VAD:bos -> vol -> eos ,音频输入2s时间
7.AIUI Recognise Result
AIUI VAD检测阶段,返回识别到的音频输入内容-"琵琶行"
AIUI VAD结束阶段,返回语音理解之后的内容-琵琶行诗的内容
8.对AIUI返回的result结果进行关键字段检索,获取需要的text文本进行TTS播报,一次交互完成。
2.AIUI异常结果处理
1.概率性交互不回复
EVENT_SLEEP:
触发机制:长时间不与AIUI进行会话交互触发,会关闭当前会话。
check之前AIUI交互场景18:32:05时开启音频输入,持续了6s,触发交互超时,再之前是TTS播报过程。
2.概率性TTS播报没有声音
EVENT_TTS TTS_SPEAK_PAUSED
时间触发机制:SDK内部主动发送暂停事件或外部触发了别的播放事件抢占音频焦点
check外部触发CMD_TTS抢占音频焦点的情况,发现事件发生在17:57:13,30s之前,排除了这个原因,最后确定是SDK主动发送的暂停事件,需要对这一特殊情况进行特殊处理。
3.嘈杂环境异常处理
EVENT_VAD VAD_EOS
AIUI根据输入的内容进行流式识别结果反馈时,解析的关键字端iatText拿不到输入的音频数据,为null,此时不做异常处理,会默认针对结果为null的提问服务器有应答且进行TTS播报,但实际情况是没有应答且没有播报的。
3.AIUI结果解析
项目中这一块结果解析不是我负责的,从同事那边薅来的劳动成果,已支付版权费,阅。
总结
AIUI交互的重头戏在于一些动画、对话框等内容的美化上,这个后面再说。
Original: https://blog.csdn.net/Cmatrix204/article/details/121947601
Author: Cmatrix204
Title: Audio-AIUI语音交互