前段时间看到有个群在招文档分类志愿者,主要工作是把各个渠道收集到的分析报告(PDF格式)进行分类整理,就想起来机器学习中有个朴素贝叶斯算法正好是处理这种语言文字分类的利器,于是决定写一个分类的脚本来玩玩儿。

整个处理思路大致如下:

1、获取PDF文档中文字内容另存在TXT文件(pdfminer)

2、对TXT文件分词并获取特征向量(jieba)

3、划分测试集与训练集并训练模型(sklearn.naive_bayes)

4、使用模型进行预测

需要注意的是,在获取PDF文档中信息时发现部分文档格式不是很规范(比如图片形式或者带有密码),这种情况下脚步会报错终止的,为了让脚本顺利执行到底,中间加入了异常忽略处理。

脚本如下:

import importlib

import sys

from pdfminer.pdfparser import  PDFParser,PDFDocument

from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter

from pdfminer.converter import PDFPageAggregator

from pdfminer.layout import LTTextBoxHorizontal,LAParams

from pdfminer.pdfinterp import PDFTextExtractionNotAllowed

import shutil

import os

import jieba

import numpy as np

from sklearn.naive_bayes import MultinomialNB

import pandas as pd

import matplotlib.pyplot as plt

%matplotlib inline

def parse(path):

'''解析PDF文本,并保存到TXT文件中'''

path_2=path.strip()

with open(path_2,'rb') as fp:

#用文件对象创建一个PDF文档分析器

parser = PDFParser(fp)

#创建一个PDF文档

doc = PDFDocument()

#连接分析器,与文档对象

parser.set_document(doc)

doc.set_parser(parser)

#提供初始化密码,如果没有密码,就创建一个空的字符串

try:

doc.initialize()

except Exception as e:

print("Unexpection error:%s" % e)

#创建PDF,资源管理器,来共享资源

rsrcmgr = PDFResourceManager()

#创建一个PDF设备对象

laparams = LAParams()

device = PDFPageAggregator(rsrcmgr,laparams=laparams)

#创建一个PDF解释其对象

interpreter = PDFPageInterpreter(rsrcmgr,device)

#循环遍历列表,每次处理一个page内容

# doc.get_pages() 获取page列表

for page in doc.get_pages():

interpreter.process_page(page)

#接受该页面的LTPage对象

layout = device.get_result()

# 这里layout是一个LTPage对象 里面存放着 这个page解析出的各种对象

# 一般包括LTTextBox, LTFigure, LTImage, LTTextBoxHorizontal 等等

# 想要获取文本就获得对象的text属性,

for x in layout:

if(isinstance(x,LTTextBoxHorizontal)):

txt_name=path[:-4]+'_2.txt'

with open(txt_name,'a',encoding='utf-8') as f:

results = x.get_text()

f.write(results  +"\n")

def doc_copy(path_1,path_2):

'''剪切路径path_1中的txt文件,然后放入新建文件夹path_2中'''

os.chdir(path_1)

txt_list=[]

for path in os.listdir(path_1):

if path[-3:] == 'txt':

txt_list.append(path)

if not os.path.isdir(path_2):  #判断是否存在path_2文件夹,如果不存在就创建一个

os.mkdir(path_2)

for txt in txt_list:

#shutil.copy(txt,path_2)

shutil.move(txt,path_2)

#提取PDF文件中文字另存在TXT文件,然后剪切到指定文件夹中

path_sample=r"F:\自动分类\样本"

os.chdir(path_sample)

list_sample=os.listdir(path_sample)

# print(list_sample)

path_sample_txt=[r"F:\自动分类\sample\jiankang",r"F:\自动分类\sample\lvyou",r"F:\自动分类\sample\qiche",r"F:\自动分类\sample\caijing"]

for i in range(0,4):

print(os.path.join(path_sample,list_sample[i]))

os.chdir(os.path.join(path_sample,list_sample[i]))

paths=os.listdir(os.path.join(path_sample,list_sample[i]))

for path in paths:

try:

parse(path)

except Exception as e:

print("Unexception error %s" % e)

doc_copy(os.path.join(path_sample,list_sample[i]),path_sample_txt[i])

def file_cut(folder_path):

'''对文件夹中不同类型的文件进行分词,然后把分词结果和文件类型一一对应存入列表'''

os.chdir(folder_path)

folder_list = os.listdir(folder_path)

data_list = []

class_list = []

for folder in folder_list:

new_folder_path = os.path.join(folder_path, folder)   #路径拼接

#     print(new_folder_path)

files = os.listdir(new_folder_path)

#     print(files ,'\n')

#         j = 1

for file in files:

with open(os.path.join(new_folder_path, file), 'r', encoding='utf-8') as f:

raw = f.read()

word_cut = jieba.cut(raw, cut_all=False)  # jieba.cut():第一个参数为需要分词的字符串,第二个cut_all控制是否为全模式。

word_list = list(word_cut)

data_list.append(word_list)

class_list.append(folder)

data_class_list = list(zip(data_list, class_list))   #数据集和标签对应压缩

return data_class_list

#对样本中的文档进行分词处理

folder_path=r"F:\自动分类\sample"

data_class_list=file_cut(folder_path)

#切分训练集和测试集

np.random.shuffle(data_class_list)   #打乱次序

index = int(len(data_class_list) * .2) + 1

train_list = data_class_list[:-index]

test_list = data_class_list[-index:]

train_data_list, train_class_list = zip(*train_list)   #测试数据、测试标签对应解压缩,zip(*)与zip()相反,指解压

test_data_list, test_class_list = zip(*test_list)

#统计训练集中所有词的词频

all_word_dict = {}

for word_list in train_data_list:

for word in word_list:

if word in all_word_dict.keys():

all_word_dict[word] += 1

else:

all_word_dict[word] = 1

#根据字典的值降序排列

all_word_tuple_list = sorted(all_word_dict.items(), key=lambda item:item[1], reverse=True)  #这里的d.items()实际上是将d转换为可迭代对象,

#items()方法将字典的元素 转化为了元组,而这里key参数对应的lambda表达式的意思则是选取元组中的第二个元素作为比较参数

#(如果写作key=lambda item:item[0]的话则是选取第一个元素作为比较对象,也就是key值作为比较对象。

#lambda x:y中x表示输出参数,y表示lambda 函数的返回值),所以采用这种方法可以对字典的value进行排序。

#注意排序后的返回值是一个list,而原字典中的各值对被转换为了list中的元组。

all_word_list, all_word_nums = zip(*all_word_tuple_list)

all_word_list = list(all_word_list)   #转换成列表

#读取不用的词汇

words_set = set()

words_file = r"F:\自动分类\stopwords\stopwords_cn.txt"

with open(words_file, 'r',encoding='ANSI') as f:

for line in f.readlines():

word = line.strip()

if len(word) > 0:

words_set.add(word)

#删除前N个高频词汇

def words_dict(all_words_list, N, stopwords_set=set()):

feature_words = []

n = 1

for t in range(N, len(all_words_list)):

if n > 1000:

break

if not all_words_list[t].isdigit() and all_words_list[t] not in stopwords_set and 1 < len(all_words_list[t]) < 5:

feature_words.append(all_words_list[t])

n += 1

return feature_words

def textfeatures(text, feature_words):

'''取特征向量'''

text_words = set(text)

features = [1 if word in text_words else 0 for word in feature_words]

return features

NB = MultinomialNB()

NB.fit(train_feature_list, train_class_list)

test_accuracy = NB.score(test_feature_list, test_class_list)

test_accuracy_list = []

deleteN = range(0, 1000, 20)

for N in deleteN:

feature_words = words_dict(all_word_list, N, words_set)

train_feature_list = [textfeatures(text, feature_words) for text in train_data_list]

test_feature_list = [textfeatures(text, feature_words) for text in test_data_list]

NB.fit(train_feature_li

st, train_class_list)

test_accuracy = NB.score(test_feature_list, test_class_list)

