欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

自然语言处理环境搭建流程

程序员文章站 2023-12-24 12:17:45
...

1、需要安装的库:

          **pip install   gensim**
          **pip install  tensorflow**
          **pip install  scipy**
          **pip  install jieba**

2、关于数据的解压

首先我们需要下载:*中文数据。一 、*(Wikipedia),是一个基于维基技术的多语言百科全书协作计划,也是一部用不同语言写成的网络百科全书。*是由吉米·威尔士与拉里·桑格两人合作创建的,于2001年1月13日在互联网上推出网站服务,并在2001年1月15日正式展开网络百科全书的项目。中文*数据按月进行更新备份,一般情况下,下载当前最新的数据,下载地址:https://dumps.wikimedia.org/zhwiki/latest/。下载下来的数据是压缩文件(bz2,gz),需要进行解压,利用process_wiki.py。在终端 python 输入python process_wiki.py zhwiki-latest-pages-articles.xml.bz2 Test.txt,将下载的zhwiki-latest-pages-articles.xml.bz2,转换为:Test.txt。

# -*- coding:utf-8 -*-
# Author:Gao
import logging
import os.path
import six
import sys
import warnings

warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim')
from gensim.corpora import WikiCorpus

if __name__ == '__main__':
    program = os.path.basename(sys.argv[0])
    logger = logging.getLogger(program)

    logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s')
    logging.root.setLevel(level=logging.INFO)
    logger.info("running %s" % ' '.join(sys.argv))

    # check and process input arguments
    if len(sys.argv) != 3:
        print("Using: python process_wiki.py enwiki.xxx.xml.bz2 wiki.en.text")
        sys.exit(1)
    inp, outp = sys.argv[1:3]
    space = " "
    i = 0

    output = open(outp, 'w',encoding='utf-8')
    wiki = WikiCorpus(inp, lemmatize=False, dictionary={})
    for text in wiki.get_texts():
        # if six.PY3:
        #     output.write(b' '.join(text).decode('utf-8') + '\n')      
        # else:
        #     output.write(space.join(text) + "\n")
        output.write(space.join(text) + "\n")
        i=i+1
        if (i%10000==0):
            logger.info("Saved " + str(i) + " articles")

    output.close()
    logger.info("Finished Saved " + str(i) + " articles")

3、繁体字转换为简体字

OpenCC第三方库,是中文字符转换,包括中文简体繁体相互转换等。安装在:D:\install\opencc\opencc-1.0.1-win64
Configurations配置文件
解压之后在opencc中的opencc中有需要的json文件就是opencc的配置文件,用来制定语言类型的转换。
自然语言处理环境搭建流程
我们利用test.py 将解压的文本打印以下:

import codecs,sys
#将繁体转化为简体后的文本打印出来
f=codecs.open('D:\\install\\opencc\\WordToVector\\Test\\Test.txt','r',encoding="utf8")
line=f.readline()
print(line)

终端定位到:D:\install\opencc\opencc-1.0.1-win64:
运行:#opencc -i Test.txt -o Test_jian.txt -c t2s.json,将繁体字化简为简体字。

自然语言处理环境搭建流程

4、利用jieba对文本进行分词

#将转换的简体文字进行分词
import jieba
import jieba.analyse
import jieba.posseg as pseg
import codecs,sys
def cut_words(sentence):
    #print sentence
    return " ".join(jieba.cut(sentence)).encode('utf-8')#利用空格将每个词分开
f=codecs.open('D:\\install\\opencc\\opencc-1.0.1-win64\\Test_jian.txt','r',encoding="utf8")#输入简体文档,进行读取操作
target = codecs.open("Test_jian_jieba.txt", 'w',encoding="utf8")#输出的文件,进行写入操作
print ('open files')
line_num=1
line = f.readline()#读取每行文本
#如果每行有内容
while line:
    print('---- processing ', line_num, ' article----------------')
    line_seg = " ".join(jieba.cut(line))#对每行进行切分
    target.writelines(line_seg)#将切分的部分写入文档
    line_num = line_num + 1
    line = f.readline()
f.close()
target.close()
exit()
while line:
    curr = []
    for oneline in line:
        #print(oneline)
        curr.append(oneline)
    after_cut = map(cut_words, curr)
    target.writelines(after_cut)
    print ('saved',line_num,'articles')
    exit()
    line = f.readline1()
f.close()
target.close()

模型验证(Word2Vec)

word2vec工具主要包含两个模型:跳字模型(skip-gram)和连续词袋模型(continuous bag of words,简称CBOW),以及两种高效训练的方法:负采样(negative sampling)和层序softmax(hierarchical softmax)。值得一提的是,word2vec词向量可以较好地表达不同词之间的相似和类比关系。
NLP 的问题,首先就要拿词语开刀。词语,是人类的抽象总结,是符号形式的(比如中文、英文、拉丁文等等),所以需要把他们转换成数值形式,或者说——嵌入到一个数学空间里,这种嵌入方式,就叫词嵌入(word embedding),而 Word2vec,就是词嵌入( word embedding) 的一种。简单点来说就是把一个词语转换成对应向量的表达形式,来让机器读取数据。
统计语言模型给出了这一类问题的一个基本解决框架。对于一段文本序列S=w1,w2,…,wT,它的概率可以表示为:
p(S)=p(w1,w2,w3,w4,w5,…,wt)
=p(w1)p(w2|w1)p(w3|w1,w2)…p(wt|w1,w2,…,wt-1)

