赞
踩
利用神经语言模型,训练词向量,通过对词向量的聚类或者其他方法来验证词向量的有效性。
利用给定语料库(或者自选语料库),利用神经语言模型(如:Word2Vec, GloVe等模型)来训练词向量,通过对词向量的聚类或者其他方法来验证词向量的有效性。
自然语言处理相关任务中要将自然语言交给机器学习中的算法来处理,通常需要将语言数学化,因为机器不是人,机器只认数学符号。向量是人把自然界的东西抽象出来交给机器处理的东西,基本上可以说向量是人对机器输入的主要方式了。
词向量就是用来将语言中的词进行数学化的一种方式,顾名思义,词向量就是把一个词表示成一个向量。 我们都知道词在送到神经网络训练之前需要将其编码成数值变量,常见的编码方式有两种:One-Hot Representation 和 Distributed Representation。
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=1∑TP(w(t)∣w(t−m),...,w(t−1),w(t+1),...,w(t+m))
在读取语料后,首先利用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
使用开源的Gensim库提供的接口来训练Word2vec模型,调用的函数如下:
Word2Vec(sentences=LineSentence(name), hs=1, min_count=10, window=5, vector_size=200, sg=0, epochs=200)
其中的参数的含义为:
模型训练完毕之后,通过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])
张无忌 | 关联度 |
---|---|
周芷若 | 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 |
明教常自称本教,也常被六大门派叫做魔教。
段誉 | 关联度 |
---|---|
萧峰 | 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 |
逍遥派的掌门是无崖子,首徒是苏星河,天山童姥是逍遥派前任掌门逍遥子的大弟子,虚竹后来加入了逍遥派,丁春秋之前也是逍遥派弟子。
郭靖 | 关联度 |
---|---|
黄蓉 | 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 |
跟少林相关的都是一些其他门派。
杨过 | 关联度 |
---|---|
小龙女 | 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 |
全真教相关的都是全真教里面相关的人以及跟全真教相关的门派。
令狐冲 | 关联度 |
---|---|
岳不群 | 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])
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。