深度学习与自然语言处理第四次作业——词向量聚类问题

深度学习与自然语言处理第四次作业——词向量聚类问题

利用神经语言模型,训练词向量,通过对词向量的聚类或者其他方法来验证词向量的有效性。



一、解题背景

利用给定语料库(或者自选语料库),利用神经语言模型(如:Word2Vec, GloVe等模型)来训练词向量,通过对词向量的聚类或者其他方法来验证词向量的有效性。


二、解题原理

1、词向量

自然语言处理相关任务中要将自然语言交给机器学习中的算法来处理,通常需要将语言数学化,因为机器不是人,机器只认数学符号。向量是人把自然界的东西抽象出来交给机器处理的东西,基本上可以说向量是人对机器输入的主要方式了。
词向量就是用来将语言中的词进行数学化的一种方式,顾名思义,词向量就是把一个词表示成一个向量。 我们都知道词在送到神经网络训练之前需要将其编码成数值变量,常见的编码方式有两种:One-Hot Representation 和 Distributed Representation。

2、Word2Vec模型原理

Word2vec,是一群用来产生词向量的相关模型。这些模型为浅而双层的神经网络,用来训练以重新建构语言学之词文本。网络以词表现,并且需猜测相邻位置的输入词,在word2vec中词袋模型假设下,词的顺序是不重要的。训练完成之后,word2vec模型可用来映射每个词到一个向量,可用来表示词对词之间的关系,该向量为神经网络之隐藏层。
Word2Vec主要包括CBOW模型(连续词袋模型)和Skip-gram模型(跳字模型)
本文主要使用的模型为CBOW模型,​ 给定一个长度为 T T T的文本序列,设时间步的词为 W ( t ) W(t) W(t),背景窗口大小为 m m m。则连续词袋模型的目标函数(损失函数)是由背景词生成任一中心词的概率。
∑ t = 1 T P ( w ( t ) ∣ w ( t − m ) , . . . , w ( t − 1 ) , w ( t + 1 ) , . . . , w ( t + m ) ) \sum_{t=1}^{T}P(w^{(t)}|w^{(t-m)},...,w^{(t-1)},w^{(t+1)},...,w^{(t+m)}) t=1TP(w(t)w(tm),...,w(t1),w(t+1),...,w(t+m))

三、实验分析

1.语料处理

