一、文本处理工具库:

1、NLTK

python上著名的自然语言处理库。自带语料库,词性分类看;自带分类,分词,等功能。有强大的社区支持,和N多的简单版wrapper(eg.TextBlob)

2、TextBlob 包–英文分析

TextBlob是一个用于处理文本数据的Python库。对NLTK的封装。它为常见的自然语言处理(NLP)任务提供了一个简单的API,例如词性标注,名词短语提取,情感分析,分类,翻译等。结果:(-1,1)GitHub链接:https://github.com/sloria/TextBlob

3、SnowNLP包–中文分析

SnowNLP是一个python写的类库,可以方便的处理中文文本内容,是受到了TextBlob的启发而写的,由于现在大部分的自然语言处理库基本都是针对英文的,于是写了一个方便处理中文的类库,并且和TextBlob不同的是,这里没有用NLTK,所有的算法都是自己实现的,并且自带了一些训练好的字典。SnowNLP用于情感分析方面(现在训练数据主要是买卖东西时的评价,所以对其他的一些可能效果不是很好),而且它的分词能力并没有jieba强大。

4、金融相关API:

彭博社Bloomberg API(30k一个月)、Thomson Reuters(15K)、 Wind、大智慧、同花顺数据API。

二、NLTK的介绍

1、模块

2、NLTK使用

from nltk.corpus import brown  #从nltk语料库中引入brown
brown.categories()  #brown中有哪些类型
print(len(brown.sents()))  #brown中的句子总数
print(len(brown.words()))  #brown中的单词总数

三、文本处理流程

1、分词:

分词方式:
(1)启发式分词:Heuristic。基于查字典进行分词。类比于relu_based
(2)机器学习/统计方法:HMM、CRF、nn、LSTM、RNN等。基于data进行分词(HMM、CRF传统模型是由公式计算是一个单词的概率是多少(概率P);nn、LSTM、RNN深度学习是黑盒子)。类比于Generative
中文的字(1000个覆盖约92%,2000字覆盖98%以上,3000字则已到99%)相当于英文的字母(26个)
(3)案例
英文分词:Tokenize

>>> import nltk
>>> sentence = “hello, world"
>>> tokens = nltk.word_tokenize(sentence)
>>> tokens
['hello', ',', 'world']

中文分词库:jieba

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)

【全模式】: 我/ 来到/ 北北京/ 清华/ 清华⼤大学/ 华⼤大/ ⼤大学
【精确模式】: 我/ 来到/ 北北京/ 清华⼤大学
【新词识别】:他, 来到, 了了, ⽹网易易, 杭研, ⼤大厦
(此处,“杭研”并没有在词典中,但是也被Viterbi算法识别出来了了)
【搜索引擎模式】: 小明, 硕士, 毕业, 于, 中国, 科学, 学院, 科学院, 中国科学院, 计算,计算所, 后, 在, 日本, 京都, 大学, 日本京都大学, 深造
特殊符号:

from nltk.tokenize import word_tokenize
tweet = 'RT @angelababy: love you baby! :D http://ah.love #168cm'
print(word_tokenize(tweet))

