在学界一般认为,《红楼梦》后 40 回并非曹雪芹所著。利用机器学习相关算法来进行判断
原理
每个作者写作都有自己的用词习惯和风格,即使是故意模仿也会留下很多痕迹。
在文言文中,文言虚词分布均匀,书中每个回目都会出现很多文言虚词,差别在于出现频率不同,我们把文言虚词的出现频率作为特征。
不只文言虚词,还有其他的词在所有回目中出现频率很多。比如对第 80 回进行词频统计,得到

  1. 了 172
  2. 的 142
  3. 我 70
  4. 宝玉 65
  5. 你 61
  6. 道 54
  7. 他 51
    这些高频词汇也可以作为特征向量。

本文将 20~29 回(诗词曲比较均衡)作为类别 1 的学习样本,将 110~119 回作为类别 2 的学习样本。
将两个类别的特征向量输入到 SVM(支持向量机) 进行训练得出一个分类模型。再对剩余回目进行分类,看它们分别偏向于哪个类别。
分词
拿到文本数据后,先进行回合划分。然后就是去标点符号、分词,做词频统计。

#!/usr/bin/python
# -*- coding:utf-8 -*-import string
import jieba
import sys
import reclass textProcesser(object):def __init__(self):pass# 将书分为章节def divide_into_chapter(self):file_in = open('text/redmansions.txt', 'r')line = file_in.readline()chapter_cnt = 1chapter_text = ""while line:if '[(' in line:path_str = 'text/chapter-' + str(chapter_cnt)file_out = open(path_str, 'a')file_out.write(chapter_text)chapter_cnt += 1file_out.close()chapter_text = lineelse:chapter_text += lineline = file_in.readline()file_in.close# 对一章分词def divide_into_words(self, document, docID):path_str = 'text/chapter-words-' + str(docID)file_out = open(path_str,'a')line = document.readline()while(line):seg_list = jieba.cut(line, cut_all=False)words = " ".join(seg_list)file_out.write(words)line = document.readline()file_out.close()# 对所有章节分词def perform_segmentation(self):for loop in range(1, 121):path_str = 'text/chapter-' + str(loop)file_in = open(path_str, 'r')self.divide_into_words(file_in, loop)# 将每个文档去除标点后,再进行词频统计def count_words(self, document, docID):result_dict = {}delset = string.punctuationline = str(document)line = line.translate(None, delset) #去除英文标点line = "".join(line.split('\n')) # 去除回车line = self.sub_replace(line) #去除中文标点word_array = []words = line.split()for word in words:if not result_dict.has_key(word):result_dict[word] = 1else:result_dict[word] += 1path_str = 'text/chapter-wordcount-' + str(docID)file_out = open(path_str,'a')# 排序后写入文本sorted_result = sorted(result_dict.iteritems(), key=lambda d:d[1], reverse = True)for one in sorted_result:line = "".join(one[0] + '\t' + str(one[1]) + '\n')file_out.write(line)file_out.close()# 对所有文档进行分词def perform_wordcount(self):for loop in range(1, 121):path_str = 'text/chapter-words-' + str(loop)file_in = open(path_str, 'r')line = file_in.readline()document = ""while line:document += lineline = file_in.readline()self.count_words(document, loop)file_in.close()def sub_replace(self, line):regex = re.compile("[^\u4e00-\u9fa5a-zA-Z0-9\s]")return regex.sub('', line.decode('utf-8'))

特征选取

  • [
    ‘之’, ‘其’, ‘或’, ‘亦’, ‘方’, ‘于’, ‘即’, ‘皆’, ‘因’, ‘仍’,
    ‘故’, ‘尚’, ‘呢’, ‘了’, ‘的’, ‘着’, ‘一’, ‘不’, ‘乃’, ‘呀’,
    ‘吗’, ‘咧’, ‘啊’, ‘把’, ‘让’, ‘向’, ‘往’, ‘是’, ‘在’, ‘越’,
    ‘再’, ‘更’, ‘比’, ‘很’, ‘偏’, ‘别’, ‘好’, ‘可’, ‘便’, ‘就’,
    ‘但’, ‘儿’, # 42 个文言虚词
    ‘又’, ‘也’, ‘都’, ‘要’, # 高频副词
    ‘这’, ‘那’, ‘你’, ‘我’, ‘他’ # 高频代词
    ‘来’, ‘去’, ‘道’, ‘笑’, ‘说’ #高频动词
    ]
    选取常用的 42 个文言虚词和通过词频统计得到的高频使用的词作为特征,分别计算它们在各个回目中出现的频率作为特征向量。
    代码
