幼儿饰品瑜伽美体用品微软
投稿投诉
微软创意
爱情通信
用品婚姻
爱好看病
美体软件
影音星座
瑜伽周边
星座办公
饰品塑形
搞笑减肥
幼儿两性
智家潮品

Python爬虫之九阴真经

  用Python探索金庸笔下的江湖!
  带你用python看小说,娱乐学习两不误。
  涉及的知识点有:常规小说网站的爬取思路基本的pandas数据整理lxml与xpath应用技巧正则模式匹配Counter词频统计pyecharts数据可视化stylecloud词云图gensim。models。Word2Vec的使用scipy。cluster。hierarchy层次聚类
  本文从传统匹配逻辑分析过渡到机器学习的词向量,全方位进行文本分析,值得学习,干货满满。(文末点击阅读原文)金庸小说的采集
  以前金庸小说的网站有很多,但大部分已经无法访问,但由于很多金庸迷的存在,新站也是源源不断出现。我近期通过百度找到的一个还可以访问的金庸小说网址是:aHR0cDovL2ppbnlvbmcxMjMuY29tLw
  不过我已经准备好已经采集完成的数据,大家可以直接下载数据,跳过本章的内容。
  数据源下载地址:https:gitcode。netas604049322blogdata每部小说的创作日期
  下面首先获取这15部作品的名称、创作年份和对应的链接。从开发者工具可以看到每行的a标签很多,我们需要的节点的特征在于后续临近节点紧接着一个创作日期的字符串:
  那么我们就可以通过遍历所有的a标签并判断其后续一个临近节点的内容是否符合日期格式,最终完整下载代码为:importrequestsfromlxmlimportetreeimportpandasaspdimportreheaders{UserAgent:Mozilla5。0(WindowsNT10。0;WOW64)AppleWebKit537。36(KHTML,likeGecko)Chrome86。0。4240。198Safari537。36,AcceptLanguage:zhCN,zh;q0。9}resrequests。get(baseurl,headersheaders)res。encodingres。apparentencodinghtmletree。HTML(res。text)atagshtml。xpath(p〔classjianjie〕pa)data〔〕forataginatags:mobjre。search(((d{4}(?:d{4})?年)),atag。tail)ifmobj:data。append((atag。text,mobj。group(1),atag。attrib〔href〕))datapd。DataFrame(data,columns〔名称,创作时间,网址〕)
  可以按照创作日期排序查看:data。sortvalues(创作时间,ignoreindexTrue,inplaceTrue)data
  名称创作时间网址书剑恩仇录1955年shujianenchoulu碧血剑1956年bixuejian射雕英雄传19571959年shediaoyingxiongzhuan神雕侠侣19591961年shendiaoxialv雪山飞狐1959年xueshanfeihu飞狐外传19601961年feihuwaizhuan白马啸西风1961年baimaxiaoxifeng倚天屠龙记1961年yitiantulongji鸳鸯刀1961年yuanyangdao天龙八部19631966年tianlongbabu连城诀1963年lianchengjue侠客行1965年xiakexing笑傲江湖1967年xiaoaojianghu鹿鼎记19691972年ludingji越女剑1970年yuenvjian章节页下载与顺序校正
  下面看看章节页节点的分布情况,以《雪山飞狐》为例:
  同时可以看到部分小说的节点出现了倒序的情况,我们需要在识别出倒序时将其正序,完整代码:fromurllib。parseimporturljoindefgetTitleAndUrl(url):urlurljoin(baseurl,url)data〔〕resrequests。get(url,headersheaders)res。encodingres。apparentencodinghtmletree。HTML(res。text)reverse,lastnumFalse,Nonefori,ataginenumerate(html。xpath(dl〔classcatbox〕dda)):data。append(〔re。sub(s,,atag。text),atag。attrib〔href〕〕)numsre。findall(第(d)章,atag。text)ifnums:iflastnumandint(nums〔0〕)lastnum:reverseTruelastnumint(nums〔0〕)顺序校正并删除后记之后的内容ifreverse:data。reverse()returndata
  测试一下:title2urlgetTitleAndUrl(data。query(名称雪山飞狐)。网址。iat〔0〕)title2url〔〔第01章,xueshanfeihu488。html〕,〔第02章,xueshanfeihu489。html〕,〔第03章,xueshanfeihu490。html〕,〔第04章,xueshanfeihu491。html〕,〔第05章,xueshanfeihu492。html〕,〔第06章,xueshanfeihu493。html〕,〔第07章,xueshanfeihu494。html〕,〔第08章,xueshanfeihu495。html〕,〔第09章,xueshanfeihu496。html〕,〔第10章,xueshanfeihu497。html〕,〔后记,xueshanfeihu498。html〕〕
  可以看到章节已经顺利的正序排列。每部小说的下载
  小说每一章的详细页最后一行的数据我们不需要:
  下载每章内容的代码:defdownloadpagecontent(url):resrequests。get(url,headersheaders)res。encodingres。apparentencodinghtmletree。HTML(res。text)content。join(html。xpath(p〔classentry〕ptext())〔:1〕)returncontent
  然后我们就可以批量下载全部小说了:importosdefdownloadonenovel(filename,url):下载单部小说title2urlgetTitleAndUrl(url)print(创建文件:,filename)fortitle,urlintitle2url:withopen(filename,a,encodingu8)asf:f。write(title)f。write()print(下载:,title)contentdownloadpagecontent(url)f。write(content)f。write()os。makedirs(novels,existokTrue)forrowindata。itertuples():filenamefnovels{row。名称}。txtos。remove(filename)downloadonenovel(filename,row。网址)人物、武功和门派数据整理
  为了更好分析金庸小说,我们还需要采集金庸小说的人物、武功和门派,个人并没有找到还可以访问相关数据的网站,于是自行收集整理了相关数据:
  相关数据都以如下格式存储,例如金庸小说的人物:小说1人物1人物2小说2人物1人物2小说3人物1人物2
  武功:小说1武功1武功2小说2武功1武功2小说3武功1武功2
  数据源下载地址:https:gitcode。netas604049322blogdata高频分析
  定义一个加载小说的方法:defloadnovel(novel):withopen(fnovels{novel}。txt,encodingu8)asf:returnf。read()主角分析
  首先我们加载人物数据:withopen(datanames。txt,encodingutf8)asf:data〔line。rstrip()forlineinf〕novelsdata〔::2〕namesdata〔1::2〕novelnames{k:v。split()fork,vinzip(novels,names)}delnovels,names,data
  可以预览一下天龙八部中的人物:print(,。join(novelnames〔天龙八部〕〔:20〕))刀白凤,丁春秋,马夫人,马五德,小翠,于光豪,巴天石,不平道人,邓百川,风波恶,甘宝宝,公冶乾,木婉清,包不同,天狼子,太皇太后,王语嫣,乌老大,无崖子,云岛主
  下面我们寻找一下每部小说的主角,统计每个人物的出场次数,显然次数越多主角光环越强,下面我们看看每部小说,出现次数最多的前十个人物:fromcollectionsimportCounterdeffindmaincharecters(novel,num10,contentNone):ifcontentisNone:contentloadnovel(novel)countCounter()fornameinnovelnames〔novel〕:count〔name〕content。count(name)returncount。mostcommon(num)fornovelinnovelnames:print(novel,dict(findmaincharecters(novel,10)))书剑恩仇录{陈家洛:2095,张召重:760,徐天宏:685,霍青桐:650,余鱼同:605,文泰来:601,骆冰:594,周绮:556,李沅芷:521,陆菲青:486}碧血剑{袁承志:3028,何铁手:306,温青:254,阿九:215,洪胜海:200,焦宛儿:197,皇太极:183,崔秋山:180,穆人清:171,闵子华:163}射雕英雄传{郭靖:5009,黄蓉:3650,洪七公:1041,黄药师:868,周伯通:654,欧阳克:611,丘处机:606,梅超风:480,杨康:439,柯镇恶:431}神雕侠侣{杨过:5991,小龙女:2133,郭靖:1431,黄蓉:1428,李莫愁:1016,郭芙:850,郭襄:778,陆无双:575,周伯通:555,赵志敬:482}雪山飞狐{胡斐:230,曹云奇:228,宝树:225,苗若兰:217,胡一刀:207,苗人凤:129,刘元鹤:107,陶子安:107,田青文:103,范帮主:83}飞狐外传{胡斐:2761,程灵素:765,袁紫衣:425,苗人凤:405,马春花:331,福康安:287,赵半山:287,田归农:227,徐铮:217,商宝震:217}白马啸西风{李文秀:441,苏普:270,阿曼:164,苏鲁克:147,陈达海:106,车尔库:99,李三:31,丁同:29,霍元龙:23,桑斯:22}倚天屠龙记{张无忌:4665,赵敏:1250,谢逊:1211,张翠山:1146,周芷若:825,殷素素:550,杨逍:514,张三丰:451,灭绝师太:431,小昭:346}鸳鸯刀{萧中慧:103,袁冠南:82,卓天雄:76,周威信:74,林玉龙:52,任飞燕:51,萧半和:48,盖一鸣:45,逍遥子:28,常长风:19}天龙八部{段誉:3372,萧峰:1786,虚竹:1636,阿紫:1150,乔峰:1131,阿朱:986,慕容复:925,王语嫣:859,段正淳:757,木婉清:734}连城诀{狄云:1433,水笙:439,戚芳:390,丁典:364,万震山:332,万圭:288,花铁干:256,吴坎:155,血刀老祖:144,戚长发:117}侠客行{石破天:1804,石清:611,丁珰:446,白万剑:446,丁不四:343,谢烟客:337,闵柔:327,贝海石:257,丁不三:217,白自在:199}笑傲江湖{令狐冲:5838,岳不群:1184,林平之:926,岳灵珊:919,仪琳:729,田伯光:708,任我行:525,向问天:513,左冷禅:473,方证:415}鹿鼎记{韦小宝:9731,吴三桂:949,双儿:691,鳌拜:479,陈近南:472,方怡:422,茅十八:400,小桂子:355,施琅:296,吴应熊:290}越女剑{范蠡:121,阿青:64,勾践:47,薛烛:29,西施:26,文种:23,风胡子:7}
  上述结果用文本展示了每部小说的前5个主角,但是不够直观,下面我用pyecharts的树图展示一下:frompyechartsimportoptionsasoptsfrompyecharts。chartsimportTreedata〔〕fornovelinnovelkungfus:tmp〔〕data。append({name:novel,children:tmp})forname,countinfindmainkungfus(novel,5):tmp。append({name:name,value:count})c(TreeMap()。add(,data,levels〔opts。TreeMapLevelsOpts(),opts。TreeMapLevelsOpts(colorsaturation〔0。3,0。6〕,treemapitemstyleoptsopts。TreeMapItemStyleOpts(bordercolorsaturation0。7,gapwidth5,borderwidth10),upperlabeloptsopts。LabelOpts(isshowTrue,positioninsideTopLeft,verticalaligntop)),〕)。setglobalopts(titleoptsopts。TitleOpts(title金庸小说主角)))c。rendernotebook()
  显然,《神雕侠侣》中的杨过和小龙女,《天龙八部》中的萧(乔)峰,段誉,虚竹,《射雕英雄传》的郭靖和黄蓉,《倚天屠龙记》的张无忌和赵敏都是主角光环最强的角色。武功分析
  使用上述相同的方法,分析各种武功的出现频次,首先加载武功数据:withopen(datakungfu。txt,encodingutf8)asf:data〔line。rstrip()forlineinf〕novelsdata〔::2〕kungfusdata〔1::2〕novelkungfus{k:v。split()fork,vinzip(novels,kungfus)}delnovels,kungfus,data
  定义计数方法:deffindmainkungfus(novel,num10,contentNone):ifcontentisNone:contentloadnovel(novel)countCounter()fornameinnovelkungfus〔novel〕:count〔name〕content。count(name)returncount。mostcommon(num)fornovelinnovelkungfus:print(novel,dict(findmainkungfus(novel,10)))书剑恩仇录{芙蓉金针:16,柔云剑术:15,百花错拳:13,追魂夺命剑:12,三分剑术:12,八卦刀:10,铁琵琶手:9,无极玄功拳:9,甩手箭:7,黑沙掌:7}侠客行{雪山剑法:46,金乌刀法:33,碧针清掌:8,五行六合掌:8,梅花拳:8,罗汉伏魔神功:3,无妄神功:1,神倒鬼跌三连环:1,上清快剑:1,黑煞掌:1}倚天屠龙记{七伤拳:98,乾坤大挪移:93,九阳真经:46,玄冥神掌:43,龙爪手:24,金刚伏魔圈:21,千蛛万毒手:18,幻阴指:17,寒冰绵掌:16,真武七截阵:10}天龙八部{六脉神剑:148,生死符:124,凌波微步:77,化功大法:52,北冥神功:36,般若掌:36,火焰刀:34,小无相功:28,天山六阳掌:25,大金刚拳:24}射雕英雄传{九阴真经:191,铁掌:169,降龙十八掌:92,打狗棒法:47,蛤蟆功:39,空明拳:25,一阳指:22,先天功:14,双手互搏:13,杨家枪法:13}碧血剑{伏虎掌:30,混元功:23,两仪剑法:21,神行百变:18,蝎尾鞭:12,破玉拳:9,金蛇剑法:5,软红蛛索:4,混元掌:4,斩蛟拳:4}神雕侠侣{玉女素心剑法:25,黯然销魂掌:19,五毒神掌:18,龙象般若功:12,玉箫剑法:10,七星聚会:8,美女拳法:8,天罗地网势:7,上天梯:5,三无三不手:4}笑傲江湖{辟邪剑法:160,独孤九剑:80,吸星大法:67,紫霞神功:36,易筋经:33,嵩山剑法:33,华山剑法:30,玉女剑十九式:20,恒山剑法:20,无双无对,宁氏一剑:13}连城诀{连城剑法:29,神照经:23,六合拳:4}雪山飞狐{胡家刀法:8,苗家剑法:7,龙爪擒拿手:5,追命毒龙锥:2,大擒拿手:2,飞天神行:1}飞狐外传{西岳华拳:26,八极拳:20,八仙剑法:8,四象步:6,燕青拳:5,赤尻连拳:5,一路华拳:4,金刚拳:3,毒砂掌:3,四门刀法:2}鸳鸯刀{夫妻刀法:17,呼延十八鞭:6,震天三十掌:1}鹿鼎记{化骨绵掌:24,拈花擒拿手:12,大慈大悲千叶手:11,沐家拳:11,八卦游龙掌:10,少林长拳:7,金刚护体神功:5,波罗蜜手:4,散花掌:3,金刚神掌:2}
  每部小说频次前5的武功可视化:frompyechartsimportoptionsasoptsfrompyecharts。chartsimportTreedata〔〕fornovelinnovelkungfus:tmp〔〕data。append({name:novel,children:tmp})forname,countinfindmainkungfus(novel,5):tmp。append({name:name,value:count})c(TreeMap()。add(,data,levels〔opts。TreeMapLevelsOpts(),opts。TreeMapLevelsOpts(colorsaturation〔0。3,0。6〕,treemapitemstyleoptsopts。TreeMapItemStyleOpts(bordercolorsaturation0。7,gapwidth5,borderwidth10),upperlabeloptsopts。LabelOpts(isshowTrue,positioninsideTopLeft,verticalaligntop)),〕)。setglobalopts(titleoptsopts。TitleOpts(title金庸高频武功)))c。rendernotebook()
  门派分析
  加载数据并获取每部小说前10的门派:withopen(databangs。txt,encodingutf8)asf:data〔line。rstrip()forlineinf〕novelsdata〔::2〕bangsdata〔1::2〕novelbangs{k:v。split()fork,vinzip(novels,bangs)ifk!未知}delnovels,bangs,datadeffindmainbangs(novel,num10,contentNone):ifcontentisNone:contentloadnovel(novel)countCounter()fornameinnovelbangs〔novel〕:count〔name〕content。count(name)returncount。mostcommon(num)fornovelinnovelbangs:print(novel,dict(findmainbangs(novel,10)))书剑恩仇录{红花会:394,言家拳:7,龙门帮:7,天山派:5,嵩阳派:3,南少林:3}侠客行{雪山派:358,长乐帮:242,侠客岛:143,金乌派:48,摩天崖:38,玄素庄:37,金刀寨:25}倚天屠龙记{明教:738,峨嵋派:289,天鹰教:224,昆仑派:130,龙门镖局:85,崆峒派:83,海沙派:58,巨鲸帮:37,神拳门:20,波斯明教:16}天龙八部{丐帮:562,星宿派:203,灵鹫宫:157,姑苏慕容:150,无量剑:83,逍遥派:77,大理段氏:75,青城派:65,蓬莱派:23,伏牛派:8}射雕英雄传{桃花岛:289,全真教:99,铁掌帮:87,仙霞派:5}白马啸西风{晋威镖局:5}碧血剑{仙都派:51,金龙帮:47,青竹帮:45,渤海派:8,永胜镖局:6,点苍派:4,飞虎寨:4,会友镖局:2,东支:2,千柳庄:2}神雕侠侣{绝情谷:128,古墓派:87}笑傲江湖{恒山派:552,华山派:521,嵩山派:297,五岳剑派:281,泰山派:137,衡山派:102,福威镖局:102,日月神教:64,武当派:46,金刀王家:20}连城诀{血刀门:24}雪山飞狐{平通镖局:7,饮马川山寨:4,青藏派:2,无极门:2,百会寺:1}飞狐外传{韦陀门:49,八卦门:31,天龙门:24,太极门:22,飞马镖局:19,五虎门:16,少林派:15,枫叶庄:8,镇远镖局:2}鸳鸯刀{威信镖局:5}鹿鼎记{天地会:542,神龙教:161,少林寺:155,清凉寺:116,王屋派:38,铁剑门:12,金顶门:8,武夷派:3}
  可视化:frompyechartsimportoptionsasoptsfrompyecharts。chartsimportTreedata〔〕fornovelinnovelbangs:tmp〔〕data。append({name:novel,children:tmp})forname,countinfindmainbangs(novel,5):tmp。append({name:name,value:count})c(TreeMap()。add(,data,levels〔opts。TreeMapLevelsOpts(),opts。TreeMapLevelsOpts(colorsaturation〔0。3,0。6〕,treemapitemstyleoptsopts。TreeMapItemStyleOpts(bordercolorsaturation0。7,gapwidth5,borderwidth10),upperlabeloptsopts。LabelOpts(isshowTrue,positioninsideTopLeft,verticalaligntop)),〕)。setglobalopts(titleoptsopts。TitleOpts(title金庸高频门派)))c。rendernotebook()
  还可以测试一下树形图:frompyecharts。chartsimportTreec(Tree()。add(,〔{name:门派,children:data}〕,layoutradial))c。rendernotebook()
  综合统计
  下面我们编写一个函数,输入一部小说名,可以输出其最高频的主角、武功和门派:frompyechartsimportoptionsasoptsfrompyecharts。chartsimportBardefshowtop10(novel):contentloadnovel(novel)charectersfindmaincharecters(novel,10,content)〔::1〕k,vmap(list,zip(charecters))c(Bar(initoptsopts。InitOpts(720px,320px))。addxaxis(k)。addyaxis(,v)。reversalaxis()。setseriesopts(labeloptsopts。LabelOpts(positionright))。setglobalopts(titleoptsopts。TitleOpts(titlef{novel}主角)))display(c。rendernotebook())kungfusfindmainkungfus(novel,10,content)〔::1〕k,vmap(list,zip(kungfus))c(Bar(initoptsopts。InitOpts(720px,320px))。addxaxis(k)。addyaxis(,v)。reversalaxis()。setseriesopts(labeloptsopts。LabelOpts(positionright))。setglobalopts(titleoptsopts。TitleOpts(titlef{novel}功夫)))display(c。rendernotebook())bangsfindmainbangs(novel,10,content)〔::1〕k,vmap(list,zip(bangs))c(Bar(initoptsopts。InitOpts(720px,320px))。addxaxis(k)。addyaxis(,v)。reversalaxis()。setseriesopts(labeloptsopts。LabelOpts(positionright))。setglobalopts(titleoptsopts。TitleOpts(titlef{novel}门派)))display(c。rendernotebook())
  例如查看天龙八部:showtop10(天龙八部)
  词云图分析
  可以先添加所有的人物、武功和门派作为自定义词汇:importjiebafornovel,namesinnovelnames。items():fornameinnames:jieba。addword(name)fornovel,kungfusinnovelkungfus。items():forkungfuinkungfus:jieba。addword(kungfu)fornovel,bangsinnovelbangs。items():forbanginbangs:jieba。addword(bang)文章整体词云查看
  这里我们仅提取词长度不小于4的成语、俗语和短语进行分析,以天龙八部这部小说为例:fromIPython。displayimportImageimportstylecloudimportjiebaimportre去除非中文字符textre。sub(〔一龟〕,,loadnovel(天龙八部))words〔wordforwordinjieba。cut(text)iflen(word)4〕stylecloud。genstylecloud(。join(words),collocationsFalse,fontpathrC:WindowsFontsmsyhbd。ttc,iconnamefasfasquare,outputnametmp。png)Image(filenametmp。png)
  修改上述代码,查看《射雕英雄传》:
  神雕侠侣:
  主角相关剧情词云
  我们知道《神雕侠侣》这部小说最重要的主角是杨过和小龙女,我们可能会对于杨过和小龙女之间所发生的故事很感兴趣。如果通过程序快速了解呢?
  我们考虑把《神雕侠侣》这部小说每一段中出现杨过及小龙女的段落进行jieba分词并制作词云。
  同样我们只看4个字以上的词:data〔〕forlineinloadnovel(神雕侠侣)。splitlines():if杨过inlineand小龙女inline:linere。sub(〔一龟〕,,line)data。extend(wordforwordinjieba。cut(line)iflen(word)4)stylecloud。genstylecloud(。join(data),collocationsFalse,fontpathrC:WindowsFontsmsyhbd。ttc,iconnamefasfasquare,outputnametmp。png)Image(filenametmp。png)
  这里的每一个词都能联想到发生在杨过和小龙女背后的一个故事。
  同样的思路看看郭靖和黄蓉:data〔〕forlineinloadnovel(射雕英雄传)。splitlines():if郭靖inlineand黄蓉inline:linere。sub(〔一龟〕,,line)data。extend(wordforwordinjieba。cut(line)iflen(word)4)stylecloud。genstylecloud(。join(data),collocationsFalse,fontpathrC:WindowsFontsmsyhbd。ttc,iconnamefasfasquare,outputnametmp。png)Image(filenametmp。png)
  最后我们看看天龙八部的三兄弟相关的词云:data〔〕forlineinloadnovel(天龙八部)。splitlines():if(萧峰inlineor乔峰inline)and段誉inlineand虚竹inline:linere。sub(〔一龟〕,,line)data。extend(wordforwordinjieba。cut(line)iflen(word)4)stylecloud。genstylecloud(。join(data),collocationsFalse,fontpathrC:WindowsFontsmsyhbd。ttc,iconnamefasfasquare,outputnametmp。png)Image(filenametmp。png)
  关系图分析
  人物关系分析
  金庸小说15部小说中预计出现了1400个以上的角色,下面我们将遍历小说的每一段,在一段中出现的任意两个角色,都计数1。最终我们取出现频次最高的前200个关系对进行可视化。
  完整代码如下:frompyechartsimportoptionsasoptsfrompyecharts。chartsimportGraphimportmathimportitertoolscountCounter()fornovelinnovelnames:namesnovelnames〔novel〕rerulef({。join(names)})forlineinloadnovel(novel)。splitlines():nameslist(set(re。findall(rerule,line)))ifnamesandlen(names)2:names。sort()fors,tinitertools。combinations(names,2):count〔(s,t)〕1countcount。mostcommon(200)nodecount,nodes,linksCounter(),〔〕,〔〕for(n1,n2),vincount:nodecount〔n1〕1nodecount〔n2〕1links。append({source:n1,target:n2})fornode,countinnodecount。items():nodes。append({name:node,symbolSize:int(math。log(count)5)5})c(Graph(initoptsopts。InitOpts(1280px,960px))。add(,nodes,links,repulsion30))c。render(tmp。html)
  这次我们生成了HTML文件是为了更方便的查看结果,前200个人物的关系情况如下:
  门派关系分析
  按照相同的方法分析所有小说的门派关系:frompyechartsimportoptionsasoptsfrompyecharts。chartsimportGraphimportmathimportitertoolscountCounter()fornovelinnovelbangs:bangsnovelbangs〔novel〕rerulef({。join(bangs)})forlineinloadnovel(novel)。splitlines():nameslist(set(re。findall(rerule,line)))ifnamesandlen(names)2:names。sort()fors,tinitertools。combinations(names,2):count〔(s,t)〕1countcount。mostcommon(200)nodecount,nodes,linksCounter(),〔〕,〔〕for(n1,n2),vincount:nodecount〔n1〕1nodecount〔n2〕1links。append({source:n1,target:n2})fornode,countinnodecount。items():nodes。append({name:node,symbolSize:int(math。log(count)5)5})c(Graph(initoptsopts。InitOpts(1280px,960px))。add(,nodes,links,repulsion50))c。render(tmp2。html)
  Word2Vec分析
  Word2Vec是一款将词表征为实数值向量的高效工具,接下来,我们将使用它来处理这些小说。
  gensim包提供了一个Python版的实现。源代码地址:https:github。comRaReTechnologiesgensim官方文档地址:http:radimrehurek。comgensim
  之前我有使用gensim包进行了相似文本的匹配,有兴趣可查阅:《批量模糊匹配的三种方法》Word2Vec训练模型
  首先我要将所有小说的段落分词后添加到组织到一起(前面的程序可以重启):importjiebadefloadnovel(novel):withopen(fnovels{novel}。txt,encodingu8)asf:returnf。read()withopen(datanames。txt,encodingutf8)asf:dataf。read()。splitlines()novelsdata〔::2〕names〔〕forlineindata〔1::2〕:names。extend(line。split())withopen(datakungfu。txt,encodingutf8)asf:dataf。read()。splitlines()kungfus〔〕forlineindata〔1::2〕:kungfus。extend(line。split())withopen(databangs。txt,encodingutf8)asf:dataf。read()。splitlines()bangs〔〕forlineindata〔1::2〕:bangs。extend(line。split())fornameinnames:jieba。addword(name)forkungfuinkungfus:jieba。addword(kungfu)forbanginbangs:jieba。addword(bang)去重nameslist(set(names))kungfuslist(set(kungfus))bangslist(set(bangs))sentences〔〕fornovelinnovels:print(f处理:{novel})forlineinloadnovel(novel)。splitlines():sentences。append(jieba。lcut(line))处理:书剑恩仇录处理:碧血剑处理:射雕英雄传处理:神雕侠侣处理:雪山飞狐处理:飞狐外传处理:白马啸西风处理:倚天屠龙记处理:鸳鸯刀处理:天龙八部处理:连城诀处理:侠客行处理:笑傲江湖处理:鹿鼎记处理:越女剑
  接下面我们使用Word2Vec训练模型:importgensimmodelgensim。models。Word2Vec(sentences)
  我这边模型训练耗时15秒,若训练耗时较长可以把训练好的模型存到本地:model。save(louischa。model)
  以后可以直接从本地磁盘读取模型:modelgensim。models。Word2Vec。load(louischa。model)
  有了模型,我们可以进行一些简单而有趣的测试。
  注意:每次生成的模型有一定随机性,后续结果根据生成的模型而变化,并非完全一致。相似角色、门派和武功
  首先看与乔(萧)峰相似的角色:model。wv。mostsimilar(positive〔乔峰,萧峰〕)〔(段正淳,0。8006908893585205),(张翠山,0。8000873923301697),(虚竹,0。7957292795181274),(赵敏,0。7937390804290771),(游坦之,0。7803780436515808),(石破天,0。777414858341217),(令狐冲,0。7761642932891846),(慕容复,0。7629764676094055),(贝海石,0。7625609040260315),(钟万仇,0。7612598538398743)〕
  再看看与阿朱相似的角色:model。wv。mostsimilar(positive〔阿朱,蛛儿〕)〔(殷素素,0。8681862354278564),(赵敏,0。8558328747749329),(木婉清,0。8549383878707886),(王语嫣,0。8355365991592407),(钟灵,0。8338050842285156),(小昭,0。8316497206687927),(阿紫,0。8169034123420715),(程灵素,0。8153879642486572),(周芷若,0。8046135306358337),(段誉,0。8006759285926819)〕
  除了角色,我们还可以看看门派:model。wv。mostsimilar(positive〔丐帮〕)〔(恒山派,0。8266139626502991),(门人,0。8158190846443176),(天地会,0。8078100085258484),(雪山派,0。8041207194328308),(魔教,0。7935695648193359),(嵩山派,0。7908961772918701),(峨嵋派,0。7845258116722107),(红花会,0。7830792665481567),(星宿派,0。7826651930809021),(长乐帮,0。7759961485862732)〕
  还可以看看与降龙十八掌相似的武功秘籍:model。wv。mostsimilar(positive〔降龙十八掌〕)〔(空明拳,0。9040402770042419),(打狗棒法,0。9009960293769836),(太极拳,0。8992120623588562),(八卦掌,0。8909589648246765),(一阳指,0。8891675472259521),(七十二路,0。8713394999504089),(绝招,0。8693119287490845),(胡家刀法,0。8578060865402222),(六脉神剑,0。8568121194839478),(七伤拳,0。8560649156570435)〕
  在Word2Vec的模型里,有过中国北京法国巴黎的例子,我们看看段誉和段公子类似于乔峰和什么的关系呢?deffindrelationship(a,b,c):d,model。wv。mostsimilar(positive〔b,c〕,negative〔a〕)〔0〕print(f{a}{b}犹如{c}{d})findrelationship(段誉,段公子,乔峰)段誉段公子犹如乔峰乔帮主
  类似的还有:情侣对findrelationship(郭靖,黄蓉,杨过)岳父女婿findrelationship(令狐冲,任我行,郭靖)非情侣findrelationship(郭靖,华筝,杨过)郭靖黄蓉犹如杨过小龙女令狐冲任我行犹如郭靖黄药师郭靖华筝犹如杨过郭芙
  查看韦小宝相关的关系:韦小宝findrelationship(杨过,小龙女,韦小宝)findrelationship(令狐冲,盈盈,韦小宝)findrelationship(张无忌,赵敏,韦小宝)findrelationship(郭靖,黄蓉,韦小宝)杨过小龙女犹如韦小宝康熙令狐冲盈盈犹如韦小宝方怡张无忌赵敏犹如韦小宝阿紫郭靖黄蓉犹如韦小宝丁珰
  门派武功之间的关系:findrelationship(郭靖,降龙十八掌,黄蓉)findrelationship(武当,张三丰,少林)findrelationship(任我行,魔教,令狐冲)郭靖降龙十八掌犹如黄蓉打狗棒法武当张三丰犹如少林玄慈任我行魔教犹如令狐冲恒山派聚类分析人物聚类分析
  之前我们使用Word2Vec将每个词映射到了一个向量空间,因此,我们可以利用这个向量表示的空间,对这些词进行聚类分析。
  首先取出所有角色对应的向量空间:allnames〔〕wordvectors〔〕fornameinnames:ifnameinmodel。wv:allnames。append(name)wordvectors。append(model。wv〔name〕)allnamesnp。array(allnames)wordvectorsnp。vstack(wordvectors)
  聚类算法有很多,这里我们使用基本的Kmeans算法进行聚类,如果只分成3类,那么很明显地可以将众人分成主角,配角,跑龙套的三类:fromsklearn。clusterimportKMeansimportpandasaspdN3labelsKMeans(N)。fit(wordvectors)。labelsdfpd。DataFrame({name:allnames,label:labels})forlabel,namesindf。groupby(label)。name:print(f类别{label}共{len(names)}个角色,前100个角色有:{,。join(names〔:100〕)})类别0共103个角色,前100个角色有:李秋水,向问天,马钰,顾金标,丁不四,耶律齐,谢烟客,陈正德,殷天正,洪凌波,灵智上人,闵柔,公孙止,完颜萍,梅超风,鸠摩智,冲虚,冯锡范,尹克西,陆冠英,王剑英,左冷禅,商老太,尹志平,徐铮,灭绝师太,风波恶,袁紫衣,殷梨亭,宋青书,阿九,韩小莹,乌老大,杨康,何铁手,范遥,朱聪,郝大通,周仲英,风际中,何太冲,张召重,一灯大师,田归农,尼摩星,霍都,潇湘子,梅剑和,南希仁,玄难,纪晓芙,韩宝驹,邓百川,裘千尺,朱子柳,宋远桥,渡难,俞岱岩,武三通,云中鹤,余沧海,花铁干,杨逍,段延庆,巴天石,东方不败,归辛树,梁子翁,赵志敬,韦一笑,赵半山,丘处机,武修文,侯通海,鲁有脚,石清,彭连虎,胖头陀,达尔巴,裘千仞,金花婆婆,金轮法王,木高峰,苗人凤,任我行,王处一,柯镇恶,樊一翁,黄药师,欧阳克,张三丰,曹云奇,沙通天,文泰来,白万剑,鹿杖客,陆菲青,班淑娴,商宝震,全金发类别1共6个角色,前100个角色有:渔人,汉子,少妇,胖子,大汉,农夫类别2共56个角色,前100个角色有:张无忌,余鱼同,慕容复,木婉清,田伯光,郭襄,周伯通,陈家洛,乔峰,张翠山,丁珰,游坦之,岳不群,黄蓉,洪七公,岳灵珊,周芷若,马春花,杨过,阿紫,阿朱,赵敏,令狐冲,段正淳,水笙,石破天,徐天宏,程灵素,林平之,双儿,郭靖,袁承志,胡斐,陆无双,狄云,霍青桐,王语嫣,萧峰,李沅芷,骆冰,李莫愁,周绮,丁典,韦小宝,段誉,戚芳,小龙女,钟灵,殷素素,李文秀,谢逊,穆念慈,郭芙,方怡,仪琳,虚竹类别3共236个角色,前100个角色有:空智,章进,澄观,薛鹊,秃笔翁,曲非烟,田青文,郭啸天,陆大有,方证,阿碧,陶子安,吴三桂,钱老本,马行空,洪胜海,张勇,瑞大林,包不同,慕容景岳,康广陵,施琅,陆高轩,袁冠南,张康年,桃花仙,定逸,执法长老,范蠡,钟镇,陈达海,桃根仙,阿曼,李四,札木合,吴之荣,哈合台,传功长老,卓天雄,茅十八,风清扬,崔希敏,方生,王进宝,葛尔丹,常金鹏,秦红棉,薛慕华,侍剑,孙仲寿,范一飞,归二娘,孙不二,吴六奇,杨铁心,万震山,单正,玄寂,武敦儒,刘正风,西华子,樊纲,店伴,何足道,小昭,孙婆婆,苏普,谭婆,朱九真,耶律洪基,圆真,萧中慧,都大锦,司马林,叶二娘,安大娘,张三,杨成协,掌棒龙头,福康安,玉林,顾炎武,马超兴,殷离,莫声谷,郑萼,桃干仙,华筝,计无施,苏鲁克,费要多罗,苏荃,玄慈,卫璧,马光佐,常遇春,沐剑声,包惜弱,朱长龄,褚万里
  我们可以根据每个类别的角色数量的相对大小,判断该类别的角色是属于主角,配角还是跑龙套。
  下面我们过滤掉众龙套角色之后,重新聚合成四类:cpd。Series(labels)。mode()。iat〔0〕remainnamesallnames〔labels!c〕remainvectorswordvectors〔labels!c〕remainlabelKMeans(4)。fit(remainvectors)。labelsdfpd。DataFrame({name:remainnames,label:remainlabel})forlabel,namesindf。groupby(label)。name:print(f类别{label}共{len(names)}个角色,前100个角色有:{,。join(names〔:100〕)})类别0共103个角色,前100个角色有:李秋水,向问天,马钰,顾金标,丁不四,耶律齐,谢烟客,陈正德,殷天正,洪凌波,灵智上人,闵柔,公孙止,完颜萍,梅超风,鸠摩智,冲虚,冯锡范,尹克西,陆冠英,王剑英,左冷禅,商老太,尹志平,徐铮,灭绝师太,风波恶,袁紫衣,殷梨亭,宋青书,阿九,韩小莹,乌老大,杨康,何铁手,范遥,朱聪,郝大通,周仲英,风际中,何太冲,张召重,一灯大师,田归农,尼摩星,霍都,潇湘子,梅剑和,南希仁,玄难,纪晓芙,韩宝驹,邓百川,裘千尺,朱子柳,宋远桥,渡难,俞岱岩,武三通,云中鹤,余沧海,花铁干,杨逍,段延庆,巴天石,东方不败,归辛树,梁子翁,赵志敬,韦一笑,赵半山,丘处机,武修文,侯通海,鲁有脚,石清,彭连虎,胖头陀,达尔巴,裘千仞,金花婆婆,金轮法王,木高峰,苗人凤,任我行,王处一,柯镇恶,樊一翁,黄药师,欧阳克,张三丰,曹云奇,沙通天,文泰来,白万剑,鹿杖客,陆菲青,班淑娴,商宝震,全金发类别1共6个角色,前100个角色有:渔人,汉子,少妇,胖子,大汉,农夫类别2共56个角色,前100个角色有:张无忌,余鱼同,慕容复,木婉清,田伯光,郭襄,周伯通,陈家洛,乔峰,张翠山,丁珰,游坦之,岳不群,黄蓉,洪七公,岳灵珊,周芷若,马春花,杨过,阿紫,阿朱,赵敏,令狐冲,段正淳,水笙,石破天,徐天宏,程灵素,林平之,双儿,郭靖,袁承志,胡斐,陆无双,狄云,霍青桐,王语嫣,萧峰,李沅芷,骆冰,李莫愁,周绮,丁典,韦小宝,段誉,戚芳,小龙女,钟灵,殷素素,李文秀,谢逊,穆念慈,郭芙,方怡,仪琳,虚竹类别3共236个角色,前100个角色有:空智,章进,澄观,薛鹊,秃笔翁,曲非烟,田青文,郭啸天,陆大有,方证,阿碧,陶子安,吴三桂,钱老本,马行空,洪胜海,张勇,瑞大林,包不同,慕容景岳,康广陵,施琅,陆高轩,袁冠南,张康年,桃花仙,定逸,执法长老,范蠡,钟镇,陈达海,桃根仙,阿曼,李四,札木合,吴之荣,哈合台,传功长老,卓天雄,茅十八,风清扬,崔希敏,方生,王进宝,葛尔丹,常金鹏,秦红棉,薛慕华,侍剑,孙仲寿,范一飞,归二娘,孙不二,吴六奇,杨铁心,万震山,单正,玄寂,武敦儒,刘正风,西华子,樊纲,店伴,何足道,小昭,孙婆婆,苏普,谭婆,朱九真,耶律洪基,圆真,萧中慧,都大锦,司马林,叶二娘,安大娘,张三,杨成协,掌棒龙头,福康安,玉林,顾炎武,马超兴,殷离,莫声谷,郑萼,桃干仙,华筝,计无施,苏鲁克,费要多罗,苏荃,玄慈,卫璧,马光佐,常遇春,沐剑声,包惜弱,朱长龄,褚万里
  每次运行结果都不一样,大家可以调整类别数量继续测试。从结果可以看到,反派更倾向于被聚合到一起,非正常姓名的人物更倾向于被聚合在一起,主角更倾向于被聚合在一起。人物层级聚类
  现在我们采用层级聚类的方式,查看人物间的层次关系,这里同样龙套角色不再参与聚类。
  层级聚类调用scipy。cluster。hierarchy中层级聚类的包,在此之前先解决matplotlib中文乱码问题:importmatplotlib。pyplotaspltmatplotlibinlineplt。rcParams〔font。sansserif〕〔SimHei〕plt。rcParams〔axes。unicodeminus〕False
  接下来调用代码为:importscipy。cluster。hierarchyasschysch。linkage(remainvectors,methodward),axplt。subplots(figsize(10,80))zsch。dendrogram(y,orientationright)idxz〔leaves〕ax。setxticks(〔〕)ax。setyticklabels(remainnames〔idx〕,fontdict{fontsize:12})ax。setframeon(False)plt。show()
  然后我们可以得到金庸小说宇宙的人物层次关系地图,结果较长仅展示一部分结果:
  当然所有小说混合产生的平行宇宙中,人物关系变得有些混乱,读者有兴趣可以拿单本小说作层次分析,就可以得到较为准确的人物层次关系。武功层级聚类
  对各种武功作与人物层次聚类相同的操作:allnames〔〕wordvectors〔〕fornameinkungfus:ifnameinmodel。wv:allnames。append(name)wordvectors。append(model。wv〔name〕)allnamesnp。array(allnames)wordvectorsnp。vstack(wordvectors)Ysch。linkage(wordvectors,methodward),axplt。subplots(figsize(10,40))Zsch。dendrogram(Y,orientationright)idxZ〔leaves〕ax。setxticks(〔〕)ax。setyticklabels(allnames〔idx〕,fontdict{fontsize:12})ax。setframeon(False)plt。show()
  结果较长,仅展示部分结果:
  可以看到,比较少的黄色部分明显是主角比较厉害的武功,而绿色比较多的部分基本都是配角的武功。门派层次聚类
  最后我们对门派进行层次聚类:allnames〔〕wordvectors〔〕fornameinbangs:ifnameinmodel。wv:allnames。append(name)wordvectors。append(model。wv〔name〕)allnamesnp。array(allnames)wordvectorsnp。vstack(wordvectors)Ysch。linkage(wordvectors,methodward),axplt。subplots(figsize(10,25))Zsch。dendrogram(Y,orientationright)idxZ〔leaves〕ax。setxticks(〔〕)ax。setyticklabels(allnames〔idx〕,fontdict{fontsize:12})ax。setframeon(False)plt。show()
  比较少的这一类,基本都是在某几部小说中出现的主要门派,而大多数门派都是打酱油的。总结
  本文从金庸小说数据的采集,到普通的频次分析、剧情分析、关系分析,再到使用词向量空间分析相似关系,最后使用scipy进行所有小说的各种层次聚类。