输出:
[‘RT’, ‘@’, ‘angelababy’, ‘:’, ‘love’, ‘you’, ‘baby’, ‘!’, ‘:’, ’D’, ‘http’, ‘:’, ‘//ah.love’, ‘#’, ‘168cm’]
输出内容@+人名、网址等都是不需要的;:D表情文本没有表示出其含义。可以利用正则表达式re,对这些内容进行删除或转化。
(4)正则表达式对照表:
http://www.regexlab.com/zh/regref.htm

import re
#识别表情O(∩_∩)O
emoticons_str = r"""(?:[:=;] #眼睛[oO\-]? #鼻子[D\)\]\(\]/\\OpP] #嘴 )"""
#识别特殊符号
regex_str = [emticons_str,r'<[^>]+>', # HTML tagsr'(?:@[\w_]+)', # @某人r"(?:\#+[\w_]+[\w\'_\-]*[\w_]+)", # 话题标签r'http[s]?://(?:[a-z]|[0-9]|[$-_@.&amp;+]|[!*\(\),]|(?:%[0-9a-f][0-9a-f]))+', # URLsr'(?:(?:\d+,?)+(?:\.?\d+)?)', # 数字r"(?:[a-z][a-z'\-_]+[a-z])", # 含有-和'的单词r'(?:[\w_]+)', # 其他r'(?:\S)' # 其他
]

注:虚词:语义处理里没有用,但对于文本表面(如写作水平等)是有用的。分词可根据需要保留
(5)社交网络中的分词案例

tokens_re = re.compile(r'('+'|'.join(regex_str)+')', re.VERBOSE | re.IGNORECASE)
emoticon_re = re.compile(r'^'+emoticons_str+'$', re.VERBOSE | re.IGNORECASE)
def tokenize(s):    return tokens_re.findall(s)
def preprocess(s, lowercase=False):    tokens = tokenize(s)    if lowercase:        tokens = [token if emoticon_re.search(token) else token.lower() for token in tokens]    return tokens
tweet = 'RT @angelababy: love you baby! :D http://ah.love #168cm'
print(preprocess(tweet)) # ['RT', '@angelababy', ':', 'love', 'you', 'baby', # ’!', ':D', 'http://ah.love', '#168cm']

2、英文的词形还原:

(1)将不同的词性(但意思相同)规范为同一个表达式。如
Inflection时态变化(不要影响词性):walk ==> walking ==> walked
derivation引申(词性的变化):nation(noun) ==> national(adjective) ==> nationalize(veb)
(2)词形归一化方法
Stemming词干提取:一般是吧不影响词性的时态的小尾巴砍掉
walking ==> walk
walked ==> walk
Lemmatization词形归一:把各种类型的词的变形(查表),都归为一个形式
went ==> go
are ==> be
(3)代码实现

  • Stemming代码实现:
from nltk.stem.porter import PorterStemmer
porter_stemmer = PorterStemmer()
print(porter_stemmer.stem('maximum'))
print(porter_stemmer.stem('presumably'))
print(porter_stemmer.stem('multiply'))
print(porter_stemmer.stem('provision'))

输出:
maximum
presum
multipli
provis

from nltk.stem import SnowballStemmer
snowball_stemmer = SnowballStemmer("english")
print(snowball_stemmer.stem('maximum'))
print(snowball_stemmer.stem('presumably'))
print(snowball_stemmer.stem('multiply'))
print(snowball_stemmer.stem('provision'))

maximum
presum
multipli
provis

from nltk.stem.lancaster import LancasterStemmer
lancaster_stemmer = LancasterStemmer()
print(lancaster_stemmer.stem('maximum'))
print(lancaster_stemmer.stem('presumably'))
print(lancaster_stemmer.stem('multiply'))
print(lancaster_stemmer.stem('provision'))

输出:
maxim
presum
multiply
provid

from nltk.stem.porter import PorterStemmer
p = PorterStemmer()
print(p.stem('went'))
print(p.stem('wenting'))

输出:
went
went

  • Lemma代码实现:
from nltk.stem import WordNetLemmatizer
wordnet_lemmatizer = WordNetLemmatizer()
print(wordnet_lemmatizer.lemmatize('dogs'))
print(wordnet_lemmatizer.lemmatize('churches'))
print(wordnet_lemmatizer.lemmatize('aardwolves'))
print(wordnet_lemmatizer.lemmatize('abaci'))
print(wordnet_lemmatizer.lemmatize('hardrock'))

输出:
dog
church
aardwolf
abacus
hardrock

一般先使用词性标注判断出词性,在使用Lemma进行词形还原。
1、对于Went:v.go的过去是;n.英文名:温特。直接使用Lemma无法正确还原
2、加入词性后即可准确的进行词形还原

#没有POS Tag,默认为NN 名词
wordnet_lemmatizer.lemmatize('are')
wordnet_lemmatizer.lemmatize('is')#加上POS Tag
wordnet_lemmatizer.lemmatize('are',pos='v')
wordnet_lemmatizer.lemmatize('is',pos='v')
  • NLTK词性标注POS Tag:
import nltk
text = nltk.word_tokenize('what does the fox say')
print(text)
print(nltk.pos_tag(text))

输出:
[‘what’, ‘does’, ‘the’, ‘fox’, ‘say’]
[(‘what’, ‘WDT’), (‘does’, ‘VBZ’), (‘the’, ‘DT’), (‘fox’, ‘NNS’), (‘say’, ‘VBP’)]

3、Stopwprds停用词:

1、全体stopwords列表 http://www.ranks.nl/stopwords
2、nltk.download(‘stopwords’)
3、代码实现

from nltk.corpus import stopwords
# 先token,得到一个word_list
# ...
# 然后filter
filtered_words = [word for word in word_list if word not in stopwords.words('english')]

4、总结

文本的一般预处理流程:
除了NLTK外,斯坦福的:CORENLP库指出中、英、西班牙文

四、文本表示----把句子按数字向量表达

机器学习:通过设定的规则去构造特征。

1、True-False

步骤:建立字典、句子单词出现即在字典对应记为1
缺点:没有考虑词的重要性和顺序关系

2、用元素频率形式表示:

(1)含义
词表位置需要固定,保持在一个空间内。文本表示相当于,每个词都进行one-hot,在累加。
(2)优点:

  • 所有句子的向量长度都是一样的,便于后期的机器学习
  • 向量的长度就是处理文本中不同的词的个数
    (3)缺点:
    没有考虑文本中词与词之间的顺序关系。
    (4)步骤:
  • 建立字典
  • 句子单词出现即在字典对应位置+1
  • 每个句子的维度变为1*字典维度。语料库字典是很重要的。
    如,
    he,he,he,we are happy
    he,he,he,we are
    you work
    每个句子对应的词向量:

    (5)代码实现:
import nltk
from nltk import FreqDist
#先做一个词库
corpus = 'this is my sentence ' 'this is my life' 'this is the day'
tokens = nltk.word_tokenize(corpus)
print(tokens)#使用NLTK的FreqDist统计一下文字出现的频率
fdist = FreqDist(tokens)
print(fdist)
print(fdist['is'])
#输出最常见的50个单词
standard_freq_vector = fdist.most_common(50)
size = len(standard_freq_vector)
print(size)
print(standard_freq_vector)
#按照词频大小,生成{词:位置索引}字典
word_to_count = {}
for term in standard_freq_vector:word_to_count[term[0]] = term[1]
print(word_to_count)
#对于任意句子
sentence = 'this is cool'
#分词
tokens = nltk.word_tokenize(sentence)
sentence_vector = []
for word in tokens:sentence_vector.append(word_to_count.get(word,0))

3、TF-IDF

单用频率表示,无法真实表达出词在该文本中的重要性,如某些公有词虽然在文本中出现的次数多,可能在整个语料库中都出现很多。
(1)TF: Term Frequency, 衡量⼀个term在⽂档中出现得有多频繁。
TF(t) = (t出现在⽂档中的次数) / (⽂档中的term总数)。
(2)IDF: Inverse Document Frequency, 衡量⼀个term有多重要。有些词出现的很多,但是明显不是很有卵⽤。⽐如’is’,’the‘,’and‘之类
的。为了平衡,我们把罕见的词的重要性(weight)搞⾼,把常见词的重要性搞低。
IDF(t) = log_e(⽂档总数 / 含有t的⽂档总数).
(3)TF−IDF=TF∗IDFTF-IDF = TF * IDFTFIDF=TFIDF
(4)例子:

现在有10M的文档,baby出现在其中的1000个文档中。
IDF(baby) = log(10000000/1000) = 4
那么来了一个文档有100个单词,其中单词baby出现3次。
TF(baby) = (3/100) = 0.03
所以,TF-IDF(baby) = TF(baby) * IDF(baby) = 0.03 * 4 = 0.12

(5)代码实现

from nltk.text import TextCollection
#首先, 把所有的⽂文档放到TextCollection类中。
#这个类会⾃自动帮你断句句, 做统计, 做计算
corpus = TextCollection(['this is sentence one','this is sentence two','this is sentence three'])
#直接就能算出tfidf
#(term:一句话中的某个term,text:这句话)
print(corpus.tf_idf('this','this is sentence four'))

五、NLP经典案例

1、情感分析

案例一:简单的情感词字典

(1)介绍
一句话分词后通过情感词字典,对每个词进行打分,最后得出句子情感得分。例如:like:1,good:2,bad:-2,terrible:-3。这代表着like的情感正面程度分值为1,good的情感正面程度为2,bad的情感正面程度为-2,terrible的情感正面程度为-3。
AFINN-111就是一个典型的情感字典:http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6010
下载后如图:

(2)使用NLTK完成简单的情感分析代码实现:

#NLTK进行情感分析
import nltk#建立情感字典
sentiment_dictionary ={}
for line in open('you_file\AFINN-111.txt'):word,score = line.split(' ')sentiment_dictionary[word] = int(score)  #构建{单词:得分}字典sentence_1 ='i love you!'
sentence_2 ='i hate you!'
#分词
word_list1 = nltk.word_tokenize(sentence_1)
word_list2 = nltk.word_tokenize(sentence_2)
#遍历每个句子,把每个词的情感得分相加,不在情感字典中的词分数全部置0
s1_score = sum(sentiment_dictionary.get(word,0) for word in word_list1)
s2_score = sum(sentiment_dictionary.get(word,0) for word in word_list2)
print('我是句子'+sentence_1+'的正面情感得分:',s1_score)
print('我是句子'+sentence_2+'的正面情感得分:',s2_score)

输出结果:
我是句子i love you!的正面情感得分:3
我是句子i hate you!的正面情感得分:-3
(3)存在的问题:

  • 出现网络新词不在字典里怎么办?
  • 出现特殊词汇怎么办?
  • 更深层的语义怎么理解?

案例二:配上ML的情感分析

from nltk.classify import NaiveBayesClassifier
from nltk import word_tokenize
#简单手造的训练集
s1 = 'i am a good boy'
s2 = 'i am a handsome boy'
s3 = 'he is a bad boy'
s4 = 'he is a terrible boy'#预处理后得到字典类型:
#key表示fname对应句子中出现的单词
#value表示每个文本单词对应的值
def preprocess(s):return {word:True for word in s.lower().split()}#把训练集做成标准形式
training_data = [[preprocess(s1),'pos'],[preprocess(s2),'pos'],[preprocess(s3),'neg'],[preprocess(s4),'neg'],]#采用朴素贝叶斯模型训练
model = NaiveBayesClassifier.train(training_data)
new_s1 = 'i am a good girl'
new_s2 = 'she is a terrible girl'
#输出预测结果
print('我在预测 '+new_s1+' 结果是:',model.classify(preprocess(new_s1)))
print('我在预测 '+new_s2+' 结果是:',model.classify(preprocess(new_s2)))

输出结果:
我在预测 i am a good girl 结果是: pos
我在预测 she is a terrible girl 结果是: neg

2、文本相似度

在句子被向量化后,我们根据余弦定理便可计算出句子的相似度
similarity=cos(θ)=A⋅B∥A∥⋅∥B∥\displaystyle similarity=cos( \theta ) =\frac{A\cdot B}{\| A\| \cdot \| B\| }similarity=cos(θ)=ABAB

3、文本分类

文本表示称为向量后,通过及其学习模型,对分类任务进行预测。

五、深度学习文本表示:让机器去学习句子表达向量,而不是人为的规定特征

1、词向量表示工具:

gensim:word2vec、tensorflow

2、词编码:

英文、ASII编码(英文)、Unicode中文、自定义一个index编码、电报编码等,在进行深度学习时,输入的词约原始越好。

3、词向量表达方式

(1)Auto-Encoder
无监督学习,工业上主要用于降维。

**(2)Word2vec:**单词本身不是单独存在于句子中间的,而是由周围的词决定。

4、文本相似度的表示:

(1)Full document: TF-IDF
(2)Window: co-occurrence matrix + SVD(2个单词都出现的矩阵计算)不光关注在文章中出现的频率,重点关注词与词之间的相关性
a.贡献计数表

b.构建SVD矩阵:把任何形状的矩阵, 都转化为三个向量相乘的矩阵。个性特征:每一行代表自己的特有特征

c.将特征值取出,放在空间平面里。做词向量表达

应为SVD计算复杂度很高,所以想到用两边定义中间的形式,去表达。

5、Word2vec

(1)Skip-gram:数据量少,经常出现稀有单词时适合使用

(2)CBOW:比Skip-gram快,对于高频词的预测精度高


(3)步骤:

  • 文本预处理:去停用词、小写化、用正则表达式去除特殊符号或文本。进行分词。文本处理后的形式,输入到Word2Vec中:[[‘hello’, ‘how’], [‘fine’, ‘thank’]]
  • 文本表示
    1)使用from gensim.models import word2vec库;
    2)设定参数(num_features最多多少个不不同的features、min_word_count⼀一个word,最少出现多少次 才被计⼊入、多少thread⼀一起跑(快⼀一点⼉儿)、embeding_size、windom_size前后观察多⻓长的“语境)
    3)跑模型。生成每个次的词向量