test_accuracy_list.append(test_accuracy)

plt.plot(deleteN, test_accuracy_list)

plt.title("Relationship of deldteN and test_accuracy_list")

plt.xlabel("deleteN")

plt.ylabel("test_accuracy_list")

plt.show()

#提取带预测PDF文件内容,然后放入指定文件夹中

path_1=r"F:\自动分类\预测"

path_2=r"F:\自动分类\test"

os.chdir(path_1)

for path in os.listdir(path_1):

try:

parse(path)

except Exception as e:

print("Unexception error %s" % e)

doc_copy(path_1,path_2)

def data_list(path):

'''对文件夹中的文件逐个分词后存入列表'''

data_list=[]

txt_list=[]

files = os.listdir(path)

for file in files:

txt_list.append(file)

with open(os.path.join(path, file), 'r', encoding='UTF-8') as f:

raw = f.read()

word_cut = jieba.cut(raw, cut_all=False)  # jieba.cut():第一个参数为需要分词的字符串,第二个cut_all控制是否为全模式。

word_list = list(word_cut)

data_list.append(word_list)

txt_data_list = list(zip(txt_list,data_list))

return txt_data_list

#构建分类字典

names = ['Code', 'Name']

data_trans = pd.read_csv(r"F:\自动分类\class\classlist.txt", sep='\t', names=names, encoding='ANSI',engine='python')

data_trans = np.array(data_trans)

dict_trans = {}

for i in range(0, len(data_trans)):

dict_trans[data_trans[i][0]] = data_trans[i][1]

txt_data_list=data_list(path=r"F:\自动分类\test")

txt_list , data_list_ = zip(*txt_data_list)

txt_test=data_list_

feature_words = words_dict(all_word_list, 600, words_set)

train_feature_list = [textfeatures(text, feature_words) for text in train_data_list]

test_feature_list = [textfeatures(text, feature_words) for text in test_data_list]

NB.fit(train_feature_list, train_class_list)

MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)

class_feature_list = [textfeatures(text, feature_words) for text in txt_test]

NB_pred = NB.predict(class_feature_list)

key=np.vectorize(dict_trans.get)(NB_pred)

vlue=txt_list

shuchu=list(zip(key,vlue))

for i in shuchu:

print(i)

结果输出

('健康', '2019上半年医疗健康行业投资与退出趋势报告(硅谷银行)_2.txt')

('旅游', '2019全球旅游消费报告(马蜂窝)_2.txt')

('汽车', '中国汽车品牌及新能源汽车发展趋势蓝皮书【巨量引擎】_2.txt')

('汽车', '重塑汽车服务理念(埃森哲)_2.txt')

最后,考虑到实际生活中大家分类通常是根据文档名称中关键字来进行划分的,所以换种思路,我们也可以直接取文档名称来作为训练模型的原料,如果数据量够多应该也会有不错的效果,亦或者说,我们可以采用集成分类把以上结合起来可能也是一个很不错的办法,有兴趣的可以尝试一下,这里就不再演示了。