北京环球影城筹备了多久?环球影城亚洲有几座?一文揭秘9月20日,全世界第五座环球影城在北京正式开园迎客,成为两节期间最热的旅游目的地之一。100多年前,环球影城从好莱坞诞生,发展至今已成为世界上最大的以电影题材为核心的主题乐园,……已经52岁的年纪,却依旧美得像个少女,许晴的减龄要点值得学细数娱乐圈的冻龄美魔女,无论以什么标准排名,许晴的名字也必定会出现在名单前列。时间仿佛待她分外温柔,经年累月地流淌而过,只是为她增添了更多风韵,而没有为她刻下衰老的深痕,以至于……琅琊榜一件事告诉你,为何梅长苏不可能接受宫羽文剧灵小筑电视剧中,宫羽有多喜欢梅长苏大家都看得出来。相对应的,梅长苏有多想要强调两个人之间的距离,大家也看得出来。最后,这两个人之间的基调从单纯的宗主和下属……秦朝的十大黑科技,究竟有多逆天?随着社会的不断进步,特别是互联网日新月异的发展,很多人都会对一个词不陌生,这个词就是黑科技。通俗来说,黑科技就是以现在的科技水平不可能出现的东西,结果却出现了。早在两千多……王者荣耀自己打脸,司马懿再次被削弱,3处调整中有2处是在搞笑文静海君策划再次打了自己的脸,用一个莫须有的理由又一次削弱了司马懿。为什么我会说策划是自己打自己的脸呢?为什么我又说司马懿的3处调整中有2处是搞笑呢?请列位往下看。司马懿……苏联解体30年后各国的足球发展!俄罗斯乌克兰大赛成绩最好转眼间,2021年已到了尾声,但其实今年12月26日,正是前苏联正式宣告解体的30周年。苏联解体后,一众加盟国都成为独立国家,亦令欧洲球坛一下子多了15支国家队;转眼间,苏联已……DOTA21战平YBB北京时间12月23日,在昨天虎牙DOTA2冬季邀请赛迎来预选赛最后一个比赛日,本日共进行三场比赛,首场比赛由Aster。A对阵YBB。赛前Aster。A在昨天战平Magma,0……NBA现役6大前锋入选名人堂的概率!詹杜100,安东尼仅第3对于所有征战NBA的球员来说,入选名人堂都是他们职业生涯最至高无上的荣誉,甚至比夺取NBA总冠军还要重要。但是能够入选名人堂的球员也是寥寥无几,尽管联盟中涌现了很多球星,但是只……价值超过1亿美元的三位女明星,你知道是谁吗?价值超过1亿美元的三位女明星第一关晓彤关晓彤1997年9月17日出生于北京。童星的首次亮相积累了很多资源,我还记得她在大学时给自己买了一辆价值数百万美元的汽车……北京冬奥会火种走进北京邮电大学当日,北京2022年冬奥会火种展示活动在北京邮电大学举办,现场展示了北京冬奥会火种灯、火炬和火炬手制服。12月9日拍摄的展示活动现场。新华社记者张晨霖摄12月9日,……光遇白雪斗篷是真香?缝合不妨碍喜欢,搭配白棉裤YYDS光遇:白雪斗篷是真香?缝合不妨碍喜欢,搭配白棉裤YYDS前言:大家好,我是喜欢玩游戏、聊游戏的孟婆小叔。今天讨论的话题,可能会让很多人不高兴。毕竟白雪斗,有缝……当红歌手的尴尬看似火的人尽皆知,其实根本没有代表作自上世纪90年代起,内地歌坛迅速崛起,尤其是最近几年,涌现出了许多有潜力的新星,共同营造了一副繁荣的景象。对于歌星来说,有一首能够为人传唱的代表作,无疑是最大的成功。比如……
新疆举报社保领域违法违规问题最高奖励可达10万元天山网讯近日,自治区人力资源和社会保障厅印发《新疆维吾尔自治区社会保险基金监督举报奖励实施细则》。《细则》明确了奖励标准。举报奖励标准根据查证属实违法违规行为所造成的社会……暴雪是懂止损的,玩家是真韭菜3月28日,动视暴雪调整,推出了新的全球服,对于注册为港澳地区的玩家,支持了微信和支付宝,以人民币结算。这一举措的指向性很明显了。动视暴雪和网易闹掰分手后,国服停运,短时……露营拖车romotow露营拖车向外旋转,形成宽敞的甲板休息室不用华丽的文字来表达项目,平白实在才是真理!!!我是KOL勾勾手刘志广,用粤语来写作!看不明白,请多看香港电视或多唱粤语歌Nofancywordstoexpressthe……量子技术发展重要里程碑科学家成功控制量子光科技日报北京3月21日电(记者张佳欣)澳大利亚悉尼大学和瑞士巴塞尔大学的科学家首次展示了识别和操纵少量相互作用的光子(光能包)的能力,这些光子具有高度相关性。这一史无前例的成就……海藻纤维抑菌内衣,近年来备受瞩目的新型内衣海藻纤维抑菌内衣是近年来备受瞩目的新型内衣产品,它的主要原料是从海洋中提取的海藻纤维,经过特殊处理后加入一定比例的抗菌因子制成的。这种内衣以其柔软舒适、透气性好、抗菌性强等特点……你所不知道的生物多样性探索地球上的生命宝库地球是一个充满奇迹和生机勃勃的行星,生物多样性是地球上最重要的生命资产之一。在广阔的自然环境中,各种不同的生物形态、习性、生活方式都在展示着其丰富的多样性。然而,由于人类活动的……零基础Python到全栈读取文件文件路径了解完之后,我们接着来看这个open功能。前面我们知道只要一个名字加一个括号,就意味着触发了一个功能的运行,只要是一个功能运行,就可能有返回值对吧。比如我们……手机颜值,vivo和OPPO更喜欢谁?这5款都出色如果您喜欢,可以点击上面的关注二字。后续会为您提供更多有价值的内容。今天分享,手机颜值,vivo和OPPO更喜欢谁?这5款都出色。第一款:vivoiQOONeo6SE……又一华为浮出水面!4nm芯片年底量产,比尔盖茨没有低估中企起步虽晚,但却能在通讯、半导体领域实现对西方企业的反超,这让华为成了老美眼中的肉中刺。常规来讲,作为科技灯塔的美国应该推动美技术快速发展实现对华为的反超,但强盗逻辑作祟,老美选……无间演员们的演技符合预期吗又一部谍战剧来袭了,今晚开播的《无间》可以说是非常让人期待。作为谍战剧,正反派之间的过招、战场上的勾心斗角一直都是谍战剧的看点之一,而这也非常考验演员们的演技,那么《无间》中有……内维尔B费下半场表现是耻辱,作为曼联球员不会以07输球在此前结束的一场英超双红会的比赛中,曼联07输给了利物浦。本场比赛结束之后,内维尔也对比赛发表了评论。内维尔在采访中这样表示:我不得不说,这场比赛曼联的表现真是一团糟。B……走啊!逛夜市去来源:人民网贵州频道原创稿整齐摆放的夜市摊。人民网顾兰云摄越来越难见到的传统爆米花制作。人民网顾兰云摄夜市小吃。人民网顾兰云摄夜市小吃。人民网顾兰云摄……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网