model = word2vec.Word2Vec(sentences, size=size, workers=num_workers, size=num_features, min_count = min_word_count, window = window)

(4)应用:

  • 输出单词在空间中的位置向量。词向量表示
model['computer']

输出:
array([-0.00449447, -0.00310097, 0.02421786, …], dtype=float32)

  • 求两个词的senmatics相似度
model.similarity('woman', 'man')

输出:0.73723527

  • 通过语义,利用空间距离计算。单词和概率。
#woman + king - man = queen
model.most_similar(positive=['woman', 'king'], negative=['man'])

输出:
[(‘queen’, 0.50882536), …]

六、机器人应用:intents


“你好吗?”——>向量,“你最近怎么样”——>向量
通过word2vec、tf-idf等形式,把句子把句子表达为向量形式。
无监督学习:KNN做聚类,计算两个句子的距离是否小于某个阈值,如果小于则认为属于一类,可以使用同一个回答
有监督学习:分类问题。
根据网上的语料库,输入词向量,确定它属于那个标签。

七、思考:

这个时候你会发现,我们的vec是针对每个word的。而我们的训练集是sen和label互相对应的,
工业上,到了这一步,有三种解决方案:
1、平均化一个句子里所有词的vec。
sen_vec = [vec, vec, vec, …] / n
2、排成一个大matrix (M * N),等着CNN进行特征提取。
[ vec | vec | vec | vec | … ]
3、用Doc2Vec。这是基于句子的vec,跟word2vec差不多思路路,用起来也差不多。
只对长篇 大文章效果好。对头条新闻,twitter这种的东西,就不行了。每一篇的就太少。
具体可以看gensim。

