第一次看到老师给的题目的时候,我就很怀疑:通过每个章回虚词出现的频率(频数),就能判别是否是同一作者?

大概出现的虚词:

cell=['之','其','或','亦','方','于','即','皆','因','仍','故','尚','乃','呀','吗','咧','罢咧','啊','罢','罢了','么','呢','了','的','着','一','不','把','让','向','往','是','在','别','好','可','便','就','但','越','再','更','比','很','偏','儿']

当然,首先考虑到:比如说“之”这个字,就有很多用法,1 助词 2动词 3代词,而动词是不属于虚词的,但是怎么判断文章中出现的”之“是不是虚词呢?好像得用到语义分析,但是某文智系统都不靠谱:

就算了吧,就简单实现一下对特定的这45个字(词)的每章回出现的频率(频数)进行统计就完事了。

先挖个坑,如果以后有时间的话,研究研究文本的特征挖掘,写个[下](估计是不太可能了)。

首先,读入txt文件。[该txt中一行代表一个段落]

file=open('redmansiondream.txt',encoding="ansi")
file_context=file.readlines()

这样就把txt中的信息存到列表file_context里了,每个内容代表一个段落中所有的文字。

其次,使用正则表达式分割file_context,本代码采用的是判断”第XXX回“出现的段号,即file_context中内容为"第XXX回"的下标,并把每回的开始段号和结束段号存储在二维数组中。

(ps:习惯了C和mat的for循环  python的for不太习惯 所以循环都是用的while)

t=0 #第t回
#提取每个章回的开始结束段号
while i<len(file_context):key=re.compile(u'第[\u4e00-\u9fa5]{0,6}回') #正则表达式查找字符串‘第X回’ 其中X长度为[0,6]pa=re.findall(key,file_context[i])if (len(pa)==1) & (file_context[i][0]=='第')& (len(file_context[i])<30):#因内容中有提及之前章回之嫌,判断字符串是否位于段首t=t+1index[t-1][0]=i#开始段号if t!=1:index[t-2][1]=i #结束段号i=i+1
index[119][1]=len(file_context)-2 #最后一回段号

这样,我们就得出了每一回的起始段号和结束段号,就相当于实现了”分割“。

之后,对于每一回,分别计算出45个指定的字出现的次数,并储存在二维数组中。

data1 储存频率,data2储存频数

i=0
while i<120:start=index[i][0]+1end=index[i][1]num=0;#统计该章回总共字数 回车符不计while start<end:#统计该章回每一段的词频num=num+len(file_context[int(start)])-1;start=start+1c=0while c<len(cell):data2[i][c]=data2[i][c]+len(re.findall(cell[c],file_context[int(start)])) #匹配得到的次数累加c=c+1#得出的结果  比如 '罢'的次数中包括'罢咧'的次数 应减减去k1=0while k1<len(cell):k2=0while k2<len(cell):if k1!=k2:if (cell[k1] in cell[k2])==True: #判断是否是子串 如果是  前者的值变为前者的值减后者的值data2[i][k1]=data2[i][k1]-data2[i][k2]k2=k2+1k1=k1+1#求频率k=0while k<len(cell):data1[i][k]=data2[i][k]*1000/num; #数值太小 统一乘以1000k=k+1;i=i+1

从而得出频率和频数。

首先使用K-means算法进行聚类:

自己写的k-means(有点长乱,可以略过):

#2_means-----(频数版)
k1=np.zeros(46)
k2=np.zeros(46)
i=0
#随机初始化2类均值 直接指定第11段为一类 101段为2类
while i<len(cell):k1[i]=data2[10][i]k2[i]=data2[100][i]i=i+1
classi=np.zeros(120) #每一回章所属于的类别 取值 1或 2
while True:ret=1 #判断是否退出循环的条件d=0while d<len(data2):c=0dis1=0 dis2=0while c<len(cell):dis1+=(data2[d][c]-k1[c])*(data2[d][c]-k1[c])dis2+=(data2[d][c]-k2[c])*(data2[d][c]-k2[c])c=c+1dis1=math.sqrt(dis1)dis2=math.sqrt(dis2)class_old=classi[d]if dis1<=dis2:classi[d]=1else:classi[d]=2if class_old!=classi[d]:ret=0d=d+1#重新计算两类均值 先清0num1=0num2=0com=0i=0while i<len(cell):k1[i]=0k2[i]=0i=i+1while com<len(classi):if classi[com]==1:num1+=1cop=0while cop<len(k1):k1[cop]+=data2[com][cop];cop+=1else:num2+=1cop=0while cop<len(k1):k2[cop]+=data2[com][cop];cop+=1com+=1cop=0while cop<len(cell):k1[cop]=math.sqrt(k1[cop])k2[cop]=math.sqrt(k2[cop])cop+=1if ret==1:breaki=0
直接使用sklearn自带的包:

from sklearn.cluster import KMeans
model=KMeans(n_clusters=2)
s=model.fit(data2)
print(model.labels_)

最后两者分别得出的结果如下:

总体看来这两个类分布的错落有致,无法区分(我就说怎么可能靠谱)

试试用决策树分类的效果:令前10个为1类(label 0),后10个为2类(label 1),对中间100回进行预测:

from sklearn.ensemble import RandomForestRegressor
X_train=np.concatenate((data2[:10],data2[110:]),0)
Y_train=np.array([0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,])
rf=RandomForestRegressor(46)
rf.fit(X_train,Y_train)
X_test=np.concatenate((data2[10:50],data2[50:110]),0)
Y_test=rf.predict(X_test)
i=0
while i<len(Y_test):Y_test[i]=round(Y_test[i])i=i+1

结果如下:

貌似效果和K-means差不多。

然后再试试层次聚类的效果:

import scipy.cluster.hierarchy as sch
import matplotlib.pylab as plt
disMat = sch.distance.pdist(data2,'euclidean')
Z=sch.linkage(disMat,method='average')
P=sch.dendrogram(Z)
plt.savefig('C:/Users/71405/Desktop/大数据分析/14/plot_dendrogram.png')

结果:

(啥都看不清。。。。)

就这样了,效果很差,以后有时间研究一下特征提取,来代替虚词词频。

完整的越到后越懒得写注释的代码:

# -*- coding: utf-8 -*-
"""
Created on Thu May 31 08:24:07 2018@author: Type真是太帅了
"""
import re
import numpy as np
import math
data1=np.zeros((120,46)) #储存120回中的46个虚词的出现频率
data2=np.zeros((120,46)) #储存120回中的46个虚词的出现频数
index=np.zeros((120,2)) #统计每回开始的段号和结束的段号(均不包括)
cell=['之','其','或','亦','方','于','即','皆','因','仍','故','尚','乃','呀','吗','咧','罢咧','啊','罢','罢了','么','呢','了','的','着','一','不','把','让','向','往','是','在','别','好','可','便','就','但','越','再','更','比','很','偏','儿']
file=open('redmansiondream.txt',encoding="ansi")
file_context=file.readlines() #把所有内容读入到file_context里
i=1
t=0 #第t回
#提取每个章回的开始结束段号
while i<len(file_context):key=re.compile(u'第[\u4e00-\u9fa5]{0,6}回') #正则表达式查找字符串‘第X回’ 其中X长度为[0,6]pa=re.findall(key,file_context[i])if (len(pa)==1) & (file_context[i][0]=='第')& (len(file_context[i])<30):#因内容中有提及之前章回之嫌,判断字符串是否位于段首t=t+1index[t-1][0]=i#开始段号if t!=1:index[t-2][1]=i #结束段号i=i+1
index[119][1]=len(file_context)-2 #最后一回段号i=0
while i<120:start=index[i][0]+1end=index[i][1]num=0;#统计该章回总共字数 回车符不计while start<end:#统计该章回每一段的词频num=num+len(file_context[int(start)])-1;start=start+1c=0while c<len(cell):data2[i][c]=data2[i][c]+len(re.findall(cell[c],file_context[int(start)])) #匹配得到的次数累加c=c+1#得出的结果  比如 '罢'的次数中包括'罢咧'的次数 应减减去k1=0while k1<len(cell):k2=0while k2<len(cell):if k1!=k2:if (cell[k1] in cell[k2])==True: #判断是否是子串 如果是  前者的值变为前者的值减后者的值data2[i][k1]=data2[i][k1]-data2[i][k2]k2=k2+1k1=k1+1#求频率k=0while k<len(cell):data1[i][k]=data2[i][k]*1000/num; #数值太小 统一乘以1000k=k+1;i=i+1#2_means-----(频数版)
k1=np.zeros(46)
k2=np.zeros(46)
i=0
#随机初始化2类均值
while i<len(cell):k1[i]=data2[10][i]k2[i]=data2[100][i]i=i+1
classi=np.zeros(120) #每一回章所属于的类别 取值 1或 2
while True:ret=1 #判断是否退出循环的条件d=0while d<len(data2):c=0dis1=0 dis2=0while c<len(cell):dis1+=(data2[d][c]-k1[c])*(data2[d][c]-k1[c])dis2+=(data2[d][c]-k2[c])*(data2[d][c]-k2[c])c=c+1dis1=math.sqrt(dis1)dis2=math.sqrt(dis2)class_old=classi[d]if dis1<=dis2:classi[d]=1else:classi[d]=2if class_old!=classi[d]:ret=0d=d+1#重新计算两类均值 先清0num1=0num2=0com=0i=0while i<len(cell):k1[i]=0k2[i]=0i=i+1while com<len(classi):if classi[com]==1:num1+=1cop=0while cop<len(k1):k1[cop]+=data2[com][cop];cop+=1else:num2+=1cop=0while cop<len(k1):k2[cop]+=data2[com][cop];cop+=1com+=1cop=0while cop<len(cell):k1[cop]=math.sqrt(k1[cop])k2[cop]=math.sqrt(k2[cop])cop+=1if ret==1:breaki=0from sklearn.cluster import KMeans
model=KMeans(n_clusters=2)
s=model.fit(data2)
print(model.labels_)from sklearn.ensemble import RandomForestRegressor
X_train=np.concatenate((data2[:10],data2[110:]),0)
Y_train=np.array([0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,])
rf=RandomForestRegressor(46)
rf.fit(X_train,Y_train)
X_test=np.concatenate((data2[10:50],data2[50:110]),0)
Y_test=rf.predict(X_test)
i=0
while i<len(Y_test):Y_test[i]=round(Y_test[i])i=i+1import scipy.cluster.hierarchy as sch
import matplotlib.pylab as plt
disMat = sch.distance.pdist(data2,'euclidean')
Z=sch.linkage(disMat,method='average')
P=sch.dendrogram(Z)
plt.savefig('C:/Users/71405/Desktop/大数据分析/14/plot_dendrogram.png')

