0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Python自然语言用金庸的武侠小说做分析和处理

马哥Linux运维 来源:未知 作者:李倩 2018-03-23 16:01 次阅读

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

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

所有人物的相似图连接。

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

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

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

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

2、NetworkX中分析和展示

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

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

一、分析结果

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

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

先来看看图:

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

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

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

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

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

注:

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

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

二、实现过程

主要步骤:

准备语料

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

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

停用词表

准备工具

Python Pandas, Numpy,Scipy(标准库)

Jieba(中文分词)

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

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

数据预处理

文本文件转发成utf8(pandas)

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

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

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

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

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

采用300个维度

过滤词频小于20次

滑动窗口 为20

下采样:0.001

生成实体关系矩阵。

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

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

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

NetworkX 生成网络图

节点是人名

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

三、部分代码实现

初始化

import numpy as np

import pandas as pd

import jieba

import jieba.posseg as posseg

%matplotlib inline

数据分词,清洗

renming_file = "yttlj_renming.csv"

jieba.load_userdict(renming_file)

stop_words_file = "stopwordshagongdakuozhan.txt"

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

corpus = "yttlj.txt"

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

def cut_join(s):

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

#print(list(new_s))

stop_words_extra =set([""])

for seg in new_s:

if len(seg)==1:

#print("aa",seg)

stop_words_extra.add(seg)

#print(stop_words_extra)

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

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

#过滤标点符号

#过滤停用词

result = ",".join(new_s)

return result

def extract_name(s):

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

words=[]

flags=[]

for k,v in new_s:

if len(k)>1:

words.append(k)

flags.append(v)

full_wf["word"].extend(words)

full_wf["flag"].extend(flags)

return len(words)

def check_nshow(x):

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

#print(x, nshow)

return nshow

# extract name & filter times

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

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

#tmp_w,tmp_f

df_wf = pd.DataFrame(full_wf)

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

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

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

df_wf_renming.head()

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

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

df_wf_renming[df_wf_renming.nshow>20].shape

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

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

my_renming = df_wf_renming.word.tolist()

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

combined_renming = set(my_renming) |set(external_renming)

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

combined_renming_file ="combined_renming.csv"

jieba.load_userdict(combined_renming_file)

# tokening

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

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

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

Word2Vec 向量化训练

# Set values for various parameters

num_features = 300 # Word vector dimensionality

min_word_count = 20 # Minimum word count

num_workers = 4 # Number of threads to run in parallel

context = 20 # Context window size

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

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

from gensim.models import word2vec

model_file_name = 'yttlj_model.txt'

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

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

size=num_features, min_count = min_word_count,

window = context,

sample = downsampling

)

model.save(model_file_name)

建立实体关系矩阵

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

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

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

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

ER["tmp"] = entity.Name

def check_nshow(x):

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

#print(x, nshow)

return nshow

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

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

count = 0

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

count +=1

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

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

elif count == entity.shape[0]:

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

for j in entity["Name"]:

relation =0

try:

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

ER.loc[i,j] = relation

if i!=j:

ER.loc[j,i] = relation

except:

relation = 0

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

NetworkX 展示人物关系图

import networkx as nx

import matplotlib.pyplot as plt

import pandas as pd

import numpy as np

import pygraphviz

from networkx.drawing.nx_agraph import graphviz_layout

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 机器学习
    +关注

    关注

    66

    文章

    8116

    浏览量

    130546
  • python
    +关注

    关注

    51

    文章

    4674

    浏览量

    83460
  • 自然语言
    +关注

    关注

    1

    文章

    269

    浏览量

    13203

原文标题:Python自然语言处理分析倚天屠龙记

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    python自然语言

    最近,python自然语言是越来越火了,那么什么是自然语言自然语言(Natural Language )广纳了众多技术,对自然或人类
    发表于 05-02 13:50

    NLPIR语义分析是对自然语言处理的完美理解

    和逻辑表示。语义分析就是对信息所包含的语义的识别,并建立一种计算模型,使其能够像人那样理解自然语言。语义分析自然语言理解的根本问题,它在自然语言
    发表于 10-19 11:34

    自然语言处理怎么最快入门?

    `本文整理自知乎上的一个问答,分享给正在学习自然语言处理的朋友们!一、自然语言处理是什么?自然语言
    发表于 11-28 10:02

    hanlp汉语自然语言处理入门基础知识介绍

    人工智能。自然语言处理涉及的几个层次:作为输入一共有两个来源,语音与文本。所以第一级是语音识别和OCR或分词(事实上,跳过分词虽然理所当然地不能做句法分析,但字符级也可以直接不少应用
    发表于 01-02 14:43

    语义理解和研究资源是自然语言处理的两大难题

    、情感分析、文档去重、全文检索和编码转换十三项独立功能,针对自然语言的研究,也为软件工程师提供了二次开发接口。 自然语言处理是计算机科学和人工智能领域的重要演讲方向。主要涉及人机相互的
    发表于 09-19 14:10

    【推荐体验】腾讯云自然语言处理

    自然语言处理技术的功劳。可以说,只要有大量文本数据的应用场景,几乎都涉及到NLP技术,也都可以使用相关自然语言处理产品的接口来智能
    发表于 10-09 15:28

    自然语言处理的分词方法

    自然语言处理——75 自动分词基本算法
    发表于 03-19 11:46

    自然语言处理语言模型

    自然语言处理——53 语言模型(数据平滑)
    发表于 04-16 11:11

    自然语言处理的词性标注方法

    自然语言处理——78 词性标注方法
    发表于 04-21 11:38

    Python自然语言处理学习笔记:建立基于特征的文法

    Python自然语言处理(第二版)-Steven Bird等》学习笔记:第09章 建立基于特征的文法
    发表于 04-26 12:38

    自然语言处理笔记

    自然语言处理笔记9-哈工大 关毅
    发表于 06-04 16:34

    自然语言处理——总结、习题

    自然语言处理——79 总结、习题
    发表于 06-19 11:22

    什么是自然语言处理

    会识别出我们正确说的话。 我们使用免费服务将在线遇到的外语短语翻译成英语, 有时它们可以为我们提供准确的翻译。 尽管自然语言处理取得了长足的进步,但仍有很大的改进空间。[理...
    发表于 07-23 10:22

    什么是自然语言处理

    什么是自然语言处理自然语言处理任务有哪些?自然语言处理的方法是什么?
    发表于 09-08 06:51

    自然语言处理(NLP)的学习方向

    科学、数学等于一体的科学。旨在从文本数据中提取信息。目的是让计算机处理或“理解”自然语言,以执行自动翻译、文本分类和情感分析等。自然语言处理
    的头像 发表于 07-06 16:30 1.3w次阅读