参考文献:文本为七月在线《自动聊天机器人项目班》学习笔记

【聊天机器人】NLP知识相关推荐

  1. 构建属于自己的“聊天机器人”——NLP系列

    全文共2807字,预计学习时长9分钟 图源:pexels 前段时间上映的日剧<轮到你了>在网络掀起了不少热议,高起低落.烂尾嫌疑令人感到一丝遗憾,但也难以掩盖其剧情的精彩.这部片子融合了很 ...

  2. 聊天机器人技术分析综述

    研究背景及发展现状 1950年图灵(Alan M. Turing)在<Mind>上发表文章<Computing Machinery and Intelligence>,文章开篇 ...

  3. 2020最新智能客服|聊天机器人算法、架构及应用分享

    智能客服(聊天机器人)是在大规模知识处理基础上发展起来的一项面向行业应用的,适用大规模知识处理.自然语言理解.知识管理.自动问答系统.推理等等技术行业,智能客服不仅为企业提供了细粒度知识管理技术,还为 ...

  4. 行业内关于智能客服、聊天机器人的应用和架构、算法分享和介绍

    更多精品内容及源码,尽在"源码大数据" 阿里巴巴 小蜜 阿里小蜜新一代智能对话开发平台技术解析 阿里小蜜:知识结构化推动智能客服升级 阿里云小蜜对话机器人背后的核心算法 大中台.小 ...

  5. python开源聊天机器人ChatterBot——聊天机器人搭建、流程分析、源码分析

    开源聊天机器人ChatterBot 3.1  ChatterBot简介 ChatterBot是一个Python库,可以轻松生成对用户输入的自动响应.ChatterBot使用一系列机器学习算法来产生不同 ...

  6. ChatterBot+第三方中文语料库实现在线聊天机器人

    设计并实现一个在线聊天机器人案例 1.ChatterBot ChatterBot是Python自带的基于机器学习的语音对话引擎,可以基于已知的对话库来产生回应.ChatterBot独特的语言设计可以使 ...

  7. 吴恩达家免费 NLP 课程重磅上线!110 个小视频教你做出聊天机器人,粉丝:我要让娃跟吴恩达姓!...

    郭一璞 发自 凹非寺 量子位 报道 | 公众号 QbitAI 朋友们,又有新课可以白嫖了 昨天晚上,吴恩达宣布DeepLearning.ai的NLP(自然语言处理)课程在Coursera上线了. 目前 ...

  8. 【NLP实战】如何基于Tensorflow搭建一个聊天机器人

    实战是学习一门技术最好的方式,也是深入了解一门技术唯一的方式.因此,NLP专栏计划推出一个实战专栏,让有兴趣的同学在看文章之余也可以自动动手试一试. 本篇介绍如何基于tensorflow快速搭建一个基 ...

  9. 【每周NLP论文推荐】 生成式聊天机器人论文介绍

    欢迎来到<每周NLP论文推荐>.在这个专栏里,还是本着有三AI一贯的原则,专注于让大家能够系统性完成学习,所以我们推荐的文章也必定是同一主题的. 生成式聊天机器人是研究的热点,现在看来,通 ...

