前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用Python进行分析

用Python进行分析

作者头像
数据森麟
发布2019-09-27 19:03:04
7070
发布2019-09-27 19:03:04
举报
文章被收录于专栏:数据森麟
1.影评分析

爬取影评直接使用之前蚁人的代码,不再说明,共爬到影评数据500条。

简单统计来看,一星差评最多,但四五星评价与一二星差评价基本持平。

不过从投票数来看,投票数最多的前25条,无一例外都是一星差评

大家给差评的原因也很统一,电视剧对小说改编过多,原著党难以接受,再加上5毛钱特效和演员的尴尬演技,感觉是妥妥烂片无疑了。不妨再看看给好评的人都是些神马想法

除过一些明明给了很差评价还点了力荐的观众之外,投票数最多的好评都来自于主演的粉丝,对他们来说,剧情研究都不重要,看颜就行。

2.小说文本分析

1. 人物出场频数

分析完影评,作为一名原著党,我觉得更有必要分析一下小说原文,直接百度下载到一个小说txt文件,小说共有1646章,首先来看看小说中出场次数最多的人物

男主出场次数太多,远远高于其他人物,我们不考虑主角,看看其他人物的出场次数

部分代码如下

代码语言:javascript
复制
# -*- coding: utf-8 -*-
"""
Created on Mon Sep 17 19:51:48 2018

@author: hzp0625
"""

import pandas as pd
import os
os.chdir('F:\\python_study\\pachong\\斗破苍穹')
import re
import numpy as np
import jieba
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r'c:\windows\fonts\simsun.ttc')#,size=20指定本机的汉字字体位置
import matplotlib.pyplot as plt
import networkx as nx  


texts = open('all(校对版全本).txt',"r")

texts = texts.read()

AllChapters = re.split('第[0-9]*章',texts)[1:]

AllChapters = pd.DataFrame(AllChapters,columns = ['text'])
AllChapters['n'] = np.arange(1,1647)

# 载入搜狗细胞词库
jieba.load_userdict('斗破苍穹.txt')
jieba.load_userdict('斗破苍穹异火.txt')
stopwords = open('中文停用词表(比较全面,有1208个停用词).txt','r').read()
stopwords = stopwords.split('\n')



# 主要人物出现的总频数,人物名单从百度百科获取
nameall = open('所有人物.txt','r').read().split('\n')
nameall = pd.DataFrame(nameall,columns = ['name'])
textsall = ''.join(AllChapters.text.tolist())
nameall['num'] = nameall.name.apply(lambda x:textsall.count(x))

nameall.loc[nameall.name=='熏儿','num'] = nameall.loc[nameall.name=='熏儿','num'].values[0] + nameall.loc[nameall.name=='熏儿','num'].values[0]
nameall.loc[nameall.name=='熏儿','num'] = -886



nameall.loc[nameall.name=='彩鳞','num'] = nameall.loc[nameall.name=='彩鳞','num'].values[0] + nameall.loc[nameall.name=='美杜莎','num'].values[0]
nameall.loc[nameall.name=='美杜莎','num'] = -886

nameall = nameall.sort_values('num',ascending = False)


plt.figure(figsize=(8,10))
fig = plt.axes()
n = 50
plt.barh(range(len(nameall.num[:n][::-1])),nameall.num[:n][::-1],color = 'darkred')
fig.set_yticks(np.arange(len(nameall.name[:n][::-1])))
fig.set_yticklabels(nameall.name[:n][::-1],fontproperties=font)
plt.xlabel('人物出场次数',fontproperties = font)
plt.show()

2. 女主分析

从出场频数来看,排名前4的是主角的老师和三个女主,那么究竟哪一个是女一?单从出场次数来看的话可能会太过简单,我们对小说分章节统计每章中所有女主的出场次数,来看看女主出场的时间分布,横轴为章节号,纵轴为出现次数

从分布图来看,前中期各个女主出场的重叠不多,每个人陪男主走过不同的剧情副本,结尾合家欢。

代码语言:javascript
复制
# 女主每章出现次数统计:熏儿,云韵,小医仙,彩鳞,美杜莎

names = ['熏儿','云韵','小医仙','彩鳞','美杜莎']
result['熏儿'] = result.fenci.apply(lambda x:x.count('熏儿') + x.count('薰儿'))
result['云韵'] = result.fenci.apply(lambda x:x.count('云韵'))
result['小医仙'] = result.fenci.apply(lambda x:x.count('小医仙'))
result['彩鳞'] = result.fenci.apply(lambda x:x.count('彩鳞') + x.count('美杜莎'))


