朴素贝叶斯文本分类-在《红楼梦》作者鉴别的应用上(python实现)
朴素贝叶斯算法简单、高效。接下来我们来介绍其如何应用在《红楼梦》作者的鉴别上。
第一步,当然是先得有文本数据,我在网上随便下载了一个txt(当时急着交初稿。。。)。分类肯定是要一个回合一个回合的分,所以我们拿到文本数据后,先进行回合划分。然后就是去标点符号、分词,做词频统计。
# -*- coding: utf- -*-
import re
import jieba
import string
import collections as coll
jieba.load_userdict('E:\\forpython\\红楼梦词汇大全.txt') # 导入搜狗的红楼梦词库 class textprocesser:
def __init__(self):
pass # 将小说分成120个章节并单独保存到txt文件中
def divide_into_chapter(self):
red=open('E:\\forpython\\红楼梦.txt',encoding='utf-8')
each_line = red.readline()
chapter_count =
chapter_text = ''
complied_rule = re.compile('第[一二三四五六七八九十百]+回 ') while each_line:
if re.findall(complied_rule,each_line):
file_name = 'chap'+str(chapter_count)
file_out = open('E:\\forpython\\chapters\\'+file_name+'.txt','a',encoding = 'utf-8')
file_out.write(chapter_text)
chapter_count +=
file_out.close()
chapter_text = each_line
else:
chapter_text += each_line each_line = red.readline() red.close() # 对单个章节的分词
def segmentation(self,text,text_count):
file_name = 'chap'+str(text_count)+'-words.txt'
file_out = open('E:\\forpython\\chapter2words\\'+file_name,'a',encoding='utf-8')
delset = string.punctuation line=text.readline() while line:
seg_list = jieba.cut(line,cut_all = False)
words = " ".join(seg_list)
words = words.translate(delset) # 去除英文标点
words = "".join(words.split('\n')) # 去除回车符
words = self.delCNf(words) # 去除中文标点
words = re.sub('[ \u3000]+',' ',words) # 去除多余的空格
file_out.write(words)
line = text.readline() file_out.close()
text.close() # 对所有章节分词
def do_segmentation(self):
for loop in range(,):
file_name = 'chap'+str(loop)+'.txt'
file_in = open('E:\\forpython\\chapters\\'+file_name,'r',encoding = 'utf-8') self.segmentation(file_in,loop) file_in.close() # 去除中文字符函数
def delCNf(self,line):
regex = re.compile('[^\u4e00-\u9fa5a-zA-Z0-9\s]')
return regex.sub('', line) # 去除标点后进行词频统计
def count_words(self,text,textID):
line = str(text)
words = line.split()
words_dict = coll.Counter(words) # 生成词频字典 file_name = 'chap'+str(textID)+'-wordcount.txt'
file_out = open('E:\\forpython\\chapter-wordcount\\'+file_name,'a',encoding = 'utf-8') # 排序后写入文本
sorted_result = sorted(words_dict.items(),key = lambda d:d[],reverse = True)
for one in sorted_result:
line = "".join(one[] + '\t' + str(one[]) + '\n')
file_out.write(line) file_out.close() def do_wordcount(self):
for loop in range(,):
file_name = 'chap'+str(loop)+'-words.txt'
file_in = open('E:\\forpython\\chapter2words\\'+file_name,'r',encoding = 'utf-8')
line = file_in.readline() text = ''
while line:
text += line
line = file_in.readline()
self.count_words(text,loop)
file_in.close() if __name__ == '__main__':
processer = textprocesser()
processer.divide_into_chapter()
processer.do_segmentation()
processer.do_wordcount()
文本分类我个人感觉最重要的是选取特征向量,我查阅了相关文献,决定选取五十多个文言虚词和二十多个在120个回合中均出现过的词汇(文言虚词的使用不受情节影响,只与作者写作习惯有关)。下面是生成
特征向量的代码
# -*- coding: utf- -*-
import jieba
import re
import string
import collections as coll
jieba.load_userdict('E:\\forpython\\红楼梦词汇大全.txt') # 导入搜狗的红楼梦词库 class featureVector:
def __init__(self):
pass # 去除中文字符函数
def delCNf(self,line):
regex = re.compile('[^\u4e00-\u9fa5a-zA-Z0-9\s]')
return regex.sub('', line) # 对整篇文章分词
def cut_words(self):
red = open('E:\\forpython\\红楼梦.txt','r',encoding = 'utf-8')
file_out = open('E:\\forpython\\红楼梦-词.txt','a',encoding = 'utf-8')
delset = string.punctuation line = red.readline() while line:
seg_list = jieba.cut(line,cut_all = False)
words = ' '.join(seg_list)
words = words.translate(delset) # 去除英文标点
words = "".join(words.split('\n')) # 去除回车符
words = self.delCNf(words) # 去除中文标点
words = re.sub('[ \u3000]+',' ',words) # 去除多余的空格
file_out.write(words)
line = red.readline() file_out.close()
red.close() # 统计词频
def count_words(self):
data = open('E:\\forpython\\红楼梦-词.txt','r',encoding = 'utf-8')
line = data.read()
data.close()
words = line.split()
words_dict = coll.Counter(words) # 生成词频字典 file_out = open('E:\\forpython\\红楼梦-词频.txt','a',encoding = 'utf-8') # 排序后写入文本
sorted_result = sorted(words_dict.items(),key = lambda d:d[],reverse = True)
for one in sorted_result:
line = "".join(one[] + '\t' + str(one[]) + '\n')
file_out.write(line) file_out.close() def get_featureVector(self):
# 将分词后的120个章节文本放入一个列表中
everychapter = []
for loop in range(,):
data = open('E:\\forpython\\chapter2words\\chap'+str(loop)+'-words.txt','r',encoding = 'utf-8')
each_chapter = data.read()
everychapter.append(each_chapter)
data.close() temp = open('E:\\forpython\\红楼梦-词.txt','r',encoding = 'utf-8')
word_beg = temp.read()
word_beg = word_beg.split(' ')
temp.close() # 找出每一个回合都出现的词
cleanwords = []
for loop in range(,):
data = open('E:\\forpython\\chapter2words\\chap'+str(loop)+'-words.txt','r',encoding = 'utf-8')
words_list = list(set(data.read().split()))
data.close()
cleanwords.extend(words_list) cleanwords_dict = coll.Counter(cleanwords) cleanwords_dict = {k:v for k, v in cleanwords_dict.items() if v >= } cleanwords_f = list(cleanwords_dict.keys()) xuci = open('E:\\forpython\\文言虚词.txt','r',encoding = 'utf-8')
xuci_list = xuci.read().split()
xuci.close()
featureVector = list(set(xuci_list + cleanwords_f))
featureVector.remove('\ufeff') # 写入文本
file_out = open('E:\\forpython\\红楼梦-特征向量.txt','a',encoding = 'utf-8')
for one in featureVector:
line = "".join(one+ '\n')
file_out.write(line) file_out.close()
return(featureVector) if __name__ == '__main__':
vectorbuilter = featureVector()
vectorbuilter.cut_words()
vectorbuilter.count_words()
vectorbuilter.get_featureVector()
朴素贝叶斯文本分类就是用特征向量的词频作为每个回合的代表(偷个懒,直接截图答辩的ppt)
用特征向量把所有一百二十个回合向量化后,你会得到120×70的一个数组。接下来就简单了。直接挑选训练集,在这我是在前80回中挑选了20至29回标记为第一类(用数字1表示),并将其作为第一类的训练集;在后80回合中挑选了110至119回标记为第二类(用数字2表示),并将其作为第二类的训练集。
# -*- coding: utf- -*- 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):
pass def have_Xtrainset(self):
Xtrainset = x_train
Xtrainset = np.vstack((Xtrainset[:],Xtrainset[:]))
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([,]),[,]) NBclf = MultinomialNB()
NBclf.fit(x_trainset,y_classset) # 建立模型 all_vector = x_train result = NBclf.predict(all_vector)
print('前'+str(len(result[:]))+'回分类结果为:')
print(result[:])
print('后'+str(len(result[:]))+'回分类结果为:')
print(result[:]) diff_chapter = [,,,,,,,]
for i in diff_chapter:
tempr = NBclf.predict_proba(all_vector[i])
print('第'+str(i+)+'回的分类概率为: ')
print(str(self.as_num(tempr[][]))+' '+str(self.as_num(tempr[][]))) if __name__ == '__main__':
res = result()
res.built_model()
上面是直接调用了skit-learn的MultinomialNB函数,详细情况我在前一篇中讲过。
得到分类结果:
从最终的分类结果来看,在第82回合左右是有一个比较明显的分界点,这样看来前80回合与后40回合在写作风格上还是有显著的差异的,这个结果和红楼梦学术界的年的推断比较一致。
至于为何在后40回中有8个回合被分到1类中,这8个回合分别是81回、82回、84回、85回、88回、89回、91回还有101回,都是在第80回合附近,这个差异有可能是由于上下文的衔接所导致的,因为本文所使用的《红楼梦》文本是从网上下载得到的,,版本不明,所以也有可能是由于红楼梦的版本所导致的。
代码肯定还有很多可以优化的地方,在这里献丑了。。。。
朴素贝叶斯文本分类-在《红楼梦》作者鉴别的应用上(python实现)的更多相关文章
- Mahout朴素贝叶斯文本分类
Mahout朴素贝叶斯文本分类算法 Mahout贝叶斯分类器按照官方的说法,是按照<Tackling the PoorAssumptions of Naive Bayes Text Classi ...
- 朴素贝叶斯文本分类(python代码实现)
朴素贝叶斯(naive bayes)法是基于贝叶斯定理与特征条件独立假设的分类方法. 优点:在数据较少的情况下仍然有效,可以处理多分类问题. 缺点:对入输入数据的准备方式较为敏感. 使用数据类型:标称 ...
- 朴素贝叶斯文本分类实现 python cherry分类器
贝叶斯模型在机器学习以及人工智能中都有出现,cherry分类器使用了朴素贝叶斯模型算法,经过简单的优化,使用1000个训练数据就能得到97.5%的准确率.虽然现在主流的框架都带有朴素贝叶斯模型算法,大 ...
- 详解使用EM算法的半监督学习方法应用于朴素贝叶斯文本分类
1.前言 对大量需要分类的文本数据进行标记是一项繁琐.耗时的任务,而真实世界中,如互联网上存在大量的未标注的数据,获取这些是容易和廉价的.在下面的内容中,我们介绍使用半监督学习和EM算法,充分结合大量 ...
- 朴素贝叶斯文本分类java实现
package com.data.ml.classify; import java.io.File; import java.util.ArrayList; import java.util.Coll ...
- Naive Bayes(朴素贝叶斯算法)[分类算法]
Naïve Bayes(朴素贝叶斯)分类算法的实现 (1) 简介: (2) 算法描述: (3) <?php /* *Naive Bayes朴素贝叶斯算法(分类算法的实现) */ /* *把. ...
- 芝麻HTTP:记scikit-learn贝叶斯文本分类的坑
基本步骤: 1.训练素材分类: 我是参考官方的目录结构: 每个目录中放对应的文本,一个txt文件一篇对应的文章:就像下面这样 需要注意的是所有素材比例请保持在相同的比例(根据训练结果酌情调整.不可比例 ...
- Python机器学习算法 — 朴素贝叶斯算法(Naive Bayes)
朴素贝叶斯算法 -- 简介 朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法.最为广泛的两种分类模型是决策树模型(Decision Tree Model)和朴素贝叶斯模型(Naive Baye ...
- [机器学习] 分类 --- Naive Bayes(朴素贝叶斯)
Naive Bayes-朴素贝叶斯 Bayes' theorem(贝叶斯法则) 在概率论和统计学中,Bayes' theorem(贝叶斯法则)根据事件的先验知识描述事件的概率.贝叶斯法则表达式如下所示 ...
随机推荐
- canva绘制圆角矩形
在做组态的时候,需要支持矩形圆角格式,但是因为canvas本身不带有圆角矩形,需要自行算出坐标进行绘制 方案一.统一圆角 <!DOCTYPE html> <html> < ...
- js中with的作用
js中with的作用当一个对象有多个需要操作的属性或方法时,可以使用如<体>试验<script type=“text/javascript”>var o=文件.创建元素(“DI ...
- Linux服务器性能检查教程
一.uptime命令 这个命令可以快速查看机器的负载情况.在Linux系统中,这些数据表示等待CPU资源的进程和阻塞在不可中断IO进程(进程状态为D)的数量.这些数据可以让我们对系统资源使用有一个宏观 ...
- QQ大盗 - 巧用clientkey
场景: 1.将程序发给好友,好友打开 qq昵称就会被秒改为”账号已被盗“. 2.将程序运行在自己的电脑,让那些随意借用电脑看片聊天的室友产生一个觉悟:乱使用别人电脑很可能会泄露隐私. 思路: 通过数据 ...
- 解决 /etc/init.d/php-fpm no such file or directory等相关问题
vi /etc/init.d/php-fpm #! /bin/sh # Comments to support chkconfig on CentOS # chkconfig: 2345 65 37 ...
- Win10系统如何利用蓝牙设置动态锁?
很多小伙伴都会有这样的经历,出门之后没走多远,却已然忘记是否锁门,有强迫症的人就会重新返回查看,以确保门是否反锁. 我们在使用电脑时也是这样,遇到事情要临时离开,却忘记是否锁屏,再返回来就耽误时间了. ...
- (备忘)Java数据类型中String、Integer、int相互间的转换
1.Integer转换成int的方法 Integer i; int k = i.intValue();即Integer.intValue(); 2.int转换成Integer int i; Integ ...
- 5.java动态代理、反射
1.java动态代理.反射(IDEA导入JUnit4) 1.1.反射 通过反射的方式可以获取class对象中的属性.方法.构造函数等 1.2.反射代码 import java.io.Serializa ...
- 9.RNN应用
import numpy as np from keras.datasets import mnist from keras.utils import np_utils from keras.mode ...
- java8学习之Optional深入详解
自上次[http://www.cnblogs.com/webor2006/p/8243874.html]函数式接口的学习告一段落之后,这次来学习一下Optional,它并非是函数式接口的概念,点击查看 ...