class modelBuilder(object):def __init__(self):passdef get_wordnum_of_chapter(self, DocID):path_str = 'text/chapter-' + str(DocID)file_in = open(path_str)text = ""for line in file_in:text += "".join(line.split('\n')) # 去除回车file_in.closenum = len(text.decode("gb18030"))return num# 每个文档提取特征向量def build_feature_vector(self, DocID, label):path_str = 'text/chapter-wordcount-' + str(DocID)# function_word_list = ['之', '其', '或', '亦', '方', '于', '即', '皆', '因', '仍', #                      '故', '尚', '呢', '了', '的', '着', '不', '乃', '呀', #                    '吗', '咧', '啊', '把', '让', '向', '往', '是', '在', '越', #                     '再', '更', '比', '很', '偏', '别', '好', '可', '便', '就',#                      '但', '儿', # 42 个文言虚词#                       '又', '也', # 高频副词#                       '这', '那', '你', '我', '他' #高频代词#                    '来', '去', '道', '笑'] #高频动词function_word_list = ['之', '其', '或', '亦', '方', '于', '即', '皆', '因', '仍', '故', '尚', '呢', '了', '的', '着', '一', '不', '乃', '呀', '吗', '咧', '啊', '把', '让', '向', '往', '是', '在', '越', '再', '更', '比', '很', '偏', '别', '好', '可', '便', '就','但', '儿',                 # 42 个文言虚词'又', '也', '都', '要',      # 高频副词'这', '那', '你', '我', '他' # 高频代词'来', '去', '道', '笑', '说' #高频动词] feature_vector_list = []for function_word in function_word_list:find_flag = 0file_in = open(path_str) #每次打开移动 cursor 到头部line = file_in.readline()while line:words = line[:-1].split('\t')if words[0] == function_word:total_words = self.get_wordnum_of_chapter(DocID)rate = float(words[1]) / total_words * 1000rate = float("%.6f" % rate)# 指定位数feature_vector_list.append(rate)# print words[0] + ' : ' + linefile_in.close()find_flag = 1breakline = file_in.readline()# 未找到词时向量为 0if not find_flag:feature_vector_list.append(0) feature_vector_list.append(label)return feature_vector_listdef make_positive_trainset(self):positive_trainset_list = []for loop in range(20, 30):feature = self.build_feature_vector(loop, 1) #label 为 1 表示正例positive_trainset_list.append(feature)# print positive_trainset_listnp.save('pos_trainset.npy', positive_trainset_list)def make_negative_trainset(self):negative_trainset_list = []for loop in range(110, 120):feature = self.build_feature_vector(loop, 2) #label 为 0 表示负例negative_trainset_list.append(feature)# print negative_trainset_listnp.save('neg_trainset.npy', negative_trainset_list)def make_trainset(self):feature_pos = np.load('pos_trainset.npy')feature_neg = np.load('neg_trainset.npy')trainset = np.vstack((feature_pos, feature_neg))np.save('trainset.npy', trainset)def make_testset(self):testset_list = []for loop in range(1, 121):feature = self.build_feature_vector(loop, 0) #无需 label,暂设为 0testset_list.append(feature)# print testset_listnp.save('testset.npy', testset_list)

特征向量含义

下面利用svm训练

# -*- coding: utf-8 -*-import numpy as np
from sklearn.naive_bayes import MultinomialNB
import get_trainset as ts
x_train = ts.get_train_set().get_all_vector()class result:def __inti__(self):passdef have_Xtrainset(self):Xtrainset = x_trainXtrainset = np.vstack((Xtrainset[19:29],Xtrainset[109:119]))return(Xtrainset)   def as_num(self,x):y='{:.10f}'.format(x)return(y)def built_model(self):x_trainset = self.have_Xtrainset()y_classset = np.repeat(np.array([1,2]),[10,10])NBclf = MultinomialNB()NBclf.fit(x_trainset,y_classset) # 建立模型all_vector = x_trainresult = NBclf.predict(all_vector)print('前'+str(len(result[0:80]))+'回分类结果为:')print(result[0:80])print('后'+str(len(result[80:121]))+'回分类结果为:')print(result[80:121])diff_chapter = [80,81,83,84,87,88,90,100]for i in diff_chapter:tempr = NBclf.predict_proba(all_vector[i])print('第'+str(i+1)+'回的分类概率为: ')print(str(self.as_num(tempr[0][0]))+' '+str(self.as_num(tempr[0][1])))res = result()res.built_model()