plt.figure(figsize=(15,5))
plt.plot(np.arange(1,result.shape[0]+1),result['熏儿'],color="r",label = u'熏儿')
plt.plot(np.arange(1,result.shape[0]+1),result['云韵'],color="lime",label = u'云韵')
plt.plot(np.arange(1,result.shape[0]+1),result['小医仙'],color="gray",label = u'小医仙')
plt.plot(np.arange(1,result.shape[0]+1),result['彩鳞'],color="orange",label = u'彩鳞')
plt.legend(prop =font)
plt.xlabel(u'章节',fontproperties = font)
plt.ylabel(u'出现次数',fontproperties = font)
plt.show()

3. 人物社交关系网络

接下来,我们对小说中的人物关系做一些探究,如果两个人物同时出现在文章的一个段落里,我们就认为这两个人物之间有一定的联系(也可以以句或章节为单位),以此为规则,计算所有人物的共现矩阵。所以人物列表通过百度百科获取,保存为txt文件便于读取。

将小说文本按段落划分之后,会发现共有八万多个段落,人物有一百个左右,直接循环效率太低,但观察得到的段落,有很多单字成段的语气词,这些可以直接删掉。

因此,对于得到的段落,我们首先删掉段落长度小于20个字的,用剩余的段落计算共现矩阵,部分主要人物的共现矩阵如下

用所有人物的共现矩阵构造社交关系网络图,计算出边和节点矩阵后,用Gephi软件直接作图(python也可以用networkx作图)

删掉边权重小于10的值后,重新作图,结果相对清晰一些,连线越宽,表明人物见的联系越紧密。

代码语言:javascript
复制
# 社交网络图  共现矩阵
# 两个人物出现在同一段,说明有某种关系
words = open('all(校对版全本).txt','r').readlines()
words = pd.DataFrame(words,columns = ['text'],index = range(len(words)))
words['wordnum'] = words.text.apply(lambda x:len(x.strip()))
words = words.loc[words.wordnum>20,]
wrods = words.reset_index(drop = True)
relationmat = pd.DataFrame(index = nameall.name.tolist(),columns = nameall.name.tolist()).fillna(0)


wordss = words.text.tolist()
for k in range(len(wordss)):
    for i in nameall.name.tolist():
        for j in nameall.name.tolist():
            if i in wordss[k] and j in  wordss[k]:
                relationmat.loc[i,j] += 1 
    if k%1000 ==0:
        print(k)

relationmat.to_excel('共现矩阵.xlsx')

# 网络图


# 边与权重矩阵
#relationmat1 = pd.DataFrame(index = range(relation.shape[]))
relationmat1 = {}
for i in relationmat.columns.tolist():
    for j in relationmat.columns.tolist():
        relationmat1[i, j] = relationmat.loc[i,j]


edgemat = pd.DataFrame(index = range(len(relationmat1)))
node = pd.DataFrame(index = range(len(relationmat1)))

edgemat['Source'] = 0
edgemat['Target'] = 0
edgemat['Weight'] = 0

node['Id'] = 0
node['Label'] = 0
node['Weight'] = 0


names = list(relationmat1.keys())
weights = list(relationmat1.values())
for i in range(edgemat.shape[0]):
    name1 = names[i][0]
    name2 = names[i][1]
    if name1!=name2:
        edgemat.loc[i,'Source'] = name1
        edgemat.loc[i,'Target'] = name2
        edgemat.loc[i,'Weight'] = weights[i]
    else:
        node.loc[i,'Id'] = name1
        node.loc[i,'Label'] = name2
        node.loc[i,'Weight'] = weights[i]        
    i+=1


edgemat = edgemat.loc[edgemat.Weight!=0,]
edgemat = edgemat.reset_index(drop = True)
node = node.loc[node.Weight!=0,]
node = node.reset_index(drop = True)



edgemat.to_csv('边.csv',index = False)
node.to_csv('节点.csv',index = False)

4. 分词词云

最后,还是以小说文本的词云作为文章结尾,为了使文本分词更准确,这里我们使用了网上流传的包含1208个词的中文停用词表,以及通过搜狗细胞词库得到的两个词库,主要包含一些人名,地名,组织名称,异火等。

网址:https://pinyin.sogou.com/dict/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-11-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据森麟 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档