贝叶斯算法对PDF文档归类相关推荐

  1. 全部博文集锦第三期CHM文件,及十三个经典算法研究PDF文档

        最近一直忙于找工作中,所以博客未能及时更新,乱七八糟的信息在微博上倒是发了不少.再者,csdn博客这段时间之内一直在改版,本想等它彻底改好了,再发表文章.不过,现在看来,还是算了. 做点实事吧 ...

  2. 【机器学习入门】(2) 朴素贝叶斯算法:原理、实例应用(文档分类预测)附python完整代码及数据集

    各位同学好,今天我向大家介绍python机器学习中的朴素贝叶斯算法.内容有:算法的基本原理:案例实战--新闻文档的分类预测. 案例简介:新闻数据有20个主题,有10万多篇文章,每篇文章对应不同的主题, ...

  3. Python scikit-learn,分类,朴素贝叶斯算法,文档分类,MultinomialNB,拉普拉斯平滑系数

    朴素贝叶斯预测分类的思想就是根据待预测文档的特征(TF-IDF高的词)分别计算属于各个类别的概率,其中概率最大的类别,就是预测的类别.(朴素的意思就是文档的特征(词)之间相互独立) 朴素贝叶斯进行文档 ...

  4. java 稀疏贝叶斯算法_稀疏贝叶斯学习(SparseBayesianLearning).PDF

    稀疏贝叶斯学习(SparseBayesianLearning) 稀疏贝叶斯学习(Sparse Bayesian Learning) 张智林(Zhilin?Zhang)? z4zhang@ Depart ...

  5. 朴素贝叶斯 php,PHP实现机器学习之朴素贝叶斯算法详解.pdf

    PHP实实现现机机器器学学习习之之朴朴素素贝贝叶叶斯斯算算法法详详解解 本文实例讲述了PHP实现机器学习之朴素贝叶斯算法.分享给大家供大家参考 具体如下: 机器学习已经在我们的生活中变得随处可见了.比 ...

  6. 人工智能知识全面讲解:垃圾邮件克星——朴素贝叶斯算法

    6.1 什么是朴素贝叶斯 6.1.1 一个流量预测的场景 某广告平台接到小明和小李两家服装店的需求,准备在A.B两个线上渠道 投放广告.因为小明和小李两家店都卖女装,属于同一行业相同品类的广告, 所以 ...

  7. 机器学习——朴素贝叶斯算法

    朴素贝叶斯算法 1.引言 2.朴素贝叶斯分类方法 3.概率基础 4.朴素贝叶斯特征提取 5.朴素贝叶斯分类的sklearn实现 6.垃圾短息分类 补充 1.引言 贝叶斯方法是一个历史悠久,有着坚实的理 ...

  8. 基于贝叶斯算法的文本分类算法

    因为要做一个关于数据挖掘的算法应用PPT,虽然知道很多数据挖掘的算法怎么使用,但是需要讲解它们的原理,还真的需要耗费很多精力,之前做一个曲线拟合,已经发在博客里,现在做贝叶斯算法的基础原理. 1.基本 ...

  9. 机器学习 第三讲 机器学习基础、机器学习算法(K-近邻算法、朴素贝叶斯算法)

    文章目录 一.机器学习基础 1.明确几点问题 2.机器学习算法的判别依据 3.机器学习算法分类 4.机器学习开发流程 二.机器学习算法 1.sklearn数据集 (1)数据集划分 (2)sklearn ...

最新文章

  1. UVa 1531 - Problem Bee
  2. Java 性能优化系列之3.2[JVM调优] --- JIT即时编译
  3. PowerDesigner导入Excel/CSV
  4. python——迭代器
  5. bgi::detail::is_valid用法的测试程序
  6. SQLserver查看某个视图的创建语句
  7. 【Linux】一步一步学Linux——cut命令(44)
  8. ARP***防范与解决方案
  9. 电话拨号器java_Android基础--电话拨号器
  10. windowsxp中linq 指定的转换无效_.NET Core 3.0 中的新变化
  11. memcached—如何在Windows操作系统中安装、启动和卸载memcached
  12. x264编码详细文字全过程
  13. mysql查找多个表并更新值_Mysql子查询,连接,多表更新
  14. java实现pdf转word
  15. spring cloud day(6) gateway网关
  16. 如何利用多任务学习提升模型性能?
  17. QuartusII 15.0 中解决仿真报错 Error : vism-19 Faild to access library问题
  18. mysql like 原理_MySql原理
  19. MTK功能机ATA导入
  20. 身份证校验和获取身份证信息的方法

热门文章

  1. Magicodes.IE 2.4版本发布
  2. linux下声音调节
  3. CentOS开机自动启动脚本
  4. 关于毕业论文那些事——如何给论文封面单元格文字两端完美对齐
  5. 关于TLC2272CDR
  6. 网盛总裁孙德良:马云的软肋
  7. Jenkins定时构建和邮件发送
  8. spring cloud 雪崩效应
  9. SQL Server 辅助软件系列
  10. 【计算机毕业设计】即动运动网站设计