Python自然语言处理分析倚天屠龙记

2024-03-24 10:20

本文主要是介绍Python自然语言处理分析倚天屠龙记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Python中文社区
全球Python中文开发者的精神部落


最近在了解到,在机器学习中,自然语言处理是较大的一个分支。存在许多挑战。例如: 如何分词,识别实体关系,实体间关系,关系网络展示等。

我用Jieba + Word2vec + NetworkX 结合在一起,做了一次自然语言分析。语料是 倚天屠龙记。 之前也有很多人用金庸的武侠小说做分析和处理,希望带来一些不同的地方。截几张图来看看:

所有人物的相似图连接。

关系同上。展示形式为多中心结构

以张无忌的不同身份为中心的网络关系图。 

这次分析的不一样之处主要是:

1、Word2Vec的相似度结果 - 作为后期社交网络权重

2、NetworkX中分析和展示

上面两个方法结合起来,可以大幅减少日常工作中阅读文章的时间。 采用机器学习,可以从头到尾半自动抽取文章中的实体信息,节约大量时间和成本。 在各种工作中都有利用的场景, 如果感兴趣的朋友,可以联系合作。

先来看看,用Word2Vec+NetworkX 可以发现什么。

一、分析结果

实体的不同属性(张无忌的总多马甲)

张无忌,无忌,张教主,无忌哥哥,张公子。同一个张无忌有多个身份,不同身份又和不同的人联系,有不一样的相似度。

先来看看图:

无忌哥哥是过于亲密的名字,一般不喊。好似和这个词相似度高的都是比较奇怪的角色。

无忌是关系熟了以后,平辈或者长辈可以称呼的名字。还有周姑娘,殷姑娘等

张无忌是通用的名字,人人可以称呼 和马甲联系密切。

张公子是礼貌尊称。 例如,黄衫女子,汝阳王等

张教主是头衔。既要尊重,也表示其实不太熟,有时还有些敌意。 例如: 朱元璋

注:

1、图是Networkx 基于Word2vex画出来了,上面的描述是我的人工分析。 

2、赵敏不在上面的网络关系图中。Word2Vec计算出来 张无忌和赵敏 相似度不太高。有些出乎我的意料。 仔细回忆一下,当年看此书时,突然就发现二人在一起了,显得比较突兀。推想起来,书中世界二人成婚了,如果变成现实世界,二人关系比较悬。

二、实现过程

主要步骤:

准备语料

  1. 倚天屠龙记 小说的文本文件

  2. 自定义分词词典 (小说中的人物名,网上有现成的,约180个)

  3. 停用词表

