文章目录
Lesson-04
- jieba分词的实现也是
Edit distance
NLP的涉及方向:
- Words :单词相关, jieba分词,用为比特方法,也是一种动态规划
- Entity:类似把人名,地点从一大丢数据中找出来,可以用jieba分词来做,把单词对应到类型
- Syntax 语法:根据规律结构来处理,只要是格式解析方面的问题,就属于这方面的处理
- Semantic 语意 :比如判断客服语言有没有骂人或讽刺,比如他说中的他指的是谁,
- Dialogue:对话,包括闲聊,或解决问题问答,例如客服机器人
- Reading Comprehension : 阅读理解,比如从文章或数据中找出,xx出生于哪一年的答案,目前还不成熟,比较复杂,难
- Generation : 生成文章,可以拓展为,语义分析+生成,把一篇文章精简
- Representation :
NLP遇到的问题
- 信息杂乱,有用的信息在混乱的数据中,
- NLP问题很难用特定的结构或格式来表示
- NLP问题一般都是离散的
- NLP问题没有一种规范,比如某个单词在不同时间地点,表达的含义是不一样的
- NLP经常会出现OOV问题,即out of Vocabulary
Word2Vec
https://www.jianshu.com/p/471d9bfbd72f
https://blog.csdn.net/u010327784/article/details/80927207
Edit distance
用编辑距离来判断相似度只能判断长的像与否,而不能判断语句的意思是否相似
词向量表示方法:
categorical:
PCA
降维,高密度表示方法
How do we get PCA: https://www.wikiwand.com/en/Principal_component_analysis
SVD
SVD降维方法
How do we get SVD: https://www.wikiwand.com/en/Singular-value_decomposition
词向量需要解决的问题:
Word2Vec表示方法
you shall kNow the words by the company it keeps
如果两个单词,它们周围出现的单词都比较接近,那么这两个单词应该是类似的
Word Embedding:
把一个单词或向量投影到另一个空间,又保存词的相似特点,这种操纵叫做embedding、
v1(1×100)⋅M(100×10000)=V11v2(1×100)⋅M(100×10000)=V21
例子:
好看随机用一个v1向量来表示
美丽随机用一个v2向量来表示
M也是一个随机矩阵
将得到的V11 和V22进行softmax处理
y1,y2,y3=softmax(o1,o2,o3)y1=∑exp(oi)exp(o1)y2=∑exp(oi)exp(o2)y3=∑exp(oi)exp(o3)
将处理过的V11,V22进行人工干预:
假设美丽周围的是ABC,我们将美丽周围所有的词随机进行个排序,假设排序结果是ABC…,那么新的V11向量的第一,第二个,第三个元素代表ABC,那么我们希望这3个元素的值最大,假设为1。(因为ABC是在美丽周围,所以我们希望ABC代表的元素值大,这样来表式新的V11)
人工干预的时候我们确定了期望输出,类似地需要学习,不断更新v1, M来使得输出V11是我们的期望输出
以上的算法属于 Word2Vec方法的skip_gram方法
Word2Vec还有一种实现方法cbow
Skip-Grim实例
从直观上理解,Skip-Gram是给定input word来预测上下文。
接下来我们来看看如何训练我们的神经网络。假如我们有一个句子“The dog barked at the mailman”。
首先我们选句子中间的一个词作为我们的输入词,例如我们选取“dog”作为input word;
有了input word以后,我们再定义一个叫做skip_window的参数,它代表着我们从当前input word的一侧(左边或右边)选取词的数量。如果我们设置skip_window=2,那么我们最终获得窗口中的词(包括input word在内)就是[‘The’, ‘dog’,‘barked’, ‘at’]。skip_window=2代表着选取左input word左侧2个词和右侧2个词进入我们的窗口,所以整个窗口大小span=2x2=4。另一个参数叫num_skips,它代表着我们从整个窗口中选取多少个不同的词作为我们的output word,当skip_window=2,num_skips=2时,我们将会得到两组 (input word, output word) 形式的训练数据,即 (‘dog’, ‘barked’),(‘dog’, ‘the’)。
神经网络基于这些训练数据将会输出一个概率分布,这个概率代表着我们的词典中的每个词是output word的可能性。这句话有点绕,我们来看个栗子。第二步中我们在设置skip_window和num_skips=2的情况下获得了两组训练数据。假如我们先拿一组数据 (‘dog’, ‘barked’) 来训练神经网络,那么模型通过学习这个训练样本,会告诉我们词汇表中每个单词是“barked”的概率大小。
模型的输出概率代表着到我们词典中每个词有多大可能性跟input word同时出现。举个栗子,如果我们向神经网络模型中输入一个单词“中国“,那么最终模型的输出概率中,像“英国”, ”俄罗斯“这种相关词的概率将远高于像”苹果“,”蝈蝈“非相关词的概率。因为”英国“,”俄罗斯“在文本中更大可能在”中国“的窗口中出现。我们将通过给神经网络输入文本中成对的单词来训练它完成上面所说的概率计算。
面的图中给出了一些我们的训练样本的例子。我们选定句子“The quick brown fox jumps over lazy dog”,设定我们的窗口大小为2(window_size=2),也就是说我们仅选输入词前后各两个词和输入词进行组合。下图中,蓝色代表input word,方框内代表位于窗口内的单词。Training Samples(输入, 输出)
我们的模型将会从每对单词出现的次数中习得统计结果。例如,我们的神经网络可能会得到更多类似(“中国“,”英国“)这样的训练样本对,而对于(”英国“,”蝈蝈“)这样的组合却看到的很少。因此,当我们的模型完成训练后,给定一个单词”中国“作为输入,输出的结果中”英国“或者”俄罗斯“要比”蝈蝈“被赋予更高的概率。
实例:
STPE1
Download Wikipedia Chinese Corpus: https://dumps.wikimedia.org/zhwiki/20190720/
STEP2
Using https://github.com/attardi/wikiextractor to extract the wikipedia corpus
- WikiExtractor安装参考 https://blog.csdn.net/sinat_29957455/article/details/81432846
- WikiExtractor 使用提取
- 中文简体和繁体的转换 OpenCC的使用教程请参考:<https://blog.csdn.net/sinat_29957455/article/details/81290356
WikiExtractor提取的文本格式如下:
<doc id="4538754" url="https://zh.wikipedia.org/wiki?curid=4538754" title="成本华">
成本华
成本华(),為安徽省和县人,祖籍山东省;她於1937年末參與中国抗日战争,在翌年被俘,並遭到日軍强奸和殺害。
</doc>
需要对其进行清洗并用jieba分词处理,具体代码如下:
import jieba
import re
def token(string):
return re.findall('\w+', string)
def jieba_deal(orign_file, save_file):
file = open(orign_file,"r",encoding='utf-8')
output = open(save_file,"w+",encoding='utf-8')
content_line = file.readline()
while content_line != '':
#print(content_line[:10])
if content_line.startswith('<doc id'):
#print(content_line)
ss = ''
content_line = file.readline()
content_line = file.readline()
if content_line.startswith('</doc>'):
ss = ss.strip()
ss = ''.join(token(str(ss))) #清洗标点或其他符号,保留存文本
words = jieba.cut(ss)
content = ''
for word in words:
content += word + ' '
output.write(content+"\n") #每篇文章内容用换行符分隔
ss += content_line.strip('\n')
content_line = file.readline()
file.close()
output.close()
处理过得到的文件如下:
笔者在这里把每一篇文章切词好存为一行,因为后边进行gensim训练导入初始文本用的是word2vec.Linesentence函数
处理完后用OpenCC进行繁体字转简体字处理下
STEP3
Using gensim get word vectors:
用word2vec.Linesentence进行文件读取,也可以以其它方式,具体见gesim官方手册
训练好的model直接用model.wv类里的方法来进行读取等操作,会更快
Reference:
代码如下:
from gensim.models import word2vec
from gensim.models import Word2Vec
import logging
logging.basicConfig(format="%(asctime)s:%(levelname)s:%(message)s",level=logging.INFO)##为了显示当前进度
sentences = word2vec.Linesentence(file_path) #file_path为处理好的文本路径
model = Word2Vec(sentences, size=250, window=5, min_count=1, workers=4, sg =1)
model.save("word2vec.model")
- 放入云GPU服务器上计算
- 利用百度AI Stdio
- 安装gensim不用pip安装,改用conda安装
conda install scipy
conda install numpy
conda gensim
STEP4
测试下两个词的近似度:
# #输入两个词计算相似度
two_corpus = ["腾讯","阿里巴巴"]
res = model.similarity(two_corpus[0],two_corpus[1])
print("similarity:%.4f"%res)
#similarity:0.6861
可视化,可以用T-SEN或wordcloud进行可视化
关于matplotlib不能显示中文的问题:
plt.rcParams[‘font.sans-serif’]=[‘SimHei’] #用来正常显示中文标签
plt.rcParams[‘axes.unicode_minus’]=False #用来正常显示负号
要保证Anaconda\Lib\site-packages\matplotlib\mpl-data\fonts\ttf目录下有SimHei字体文件
Reference:
TSNE代码如下
import pandas as pd
pd.options.mode.chained_assignment = None
import numpy as np
import re
import nltk
from gensim.models import word2vec
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt
%matplotlib inline
def tsne_plot(model, word):
"Creates and TSNE model and plots it, only choose top 300 word that most similarer to parameter:word"
labels = []
tokens = []
result = model.wv.most_similar(word,topn=300)
for each in result:
tokens.append(model[each[0]])
labels.append(each[0])
#全部导入数据太大,内存不够,画不出来
#for word in model.wv.vocab:
# tokens.append(model[word])
# labels.append(word)
tsne_model = TSNE(perplexity=40, n_components=2, init='pca', n_iter=2500, random_state=23)
new_values = tsne_model.fit_transform(tokens)
x = []
y = []
for value in new_values:
x.append(value[0])
y.append(value[1])
plt.figure(figsize=(16, 16))
for i in range(len(x)):
plt.scatter(x[i],y[i])
plt.annotate(labels[i],
xy=(x[i], y[i]),
xytext=(5, 2),
textcoords='offset points',
ha='right',
va='bottom')
plt.show()
Wordcloud代码如下:
import numpy as np
import matplotlib.pyplot as plt
from wordcloud import WordCloud
'''
获取一个圆形的mask
'''
def get_mask():
x,y = np.ogrid[:300,:300]
mask = (x-150) ** 2 + (y-150)**2 > 130 ** 2
mask = 255 * mask.astype(int)
return mask
'''
绘制词云
'''
def draw_word_cloud(word_cloud):
wc = WordCloud(background_color="white",font_path = font,mask= get_mask())
wc.generate_from_frequencies(word_cloud)
#隐藏x轴和y轴
plt.figure(figsize=(15,15))
plt.axis("off")
plt.imshow(wc,interpolation="bilinear")
plt.show()
one_corpus = ["人工智能"]
result = model.wv.most_similar(one_corpus[0],topn=100)
word_cloud = dict()
for sim in result:
# print(sim[0],":",sim[1])
word_cloud[sim[0]] = sim[1]
#绘制词云
draw_word_cloud(word_cloud)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。