在读取语料后,首先利用jieba分词对语料进行分词,去掉txt文本中一些无意义的广告和标点符号等内容,并将处理后的语料重新保存进新的文件夹中。
在实验过程中,注意到某些无关词语会在结果中出现,因此在进行语料处理时,去掉一些无关词语(例如,“我”、“你”、“他”、“她”、“它”等

代码如下(语料处理):

def read_novel(path_in, path_out):  # 读取语料内容
    content = []
    names = os.listdir(path_in)
    for name in names:
        novel_name = path_in + '\\' + name
        fenci_name = path_out + '\\' + name
        for line in open(novel_name, 'r', encoding='ANSI'):
            line.strip('\n')
            line = re.sub("[A-Za-z0-9\:\·\—\,\。\“\”\\n \《\》\!\?\、\...]", "", line)
            line = content_deal(line)
            con = jieba.cut(line, cut_all=False) # 结巴分词
            # content.append(con)
            content.append(" ".join(con))
        with open(fenci_name, "w", encoding='utf-8') as f:
            f.writelines(content)
    return content, names


def content_deal(content):  # 语料预处理,进行断句,去除一些广告和无意义内容
    ad = ['本书来自www.cr173.com免费txt小说下载站\n更多更新免费电子书请关注www.cr173.com', '----〖新语丝电子文库(www.xys.org)〗', '新语丝电子文库',
          '\u3000', '\n', '。', '?', '!', ',', ';', ':', '、', '《', '》', '“', '”', '‘', '’', '[', ']', '....', '......',
          '『', '』', '(', ')', '…', '「', '」', '\ue41b', '<', '>', '+', '\x1a', '\ue42b', '她', '他', '你', '我', '它', '这'] #去掉其中的一些无意义的词语
    for a in ad:
        content = content.replace(a, '')
    return content

2.模型训练

使用开源的Gensim库提供的接口来训练Word2vec模型,调用的函数如下:
Word2Vec(sentences=LineSentence(name), hs=1, min_count=10, window=5, vector_size=200, sg=0, epochs=200)
其中的参数的含义为:

  • sentences:可以是一个list,对于大语料集,建议使用BrownCorpus,Text8Corpus或LineSentence构建;
  • hs: 如果为1则会采用hierarchical softmax技巧。如果设置为0(defaut),则negative sampling会被使用;
  • min_count: 可以对字典做截断,词频少于min_count次数的单词会被丢弃掉, 默认值为5,这里的值为10。
  • window:表示当前词与预测词在一个句子中的最大距离是多少,这里为5;
  • vector_size:是指特征向量的维度,默认为100;
  • sg: 用于设置训练算法,默认为0,对应CBOW算法;sg=1则采用skip-gram算法;
  • epochs:迭代次数,默认为5。这里的参数不是iter,官方在新的版本中将这个关键词改为了epochs,使用iter会报错。

3、聚类分析

模型训练完毕之后,通过Gensim库中给出的接口函数(例如,most_similar(),similarity()等),输出训练之后的模型,与某个给定输入词关联度最高的词或者是给定的某两个词之间的关联性。

我选择了金庸小说集中我较为了解的五本小说《倚天屠龙记》、《天龙八部》、《射雕英雄传》、《神雕侠侣》、《笑傲江湖》作为样本,对其中的主角、门派分别进行了聚类分析。

代码如下(聚类分析):

if __name__ == '__main__':   ##
    [data_txt, files] = read_novel("金庸小说集", "output")
    #[data_txt, files] = read_novel("倚天屠龙记", "output")
    #model = Word2Vec(data_txt, vector_size=400, window=5, min_count=5, epochs=200, workers=multiprocessing.cpu_count())
    test_name = ['张无忌', '乔峰', '郭靖', '杨过', '令狐冲', '韦小宝']
    #test_name = ['张无忌']
    test_menpai = ['明教', '逍遥派', '少林', '全真教', '华山派', '少林']
    for i in range(0, 5):
        name = "output/" + files[i]
        print(name)
        model = Word2Vec(sentences=LineSentence(name), hs=1, min_count=10, window=5, vector_size=200, sg=0, epochs=200)
        for result in model.wv.similar_by_word(test_name[i], topn=10):
            print(result[0], result[1])
        for result in model.wv.similar_by_word(test_menpai[i], topn=10):
            print(result[0], result[1])



四、实验结果

1、《倚天屠龙记》

张无忌关联度
周芷若0.511336
张翠山0.463939
谢逊0.412231
赵敏0.403387
宋青书0.392989
金花婆婆0.37242
朱长龄0.364297
鹿杖客0.357451
殷素素0.346302
了张无忌0.346121

张无忌跟周芷若是青梅竹马,父亲为张翠山,义父为谢逊,后来跟赵敏在一起,宋青书是张无忌的师哥,金花婆婆是明教的紫衫龙王,也是小昭的母亲,也是与张无忌相关。

明教关联度
本教0.415993
魔教0.319323
从来不0.275328
0.262971
僧侣0.253044
报仇0.248239
船只0.245379
峨嵋派0.244295
贵教0.243198
明教之0.238621

明教常自称本教,也常被六大门派叫做魔教。

2、《天龙八部》

段誉关联度
萧峰0.564757
段正淳0.472794
慕容复0.459998
段誉0.438487
游坦之0.427203
王语嫣0.417367
鸠摩智0.391007
徐长老0.37959
钟夫人0.357237
阿朱0.352062

段誉的结拜大哥是萧峰,父亲为段正淳,慕容复是对头,这些都是跟他相关的人。

逍遥派关联度
苏星河0.338742
无崖子0.332658
童姥0.266579
虚竹0.250159
丁春秋0.247675
武学上0.247264
小僧0.242177
波罗星0.239409
姥姥0.237926
般若0.232889

逍遥派的掌门是无崖子,首徒是苏星河,天山童姥是逍遥派前任掌门逍遥子的大弟子,虚竹后来加入了逍遥派,丁春秋之前也是逍遥派弟子。

3、《射雕英雄传》

郭靖关联度
黄蓉0.754457
洪七公0.689884
欧阳克0.683156
欧阳锋0.658934
裘千仞0.606486
黄药师0.597743
周伯通0.573734
完颜康0.561691
梅超风0.534767
丘处机0.522161

郭靖的老婆是黄蓉,师傅是洪七公,跟上述的人都有交集。

少林关联度
昆仑0.582904
星宿0.576276
六大0.558112
全真0.554336
崆峒0.532443
海沙0.508429
蓬莱0.496702
大门0.438703
青海0.431732
污衣0.425564

跟少林相关的都是一些其他门派。

4、《神雕侠侣》

杨过关联度
小龙女0.728308
李莫愁0.685839
黄蓉0.664348
郭靖0.641764
陆无双0.640486
法王0.619647
赵志敬0.589013
周伯通0.57856
公孙止0.555143
洪七公0.554223

杨过的姑姑也是小龙女,跟其他的人也有一些交集关系。

全真教关联度
赵志敬0.354839
丘道长0.337257
重阳0.334504
全真0.294923
丘处机0.287868
北斗0.279528
王重阳0.278343
打架0.276295
王处一0.27136
孙婆婆0.265189

全真教相关的都是全真教里面相关的人以及跟全真教相关的门派。

5、《笑傲江湖》

令狐冲关联度
岳不群0.778345
林平之0.725633
岳灵珊0.700197
田伯光0.680995
仪琳0.67232
岳夫人0.66513
盈盈0.626171
向问天0.613704
任行0.593848
张无忌0.589727

与令狐冲相关的是他的师傅、师弟、师妹等人,其余人都是与令狐冲有交集的人。有意思的是,在最后与令狐冲相关的人中,出现了张无忌。具体分析结果见实验分析。

华山派关联度
青城派0.560951
华山0.504883
本派0.448503
武当派0.434742
嵩山0.432196
岳不群0.426482
恒山0.422759
本门0.418473
峨嵋派0.408812
青城0.404923

与华山派相关的都是一些门派,其中岳不群是华山派的掌门。

五、实验分析

本次实验针对金庸先生的五本小说《倚天屠龙记》、《天龙八部》、《射雕英雄传》、《神雕侠侣》、《笑傲江湖》作为样本,对其中的主角、门派分别进行了聚类分析。

  • 实验结果如上所示,其中人物与门派的关联度均较高,符合小说的实际情况。
  • 但在针对《笑傲江湖》中的令狐冲的人物关联度分析时,出现了张无忌。对这种情况进行分析之后,考虑原因,可能是模型构建中出现问题,在模型构建时,应将每本小说的模型分开,本实验中未分开每本小说的模型。张无忌跟令狐冲都是两部小说的主角,他们的共同点都是与门派、少年英雄、学会了绝世武功等。因此作者金庸,可能在两个人物塑造时,人物语气、人物描述部分存在相似部分,因此分析出令狐冲与张无忌的关联度。

附录

实验全部代码如下所示:
实验代码参考前人

import math
import jieba
import os  # 用于处理文件路径
import re
import sys
import random
import numpy as np
import multiprocessing
from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence
def read_novel(path_in, path_out):  # 读取语料内容
    content = []
    names = os.listdir(path_in)
    for name in names:
        novel_name = path_in + '\\' + name
        fenci_name = path_out + '\\' + name
        for line in open(novel_name, 'r', encoding='ANSI'):
            line.strip('\n')
            line = re.sub("[A-Za-z0-9\:\·\—\,\。\“\”\\n \《\》\!\?\、\...]", "", line)
            line = content_deal(line)
            con = jieba.cut(line, cut_all=False) # 结巴分词
            # content.append(con)
            content.append(" ".join(con))
        with open(fenci_name, "w", encoding='utf-8') as f:
            f.writelines(content)
    return content, names


def content_deal(content):  # 语料预处理,进行断句,去除一些广告和无意义内容
    ad = ['本书来自www.cr173.com免费txt小说下载站\n更多更新免费电子书请关注www.cr173.com', '----〖新语丝电子文库(www.xys.org)〗', '新语丝电子文库',
          '\u3000', '\n', '。', '?', '!', ',', ';', ':', '、', '《', '》', '“', '”', '‘', '’', '[', ']', '....', '......',
          '『', '』', '(', ')', '…', '「', '」', '\ue41b', '<', '>', '+', '\x1a', '\ue42b', '她', '他', '你', '我', '它', '这'] #去掉其中的一些无意义的词语
    for a in ad:
        content = content.replace(a, '')
    return content


if __name__ == '__main__':   ##
    [data_txt, files] = read_novel("金庸小说集", "output")
    #[data_txt, files] = read_novel("倚天屠龙记", "output")
    #model = Word2Vec(data_txt, vector_size=400, window=5, min_count=5, epochs=200, workers=multiprocessing.cpu_count())
    test_name = ['张无忌', '乔峰', '郭靖', '杨过', '令狐冲', '韦小宝']
    #test_name = ['张无忌']
    test_menpai = ['明教', '逍遥派', '少林', '全真教', '华山派', '少林']
    for i in range(0, 5):
        name = "output/" + files[i]
        print(name)
        model = Word2Vec(sentences=LineSentence(name), hs=1, min_count=10, window=5, vector_size=200, sg=0, epochs=200)
        for result in model.wv.similar_by_word(test_name[i], topn=10):
            print(result[0], result[1])
        for result in model.wv.similar_by_word(test_menpai[i], topn=10):
            print(result[0], result[1])


  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在MapReduce编程中,K均值聚类是一个常用的算法。在实验中可能会遇到以下问题: 1. 数据倾斜问题 在K均值聚类中,数据可能会出现倾斜,导致一些Reducer处理的数据量过大,而其他Reducer则处理很少的数据。这会导致整个程序运行效率低下。 解决办法:可以采用数据切分、数据预处理、负载均衡等方法来解决数据倾斜问题。比如可以对数据进行随机分片,或者采用局部聚类的方法进行预处理,以达到负载均衡的效果。 2. 初始中心点选择问题 K均值聚类算法中,初始中心点的选择对结果有很大的影响。如果初始中心点选择不合理,可能会导致最终的聚类结果不理想。 解决办法:可以采用随机选择、聚类采样等方法来确定初始中心点。同时,可以多次运行算法,选择最优的结果。 3. 算法收敛速度问题 K均值聚类算法需要迭代多次才能收敛,每次迭代都需要进行MapReduce操作,这会导致程序运行时间较长。 解决办法:可以采用优化算法、增加并行度等方法来提高算法收敛速度。比如可以采用Mini-Batch K-means算法来减少计算量,或者增加Reducer的数量来提高并行度。 4. 数据量过大问题 K均值聚类算法需要处理大量数据,如果数据量过大,可能会导致程序无法运行或者运行时间过长。 解决办法:可以采用数据采样、分布式存储等方法来解决数据量过大的问题。比如可以采用Hadoop分布式文件系统(HDFS)来存储数据,或者采用MapReduce框架中的Combiner函数来减少数据传输量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值