最新文章

  1. MFC给按钮添加皮肤
  2. IOS8中SWIFT 弹出框的显示
  3. 贾君鹏你妈妈喊你回家吃饭
  4. .NET Core性能测试组件BenchmarkDotNet 支持.NET Framework Mono
  5. linux多进程通过中断实现,Linux驱动中断上下文中会发生什么结果实验测试
  6. python3.7代码转python2.7_Python3.7与Python2.7在centos7下兼容并存
  7. 最新!2020世界一流大学学术排名出炉!
  8. 20170721L08-02-02老男孩Linux运维实战培训初级第八节课课前【上机实战】考试讲解...
  9. 【Kafka】Kafka客户端分配方案
  10. 《Java从入门到放弃》框架入门篇:hibernate中的多表对应关系(二)
  11. MySQL:Specified key was too long; max key length is 1000 bytes
  12. Document/View 模式下的窗口重绘
  13. 从github下载的项目如何运行??---------本文以vue的项目为例
  14. 会扫地炒菜,将来机器人当钟点工
  15. 论文查重前应删掉哪些内容?
  16. 【笑爆肚子的超级冷笑话】
  17. Mycat全局序列号失效的诡异事件
  18. 深度调查:危险的“360安全卫士”!
  19. 专科出身,2年进入苏宁,5年跳槽阿里,论我是怎么快速晋升的?
  20. python斐波拉契数列(Fibonacci)

热门文章

  1. 日本推出《进击的巨人VR》线下体验|互联网行业公会
  2. 1108: 爱管闲事的晶晶
  3. Cocos2d使用TexturePacker工具打包生成plist和pvr.ccz文件方法总结
  4. 高效好用的bi数据分析工具
  5. c语言编程小练习-九九乘法表
  6. 二分搜索树--二叉树
  7. 【OS】IO系统——设备管理
  8. URL转二维码,图片
  9. 地级市个人所得税(2010-2019年)
  10. RB521C30-2/TR肖特基势垒二极管WILLSEM封装SOD923