聚类简单实现对《红楼梦》是否同一作者的分析(上)相关推荐

  1. python分析红楼梦中人物形象_红楼梦中四个人物形象分析

    1 贾宝玉人物分析 通过认真品读石头记, 我认为把贾宝玉作以上评价是不客观. 不合实际的, 是有悖于曹雪芹 本意的. 在我看来, 贾宝玉是一个充满爱心的, 敢于向森严的封建等级制度挑战的革命英雄, 这 ...

  2. python分析红楼梦中人物形象_红楼梦中贾宝玉的人物形象分析

    贾宝玉,中国古典名著<红楼梦>中的男主角.他是女娲补天弃在青埂峰下的一块顽石和赤霞宫神瑛侍者转世真身,荣国府贾政与王夫人所生的次子.因衔玉而诞,系贾府玉字辈嫡孙,故名贾宝玉,贾府通称宝二爷 ...

  3. python分析红楼梦中人物形象_《红楼梦》中女性人物形象分析

    探春,胸怀.文才高王熙凤一等,她有不同于其他人的远见,有着和男人一较高低的魄力.但有才有志如此的探春,最后还是远嫁他乡.庶出的身份也曾让她感到过屈辱,但是她不流俗,不孤高;不自卑,不自弃;不悲天悯人, ...

  4. 【大数据】《红楼梦》作者分析(QDU)

    [大数据]蔬菜价格分析(QDU) [大数据]美国新冠肺炎疫情分析--错误版(QDU) [大数据]美国新冠肺炎疫情分析--正确版(QDU) [大数据]乳腺癌预测--老师给的链接(QDU) 由于kaggl ...

  5. 用Python分析《红楼梦》:见证了贾府的兴衰,你是否还能“笑道”世事无常

    没读过<红楼梦>也能知道前后四十回是不是一个作者写的?很久以前,数据侠黎晨,用机器学习的算法分析了<红楼梦>,认为后四十回和前八十回内容上有明显差距.不过,数据侠楼宇却不这么认 ...

  6. python split函数 空格_python上手--10行代码读懂红楼梦

    取名10行代码看懂红楼梦,是将介绍使用python代码来读红楼梦获取其主要人物.这里的思想就是词频统计,通过分析红楼梦小说文字中出现最多的词语,来概括说明红楼梦的核心人物和事情.实际上如果你能跟着往下 ...

  7. python红楼梦人物词频统计_用 Python 分析《红楼梦》

    1 前言 两个月以来,我通过互联网自学了一些文本处理的知识,用自然语言处理和机器学习算法对<红楼梦>进行了一些分析.这个过程中我找到了一些有趣的发现,所以我想写一篇文章,既㲌与大家分享和讨 ...

  8. 红楼梦人物出场统计python_用Python分析《红楼梦》:见证贾府的兴衰

    没读过<红楼梦>也能知道前后四十回是不是一个作者写的?很久以前,数据侠黎晨,用机器学习的算法分析了<红楼梦>,认为后四十回和前八十回内容上有明显差距.不过,数据侠楼宇却不这么认 ...

  9. python红楼梦人物统计_基于共现使用Python来分析《红楼梦》中贾宝玉与金陵十二钗的关系...

    上一篇,我们使用Python分析了<三国演义>中人物出现次数(罗贯中的<三国演义>中到底谁是主角?我们使用Python来分析一下),文中我们仅仅从人物出现次数,来推断出这部作品 ...

  10. 机器学习之红楼梦作者判断(贝叶斯分类)

    上篇文章不带假设的使用聚类算法去判断红楼梦的作者,这一篇打算使用监督学习方法的贝叶斯分类,假设后四十回不是曹雪芹所写, 去做个验证. 关于我读过比较好的贝叶斯讲解:A simple explanati ...

最新文章

  1. 最后一片蓝海的终极狂欢-写在Win10发布前夕
  2. 关于如何在matlab中导入并翻译Hypemesh导出的大型刚度矩阵txt文本
  3. k2677场效应管参数引脚_共射极放大电路,场效应管放大电路,运算放大电路
  4. 使用swoole作为MQTT客户端并接收实现即时消息推送
  5. FF与IE兼容性总结(转载)
  6. 对自己深度学习方向的论文有idea,可是工程实践能力跟不上,实验搞不定怎么办?...
  7. 如何往linux上面上传东西
  8. 【亲测有效】无法定位链接器!请检查 tools\link.ini 中的配置是否正确的解决方案...
  9. python网易云付费歌曲下载_python 根据网易云歌曲的ID 直接下载歌曲的实例
  10. adminLTE的介绍
  11. 内置函数--inline
  12. kvm中raw格式转换为qcow2格式节省主机空间
  13. css写七步诗,《七步诗》改写550字
  14. Friendship 友谊--我最宝贵的财富
  15. 基于Canal+kafka监听数据库变化的最佳实践
  16. keycloak 验证 token
  17. 电脑录屏软件哪个好用,分享4款不限时长的录屏软件
  18. 文本的检测、识别实战:使用 Tesseract 进行 OpenCV OCR 和文本识别
  19. OpenGL ES glfw 下载和使用
  20. 【C语言典例】——day3:设计魔方阵(数组)

热门文章

  1. SQL Server不能通过外部IP访问,解决方法
  2. 如何利用C语言生成随机数
  3. 边缘发光材质unity_Unity Shader Graph 小功能实现(一)边缘发光
  4. Linux系统的目录树
  5. 11月14日火箭vs灰熊视频直播在线观看
  6. 隔板法详解(各种方法)
  7. Python Pandas 导入dta文件的方法
  8. 微软 Win11 22H2 (KB5017321) 更新失败并显示下载错误 0x800F0806,修复方法来了
  9. 自动取款机属于计算机领域中的,《计算机知识》真题库290题
  10. 智能擦窗机器人的社会意义_擦窗机器人的现状与应用分析