创建网站基本流程,请问如何做网站,响应式自适应织梦网站模板,创建wordpress网站写在前面本来是想写“实战篇”的#xff0c;感觉实验语料库不大#xff0c;就算是一个应用篇吧。选取了中文语料#xff0c;主要简单介绍jieba分词的使用#xff0c;以及Gemsim模块中Word2Vec的使用。word2vec的原理可以参考之前的文章#xff1a;华夏狼崽感觉实验语料库不大就算是一个应用篇吧。选取了中文语料主要简单介绍jieba分词的使用以及Gemsim模块中Word2Vec的使用。word2vec的原理可以参考之前的文章华夏狼崽word2vec学习笔记(原理篇)zhuanlan.zhihu.com一、语料介绍一直比较喜欢金庸的武侠小说所以语料选取了金庸的十五部小说(精校版)最初的项目中只训练了一部《射雕英雄传》内容太少不够爽可以分析的关系也不多所以一次性训练了十五部小说看是否能得到不同小说之间一些人物、门派、武功的关系。二、文本预处理要训练词向量首先就要得到词原始的数据都是完整的文本、句子怎样得到词语呢这里用到一个很好用的模块jieba。jieba模块是一个python中文分词模块可以将输入的句子分为词语有三种分词方式精准模式全模式和搜索引擎模式。安装方法和更细节的使用方式这里不做介绍可以参考jieba的官方githubfxsjy/jieba1. 导入jieba模块和其他相关模块并加载文件路径import osimport jiebaimport warningswarnings.filterwarnings(ignore)novel_path E:/Learn/WORD2VEC/金庸小说精校版/data_path E:/Learn/WORD2VEC/novel_path为小说原始文本路径data_path为其他一些文件的路径(下文一一介绍)。2. 过滤标点以及停用词在分词中标点符号是我们不需要的。还有一类词是训练词向量时不需要的这些词单独出现没有什么具体意义比如的各位什么等等这一类词称为停用词(stop word)。停用词表的选择需要根据实际应用环境调整这里我的停用词表下载了网上比较通用的中文语料停用词表根据词向量训练结果做了一点点调整添加了几个在武侠小说中容易出现而我并不想得到它的词向量的词比如说道等等。由于下载的停用词表中包含了标点符号所以这里可以把标点当作停用词合并一起处理。加载停用词表stop_words_file open(data_path stop_words.txt, r)stop_words list()for line in stop_words_file.readlines():line line.strip() # 去掉每行末尾的换行符stop_words.append(line)stop_words_file.close()print(len(stop_words))print(stop_words[300:320])看一下一共几个停用词抽一些出来随便看看有哪些词1903[乘势, 乘机, 乘胜, 乘虚, 乘隙, 九, 也, 也好, 也就是说, 也是, 也罢, 了, 了解, 争取, 二, 二来, 二话不说, 二话没说, 于, 于是]停用词表加载完毕后面只需判断分出的词是否在表里即可如果在表里则舍弃不要。3. 添加自定义词汇最开始的实验中我是直接分词的但是发现很多想要的词汇都没能正确的分出来包括一些重要人物的名称一些重要的武功等是因为这些词汇都是武侠小说这种特定环境下的专有名词jieba的词汇表中并没有收录所以我整理了三份txt文本分别记录了武侠小说中的人物名称、武功名称和门派名称参考来源金庸网-金庸数据库。将人名添加到词汇表中people_names_file open(data_path 金庸小说全人物.txt, r)people_names list()for line in people_names_file.readlines():line line.strip() # 去掉每行末尾的换行符jieba.add_word(line)people_names.append(line)stop_words_file.close()print(len(people_names))添加的人名数量1237类似的导入了389个武功名称和97个门派名称。4. 分词分词本来我以为是没有什么的直接用精确模式逐本逐行的分就好了。实际操作时遇到了一点小问题。先看一下文件名novel_names list(os.listdir(novel_path))novel_names输出[书剑恩仇录.txt,侠客行.txt,倚天屠龙记.txt,天龙八部.txt,射雕英雄传.txt,白马啸西风.txt,碧血剑.txt,神雕侠侣.txt,笑傲江湖.txt,越女剑.txt,连城诀.txt,雪山飞狐.txt,飞狐外传.txt,鸳鸯刀.txt,鹿鼎记.txt]逐本逐行的分词发现结果中有很多类似这样的词[黄蓉道, 郭靖叫, 黄蓉喜, 黄蓉思, 谢逊怒]很多人名没能够分割出来和后面的一个字练成了一个新的词语。这主要是因为中文语言太灵活了的确难以完美分割每个词。如果数量不多的话我也就接受这个结果了。简单统计了一下以黄蓉为例一共出现两千多次有超出五分之一是分错的这个数量就比较大了需要考虑解决的方法。再统计观察了一下发现只有两个字的人名会出现这种情况三个字的和四个字的名字都能很好的分割开这样就容易解决了。我的解决策略是对分出来的词判断它的前两个字组成的新词是否在全部人名列表中如果存在则直接用新词替换它加入分词表。这样的方法很容易上面的问题但是有一个缺点就是如果存在一个人的名字的前两个字恰好也是另外一个人的名字这样就直接会直接把第二个人名字记下导致分错了举例有两人分别名为王毛毛和王毛当分词结果分出王毛毛就会因为它的前两个字存在于人名表中就会把这个词改成王毛这其实是错误的。这种情况其实是可以避免的只需要再加一个规则如果整个名字是正确的人名的话就优先使用原始分词结果。这个规则是可以的但是我并没有使用原因是在金庸先生的武侠小说中给人物起名基本没有这种情况起的名字差距都挺远的主角们名称更是不会和其他的有这种重叠情况。好像只有《倚天屠龙记》中张三丰和《侠客行》里的一个小人物张三出现这个问题我选择删掉张三我并不想分析这个人物)代码如下seg_novel []for novel_name in novel_names:novel open(novel_path novel_name, r, encodingutf-8-sig)print(Waiting for{}....format(novel_name))line novel.readline()forward_rows len(seg_novel)while line:line_1 line.strip()outstr line_seg jieba.cut(line_1, cut_allFalse)for word in line_seg:if word not in stop_words:if word ! \t:if word[:2] in people_names:word word[:2]outstr wordoutstr if len(str(outstr.strip())) ! 0:seg_novel.append(str(outstr.strip()).split())line novel.readline()print({}finishedwith{}Row.format(novel_name, (len(seg_novel) - forward_rows)))print(- * 40)print(- * 40)print(- * 40)print(All finishedwith{}Row.format(len(seg_novel)))可以看到每一本书分词后的行数和总行数Waiting for 书剑恩仇录.txt...书剑恩仇录.txt finishedwith 3561 Row----------------------------------------Waiting for 侠客行.txt...侠客行.txt finishedwith 3513 Row----------------------------------------Waiting for 倚天屠龙记.txt...倚天屠龙记.txt finishedwith 7918 Row----------------------------------------Waiting for 天龙八部.txt...天龙八部.txt finishedwith 10947 Row----------------------------------------Waiting for 射雕英雄传.txt...射雕英雄传.txt finishedwith 7130 Row----------------------------------------Waiting for 白马啸西风.txt...白马啸西风.txt finishedwith 597 Row----------------------------------------Waiting for 碧血剑.txt...碧血剑.txt finishedwith 3786 Row----------------------------------------Waiting for 神雕侠侣.txt...神雕侠侣.txt finishedwith 6998 Row----------------------------------------Waiting for 笑傲江湖.txt...笑傲江湖.txt finishedwith 8550 Row----------------------------------------Waiting for 越女剑.txt...越女剑.txt finishedwith 196 Row----------------------------------------Waiting for 连城诀.txt...连城诀.txt finishedwith 2207 Row----------------------------------------Waiting for 雪山飞狐.txt...雪山飞狐.txt finishedwith 1096 Row----------------------------------------Waiting for 飞狐外传.txt...飞狐外传.txt finishedwith 3776 Row----------------------------------------Waiting for 鸳鸯刀.txt...鸳鸯刀.txt finishedwith 211 Row----------------------------------------Waiting for 鹿鼎记.txt...鹿鼎记.txt finishedwith 11158 Row------------------------------------------------------------------------------------------------------------------------All finishedwith 71644 Row随便取几行出来看看[郭靖, 黄蓉, 完颜洪烈, 做, 爹爹, 语气, 间, 亲热, 相互, 一眼, 郭靖, 气恼, 难受, 恨不得, 揪住, 问个, 明白][黄蓉, 郭靖, 边道, 喝得, 酒儿, 偏, 两人, 溜, 出阁, 子, 来到, 后园, 黄蓉, 晃动, 火折, 点燃, 柴房中, 柴草, 四下, 放, 起火][一日, 中, 洪七公, 心, 早已, 御厨, 之内, 好容易, 挨到, 时分, 郭靖, 负, 洪七公, 四人, 上屋, 径往, 大内, 皇宫, 高出, 民居, 屋瓦, 金光灿烂, 极易, 辨认, 不多时, 四人, 已悄, 没声, 跃进, 宫墙][完颜洪烈, 悄声, 所说, 耳目众多, 饮酒, 三人, 转过, 话题, 说些, 景物, 见闻, 风土人情]嗯不错是我想要的效果通过一个嵌套列表存储每一句为列表中一个元素每一句又由分好的词构成一个列表这也是word2vec训练时需要输入的格式。三、训练词向量这里用的是Gemsim模块中Word2Vec。Gemsim模块是一个据说功能很强大的NLP处理模块我只尝试了Word2Vec函数以后有需要的话学习一下其他部分。训练代码如下import gensim.models as w2vmodel w2v.Word2Vec(sentencesseg_novel, size200, window5, min_count5, sg0)model.save(data_path all_CBOW.model) # 保存模型说一下Word2Vec中的几个参数sentences是输入的语料即分词得到的嵌套列表可以通过LineSentence或Text8Corpus函数构造。size即是训练得到的词向量的维数。window为滑窗大小也就是训练词与上下文词最远的距离。min_count是指过滤掉一些低词频的词。sg为选择CBOW模型还是skip-gram模型0为CBOW模型1为skip-gram模型默认为CBOW模型(实际发现CBOW和skip-gram模式得到的结果差距还是比较大的具体可以看下文对比)。还有一些其他参数不一一列出可以参考官方文档gensim: topic modelling for humansradimrehurek.com1. CBOW参数都选取默认(CBOW)训练得到词向量模型。接下来做一些简单有趣的测试。首先是用模型测试一些词的相似度(实则根据词向量计算余弦相似度)。print(model.similarity(张无忌, 周芷若))print(model.similarity(张无忌, 赵敏))看一下张无忌和周芷若、赵敏哪个相似度更高呢0.701477470.74265605好吧还是和赵敏比较好。看一下和张无忌最接近的五个词print(model.most_similar(张无忌, topn5))[(令狐冲, 0.8610879182815552),(虚竹, 0.8390334844589233),(黑白子, 0.8079050779342651),(张翠山, 0.8067573308944702),(苗人凤, 0.7919591665267944)]诶除了张翠山之外其他的几个人怎么关联的呢实际大概是因为令狐冲、虚竹等也是其他小说中数一数二重要的人物吧。看一下和峨嵋派最接近的五个词print(model.most_similar(峨嵋派, topn5))[(华山派, 0.9490149021148682),(昆仑派, 0.9471687078475952),(嵩山派, 0.9393842220306396),(本派, 0.9321860074996948),(雪山派, 0.9311256408691406)]除了本派乱入其他也都是一些门派。韦小宝关系最乱看下和哪个老婆最好print(model.similarity(韦小宝, 阿珂))print(model.similarity(韦小宝, 双儿))print(model.similarity(韦小宝, 建宁公主))print(model.similarity(韦小宝, 苏荃))print(model.similarity(韦小宝, 沐剑屏))print(model.similarity(韦小宝, 曾柔))print(model.similarity(韦小宝, 方怡))0.465504320.517360450.467250140.455971480.51027250.362217340.50045687双儿第一沐剑屏其次没看过鹿鼎记不做分析。看一下和韦小宝最接近的十个词print(model.most_similar(韦小宝, topn10))[(康熙, 0.6945387125015259),(公主, 0.6921814680099487),(乾隆, 0.6888490915298462),(太后, 0.6246222257614136),(苏菲亚, 0.605838418006897),(周总镖, 0.6015807390213013),(祖千秋, 0.6013493537902832),(小桂子, 0.5954452753067017),(陈家洛, 0.5947461128234863),(徐天宏, 0.5941584706306458)]没想到7个老婆都没进入前十反而编外老婆苏菲亚排名那么高。。不过韦小宝和康熙皇帝的关系是真的近呀。除此之外还可以用以下函数寻找对应关系类似于李白之与唐代等于曹雪芹之于清代。def find_relation(a, b, c):d, _ model.most_similar(positive[c, b], negative[a])[0]print (c,d)首先就想找一下杨过之与小龙女等于张无忌之于谁print(find_relation(杨过,小龙女,张无忌))张无忌 赵敏~~~~~~~~这个结果还是找的比较准的心疼周芷若一秒。但是有一些就不准了乱入了比如print(find_relation(杨过,小龙女,郭靖))郭靖 石清。。不止这里有乱入在测试一些人的最接近词时也有很多挺难解释的可能他们相似的维度并不容易观察的到吧。接下来用skip-gram尝试是不是同样的效果呢2. skip-gram只需把sg参数设置为1即可参数也选用默认参数。杨过之与小龙女等于张无忌之于谁print(find_relation(杨过,小龙女,张无忌))张无忌 周芷若。。。逆风翻盘那赶紧看看其他的结果print(find_relation(杨过,小龙女,郭靖))郭靖 蓉儿print(find_relation(杨过,小龙女,黄蓉))黄蓉 靖哥哥这个就有点秀了呀不仅能找对人找到的还是昵称。。。和张无忌最接近的五个词print(model.most_similar(张无忌, topn5))[(周芷若, 0.6134092211723328),(赵敏, 0.5959696769714355),(小昭, 0.5360002517700195),(杨逍, 0.5234625935554504),(波斯, 0.49604594707489014)]这下就没有其他时代乱入的人了而且也都是比较好解释的通的还可以找找这样的关系print(find_relation(杨过,小龙女,乔峰))乔峰 阿朱print(find_relation(杨过,小龙女,段誉))段誉 王语嫣print(find_relation(杨过,小龙女,段正淳))段正淳 刀白凤print(find_relation(武当派,张三丰,峨嵋派))峨嵋派 周芷若print(find_relation(武当派,张三丰,天地会))天地会 陈近南乔峰阿朱这个就没什么好说的了段氏父子的异性关系圈一直比较复杂。。从词向量的角度看段誉还是对神仙姊姊钟情的段正淳还是对正室妻子有更多的情感的。武当派之于张三丰----峨嵋派不应该是灭绝师太嘛哈哈好吧周芷若毕竟也是做过峨嵋掌门的也算解释的通吧。不止是在同一部小说中可以对应这种关系通过《倚天屠龙记》中的武当派掌门张三丰也可以找到《鹿鼎记》中天地会总舵主陈近南。最后再看一个原著中比较神秘的人print(model.most_similar(王重阳, topn10))[(林朝英, 0.8663322925567627),(宝典, 0.8595889210700989),(研习, 0.8348122835159302),(创制, 0.8294848799705505),(先天功, 0.8276116251945496),(医术, 0.827604353427887),(精研, 0.8269264101982117),(神通, 0.8256270885467529),(剑宗, 0.8248381614685059),(功诀, 0.8226447701454163)]这个结果还是蛮满意的王重阳作为一个武学奇才五绝之首世称天下第一与创制研习精研一类词相近然而排在第一的却还是对他因爱生恨的林朝英。写在后面有意思的测试还有很多就不一一叙述了。乱入的结果也不少优化分词或者调整参数可能有更好的结果。总之从结果看来CBOW模型更注重文章整体的关联很多相似度高的词跨越了多个时代多本小说而skip-gram模型更加注重局部相似度高的词基本集中在同一本小说中。查阅了一些文章后的确说CBOW模型在语料库较大时效果较好skip-gram模型在语料库较小时候效果比较好。可能十五本小说语料库的确比较小吧所以skip-gram模型的测试结果的可解释性更强点。这也只是从训练出的词向量做的最直接的测试后续还可以用聚类分类等其他算法进行其他更有意思的测试。相关的代码和文件上传在github上感兴趣的话可以自己尝试一下wolfkin-hth/novelsgithub.com学习路漫漫狼崽在路上~