结果如下

1 指该回目属于类别 1,2 指该回目属于类别 2。

可以得出结论

  1. 前 80 回属于一类,后 40 回属于一类
  2. 80 回左右是分界点
  3. 后 40 回风格不同于前 80 回

SVM文本分类-在《红楼梦》作者鉴别的应用上(python实现)相关推荐

  1. 机器学习日常练习——红楼梦作者分析(聚类)

    红楼梦作者分析(聚类) 实验要求 实验题目:<红楼梦>作者分析 实验目的 实验内容 资料下载 实验过程: 问题分析: 解决思路: 代码: 代码一: 出现的问题 文件编码问题 将红楼梦数据, ...

  2. 支持向量机(SVM)-文本分类 (1)

    谢谢你能看我一本正经的胡说八道. 0) 缘由 为什么要写这么一篇博文呢? 我在很多次面试中,都被问到SVM算法.惭愧的是,我近两年一直关注深度学习算法,对SVM的理论本来就掌握得不熟,加上时间一久,被 ...

  3. 用机器学习的方法鉴别红楼梦作者

    为什么80%的码农都做不了架构师?>>>    在学界一般认为,<红楼梦>后 40 回并非曹雪芹所著.本文尝试应用机器学习的方法来分析原著文本中作者的用词习惯,从技术角度 ...

  4. 数学建模训练 — 红楼梦作者解析

    摘要 <红楼梦>不同章回之间作者的异同,历来被学术界争论不休.当新的计算工具出现之后,我们就可以用数学的知识统计分析<红楼梦>不同章回作者异同的问题. 针对问题一,问题一要求根 ...

  5. 【数学建模论文】数学模型分析红楼梦作者

    1.摘要 <红楼梦>不同章回之间作者的异同,历来被学术界争论不休.当新的计算工具出现之后,我们就可以用数学的知识统计分析<红楼梦>不同章回作者异同的问题. 针对问题一,问题一要 ...

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

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

  7. python红楼梦作者_用 Python 分析《红楼梦》,后四十回是曹雪芹所写吗?(开源)...

    原标题:用 Python 分析<红楼梦>,后四十回是曹雪芹所写吗?(开源)

  8. 统计虚词使用不同聚类方法判别红楼梦作者

    采用了K-means聚类和层次聚类.密度聚类效果不太好就舍弃了 用到的库 import numpy as np from sklearn.cluster import KMeans from skle ...

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

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

最新文章

  1. 王兴最好的半年结束了
  2. 数字雕刻中“节奏”的作用
  3. kali linux 2.0 web 渗透测试 电子书
  4. 网络知识:交换机中的半双工与全双工知识笔记
  5. TypeScript 2.1发布
  6. Linux 之目录 -鸟哥的Linux私房菜
  7. Linux实战教学笔记13:定时任务补充
  8. poj3159差分约束+栈实现的spfa+邻接链表
  9. Objective-C的hook方案(一): Method Swizzling
  10. 01背包问题-一维数组实现原理
  11. TP框架log日志使用方法
  12. 编译原理与编译构造 LR文法
  13. 苹果设备解锁工具iToolab UnlockGo Mac
  14. Windows10系统常用快捷键汇总
  15. 如何解决直播中黑屏、花屏、闪屏问题?10 分钟搞明白
  16. 申宝策略-船舶军工表现靓丽
  17. VSCode设置代码格式化
  18. mybatis分页多表查询
  19. 从技术宝库到云上机遇:华为云开天aPaaS的“修路记”
  20. 苹果、天猫同步关停是因为发新品?这些猜想你看靠谱吗....

热门文章

  1. 三菱PLC FX3U与福禄克FLUKE 数字万用表通讯程序 样板实例程序
  2. 北方民族大学计算机技术学制,北方民族大学2014年硕士研究生考试调剂信息
  3. 进程控制(二)——minishell延续
  4. 网络安全 - 信息收集
  5. css居中怎么移动,移动端css水平垂直居中
  6. OTT TV影音系统,不丢帧、不卡顿、不花屏
  7. 计算机画图设计前景色,画图的前景色和背景色
  8. 一卡通系统软件测试,公共交通一卡通互联互通测试平台的研究
  9. 编程题006--判断是不是完全二叉树--niuke
  10. 基于STM32的智能家居系统设计