准备工具

  1. Python Pandas, Numpy,Scipy(标准库)

  2. Jieba(中文分词)

  3. Word2vec (单词向量化工具,可以计算单词之间的详细度)

  4. Networks(网络图工具,用于展示复杂的网络关系

数据预处理

  1. 文本文件转发成utf8(pandas)

  2. 文本文件分句,分词(Jieba)

  3. 文本文件分句,分词, 分析词性,主要是人名(Jieba)

  4. 更新自定义词典,重新分词(整个过程需要几遍,直至满意)

  5. 手工少量删除(分词出来的人名误判率不高,但是还是存在一些。例如:赵敏笑道,可以被识别的 一个叫 赵敏笑的人。 这部分工作还需要手工做。 除非有更好的分词工具,或者可以训练的分词工具,才能解决这一问题。

Word2Vec 训练模型。这个模型可以计算两个人之间的相似度

  1. 采用300个维度

  2. 过滤词频小于20次

  3. 滑动窗口 为20

  4. 下采样:0.001

生成实体关系矩阵。

  1. 网上没找找到现成库,我就自己写了一个。

  2. N*N 维度。 N是人名数量。

  3. 用上面WordVec的模型来,填充实体关系矩阵

NetworkX 生成网络图

  1. 节点是人名

  2. 边是两个节点之间的线条。也就是两个人之间的关系。

三、部分代码实现(因篇幅有限,获取完整代码请关注公众号编程狗回复0321获取)

初始化

  
  1. import numpy as np

  2. import pandas as pd

  3. import jieba

  4. import jieba.posseg as posseg

  5. %matplotlib inline

数据分词,清洗

  
  1. renming_file = "yttlj_renming.csv"

  2. jieba.load_userdict(renming_file)

  3. stop_words_file = "stopwordshagongdakuozhan.txt"

  4. stop_words = pd.read_csv(stop_words_file,header=None,quoting=3,sep="\t")[0].values

  5. corpus = "yttlj.txt"

  6. yttlj = pd.read_csv(corpus,encoding="gb18030",header=None,names=["sentence"])

  7. def cut_join(s):

  8.    new_s=list(jieba.cut(s,cut_all=False)) #分词

  9.    #print(list(new_s))

  10.    stop_words_extra =set([""])

  11.    for seg in new_s:

  12.        if len(seg)==1:

  13.            #print("aa",seg)

  14.            stop_words_extra.add(seg)

  15.    #print(stop_words_extra)

  16.    #print(len(set(stop_words)| stop_words_extra))

  17.    new_s =set(new_s) -set(stop_words)-stop_words_extra

  18.    #过滤标点符号

  19.    #过滤停用词

  20.    result = ",".join(new_s)

  21.    return  result

  22. def extract_name(s):

  23.    new_s=posseg.cut(s) #取词性

  24.    words=[]

  25.    flags=[]

  26.    for k,v in new_s:

  27.        if len(k)>1:

  28.            words.append(k)

  29.            flags.append(v)

  30.    full_wf["word"].extend(words)

  31.    full_wf["flag"].extend(flags)

  32.    return len(words)

  33. def check_nshow(x):

  34.    nshow = yttlj["sentence"].str.count(x).sum()

  35.    #print(x, nshow)

  36.    return nshow

  37. # extract name & filter times

  38. full_wf={"word":[],"flag":[]}

  39. possible_name = yttlj["sentence"].apply(extract_name)

  40. #tmp_w,tmp_f

  41. df_wf = pd.DataFrame(full_wf)

  42. df_wf_renming = df_wf[(df_wf.flag=="nr")].drop_duplicates()

  43. df_wf_renming.to_csv("tmp_renming.csv",index=False)

  44. df_wf_renming = pd.read_csv("tmp_renming.csv")

  45. df_wf_renming.head()

  46. df_wf_renming["nshow"] = df_wf_renming.word.apply(check_nshow)

  47. df_wf_renming[df_wf_renming.nshow>20].to_csv("tmp_filtered_renming.csv",index=False)

  48. df_wf_renming[df_wf_renming.nshow>20].shape

  49. #手工编辑,删除少量非人名,分词错的人名

  50. df_wf_renming=pd.read_csv("tmp_filtered_renming.csv")

  51. my_renming = df_wf_renming.word.tolist()

  52. external_renming = pd.read_csv(renming_file,header=None)[0].tolist()

  53. combined_renming = set(my_renming) |set(external_renming)

  54. pd.DataFrame(list(combined_renming)).to_csv("combined_renming.csv",header=None,index=False)

  55. combined_renming_file ="combined_renming.csv"

  56. jieba.load_userdict(combined_renming_file)

  57. # tokening

  58. yttlj["token"]=yttlj["sentence"].apply(cut_join)

  59. yttlj["token"].to_csv("tmp_yttlj.csv",header=False,index=False)

  60. sentences = yttlj["token"].str.split(",").tolist()

Word2Vec 向量化训练

  
  1. # Set values for various parameters

  2. num_features = 300    # Word vector dimensionality                      

  3. min_word_count = 20   # Minimum word count                        

  4. num_workers = 4       # Number of threads to run in parallel

  5. context = 20          # Context window size                                                                                    

  6. downsampling = 1e-3   # Downsample setting for frequent words

  7. # Initialize and train the model (this will take some time)

  8. from gensim.models import word2vec

  9. model_file_name = 'yttlj_model.txt'

  10. #sentences = w2v.LineSentence('cut_jttlj.csv')

  11. model = word2vec.Word2Vec(sentences, workers=num_workers, \

  12.            size=num_features, min_count = min_word_count, \

  13.            window = context, \

  14.            sample = downsampling

  15.            )

  16. model.save(model_file_name)  

建立实体关系矩阵

  
  1. entity = pd.read_csv(combined_renming_file,header=None,index_col=None)

  2. entity = entity.rename(columns={0:"Name"})

  3. entity = entity.set_index(["Name"],drop=False)

  4. ER = pd.DataFrame(np.zeros((entity.shape[0],entity.shape[0]),dtype=np.float32),index=entity["Name"],columns=entity["Name"])

  5. ER["tmp"] = entity.Name

  6. def check_nshow(x):

  7.    nshow = yttlj["sentence"].str.count(x).sum()

  8.    #print(x, nshow)

  9.    return nshow

  10. ER["nshow"]=ER["tmp"].apply(check_nshow)

  11. ER = ER.drop(["tmp"],axis=1)

  12. count = 0

  13. for i in entity["Name"].tolist():

  14.    count +=1

  15.    if count % round(entity.shape[0]/10) ==0:

  16.        print("{0:.1f}% relationship has been checked".format(100*count/entity.shape[0]))

  17.    elif count == entity.shape[0]:

  18.        print("{0:.1f}% relationship has been checked".format(100*count/entity.shape[0]))

  19.    for j in entity["Name"]:

  20.        relation =0

  21.        try:

  22.            relation = model.wv.similarity(i,j)

  23.            ER.loc[i,j] = relation

  24.            if i!=j:

  25.                ER.loc[j,i] = relation

  26.        except:

  27.            relation = 0

  28. ER.to_hdf("ER.h5","ER")

NetworkX 展示人物关系图

  
  1. import networkx as nx

  2. import matplotlib.pyplot as plt

  3. import pandas as pd

  4. import numpy as np

  5. import pygraphviz

  6. from networkx.drawing.nx_agraph import graphviz_layout


本文作者

王勇,Python中文社区专栏作者,雪球ID:快乐_爸,目前感兴趣项目商业分析、Python、机器学习、Kaggle。17年项目管理,通信业干了11年项目经理管合同交付,制造业干了6年项目管理:PMO,变革,生产转移,清算和资产处理。MBA, PMI-PBA, PMP。


因篇幅有限,获取完整代码请关注公众号编程狗回复0321获取

点击下方阅读原文免费成为Python中文社区会员

这篇关于Python自然语言处理分析倚天屠龙记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/841306

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

nudepy,一个有趣的 Python 库!

更多资料获取 📚 个人网站:ipengtao.com 大家好,今天为大家分享一个有趣的 Python 库 - nudepy。 Github地址:https://github.com/hhatto/nude.py 在图像处理和计算机视觉应用中,检测图像中的不适当内容(例如裸露图像)是一个重要的任务。nudepy 是一个基于 Python 的库,专门用于检测图像中的不适当内容。该

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57