即将序列的联合概率转化为一系列条件概率的乘积。问题变成了如何去预测这些给定previous words下的条件概率p(wt|w1,w2,…,wt−1)。常见的统计语言模型有N元文法模型(N-gram Model)

基于马尔科夫假设(Markov Assumption):下一个词的出现仅依赖于它前面的一个或几个词
假设下一个词的出现依赖它前面的一个词,则有:
p(S)=p(w1)p(w2|w1)p(w3|w1,w2)…p(wn|w1,w2,…,wn-1)
=p(w1)p(w2|w1)p(w3|w2)…p(wn|wn-1) // bigram
假设下一个词的出现依赖它前面的两个词,则有:
p(S)=p(w1)p(w2|w1)p(w3|w1,w2)…p(wn|w1,w2,…,wn-1)
=p(w1)p(w2|w1)p(w3|w1,w2)…p(wn|wn-1,wn-2) // trigram
那么,我们在面临实际问题时,如何选择依赖词的个数,即n
更大的n:对下一个词出现的约束信息更多,具有更大的辨别力;
更小的n:在训练语料库中出现的次数更多,具有更可靠的统计信息,具有更高的可靠性。
理论上,n越大越好,经验上,trigram用的最多,尽管如此,原则上,能用bigram解决,绝不使用trigram。

NLP词的表示方法类型

词的独热表示one-hot
比如我们有5个词组成的词汇表,词"Queen"在词汇表中的序号为2, 那么它的词向量就是(0,1,0,0,0)。同样的道理,词"Woman"是序号3,词向量就是(0,0,1,0,0)。这种词向量的编码方式我们一般叫做one hot representation.
One hot representation用来表示词向量非常简单,但是却有很多问题。1、任意两个词之间都是孤立的,根本无法表示出在语义层面上词语词之间的相关信息,而这一点是致命的。2、我们的词汇表一般都非常大,比如达到百万级别,这样每个词都用百万维的向量来表示简直是内存的灾难。能不能把词向量的维度变小呢?
词的分布式表示 distributed representation
Dristributed representation可以解决One hot representation的问题,它的思路是通过训练,将每个词都映射到一个较短的词向量上来所有的这些词向量就构成了向量空间,进而可以用普通的统计学的方法来研究词与词之间的关系。这个较短的词向量维度是多大呢?这个一般需要我们在训练时自己来指定。
词的分布式表示主要可以分为三类:基于矩阵的分布表示、基于聚类的分布表示和基于神经网络的分布表示
我们就需要训练神经网络语言模型,即CBOW和Skip-gram模型。这个模型的输出我们不关心,我们关心的是模型中第一个隐含层中的参数权重,这个参数矩阵就是我们需要的词向量它的每一行就是词典中对应词的词向量,行数就是词典的大小。
自然语言处理环境搭建流程
公式咱们就不放了,网络计算的步骤:
输入层:上下文单词的onehot。(假设单词向量空间dim为V(词向量的维度),上下文单词个数为C)
所有onehot分别乘以共享的输入权重矩阵W(VN矩阵,N为自己设定的数,初始化权重矩阵W)
所得的向量 (注意onehot向量乘以矩阵的结果) 相加求平均作为隐层向量, size为1
N.
乘以输出权重矩阵W’ {NV}
得到向量 {1
V} **函数处理得到V-dim概率分布 {PS: 因为是onehot嘛,其中的每一维都代表着一个单词},概率最大的index所指示的单词为预测出的中间词(target word)
与true label的onehot做比较,误差越小越好。loss function(一般为交叉熵代价函数)

negative sampling 每次让一个训练样本仅仅更新一小部分的权重参数,从而降低梯度下降过程中的计算量。
如果 vocabulary 大小为1万时, 当输入样本 ( “fox”, “quick”) 到神经网络时, “ fox” 经过 one-hot 编码,在输出层我们期望对应 “quick” 单词的那个神经元结点输出 1,其余 9999 个都应该输出 0。在这里,这9999个我们期望输出为0的神经元结点所对应的单词我们为 negative word. negative sampling 的想法也很直接 ,将随机选择一小部分的 negative words,比如选 10个 negative words 来更新对应的权重参数。
在论文中作者指出指出对于小规模数据集建议选择 5-20 个 negative words,对于大规模数据集选择 2-5个 negative words.
如果使用了 negative sampling 仅仅去更新positive word- “quick” 和选择的其他 10 个negative words 的结点对应的权重,共计 11 个输出神经元,相当于每次只更新 300 x 11 = 3300 个权重参数。对于 3百万 的权重来说,相当于只计算了千分之一的权重,这样计算效率就大幅度提高。

相关标签: 自然语言处理

上一篇:

下一篇: