数据挖掘+python中⽂⽂本分类
源码 github
报告
⽂本分类
摘要
⽂本分类指按照预先定义的主题类别,为⽂档集合中的每个⽂档确定⼀个类别。这样⽤户不但能够⽅便地浏览⽂档,⽽且可以通过限制搜索范围来使⽂档的查更容易、快捷。⽬前,主要⽅法有朴素贝叶斯分类(Naive Bayesian Model),向量空间模型(Vector Space Model)以及线性最⼩⼆乘LLSF(Linear Least Square Fit)。本⽂中,使⽤⼀个已经分好类的数据集,通过对其中的⽂章进⾏分词,并存⼊Bunch数据结构,统计词频,然后再⽤TF-IDF的⽅法进⾏特征选取,最后使⽤利⽤朴素贝叶斯对测试数据集分类,并评估准确率。
1.⽂本分类过程
中⽂语⾔的⽂本分类技术和流程,主要包括下⾯⼏个步骤:
1. 预处理:去除⽂本噪声信息,例如HTML标签,⽂本格式转换,检测句⼦边界
2. 中⽂分词:使⽤中⽂分词器为⽂本分词,并去除停⽤词
3. 构建词向量空间:统计⽂本词频,⽣成⽂本的词向量空间
4. 权重策略——TF-IDF:使⽤TF-IDF发现特征词,并抽取为反映⽂档主题的特征
5. 分类:使⽤算法训练分类器,本⽂使⽤朴素贝叶斯
6. 评价分类结果
2.数据集
训练集train_small中包含10个分类,每个分类下有⼀些txt⽂本⽂件。
同样,在测试集test_small中也有10个分类的数据集,就是⽤这些数据来测试模型的好坏。
3.分词
分词是将连续的字序列按照⼀定的规范重新组合成词序列的过程,中⽂分词即将⼀个汉字序列(句⼦)
切分成⼀个个独⽴的单词,中⽂分词很复杂,从某种程度上并不完全是⼀个算法问题,最终概率论解决了这个问题,算法是基于概率图模型的条件随机场(CRF)分词是⾃然语⾔处理中最基本,最底层的模块,分词精度对后续应⽤模块的影响很⼤,⽂本或句⼦的结构化表⽰是语⾔处理中最核⼼的任务,⽬前⽂本的结构化表⽰分为四⼤类:词向量空间、主体模型、依存句法的树表⽰、RDF的图表⽰。
由于数据已经相对规整,直接对训练集和测试集中所有⽂本中⽂章进⾏分词,并把分好的⽂章存⼊各⾃对应的分词⽂件夹。
# -*- coding: utf-8 -*-
import os
import jieba
def savefile(savepath, content):
fp = open(savepath,"w",encoding='gb2312',errors='ignore')
fp.write(content)
fp.close()
def readfile(path):
fp = open(path,"r",encoding='gb2312',errors='ignore')
content = fp.read()
fp.close()
return content
corpus_path = "test_small/" # 未分词分类预料库路径
seg_path = "test_seg/" # 分词后分类语料库路径
catelist = os.listdir(corpus_path) # 获取改⽬录下所有⼦⽬录
print(catelist)
for mydir in catelist:
class_path = corpus_path + mydir + "/" # 拼出分类⼦⽬录的路径
seg_dir = seg_path + mydir +"/" # 拼出分词后预料分类⽬录
if not ists(seg_dir): # 是否存在,不存在则创建
os.makedirs(seg_dir)
file_list = os.listdir(class_path)
for file_path in file_list:
fullname = class_path + file_path
content = readfile(fullname).strip() # 读取⽂件内容
content = place("\r\n","").strip() # 删除换⾏和多余的空格
content_seg = jieba.cut(content)
savefile(seg_dir + file_path, " ".join(content_seg))
print("分词结束")
对于代码中corpus_path ="test_small/"和seg_path ="test_seg/" 这两个变量,只要改为训练集的路径,就是对训练集进⾏分词。分词结果:
截⽌⽬前,我们已经得到了分词后的训练集语料库和测试集语料库,下⾯我们要把这两个数据集表⽰为变量,从⽽为下⾯程序调⽤提供服务。我们采⽤的是Scikit-Learn库中的Bunch数据结构来表⽰这两个数据集。⽤Bunch表⽰,就是:
from sklearn.datasets.base import Bunch
bunch = Bunch(target_name=[],label=[],filenames=[],contents=[])
我们在Bunch对象⾥⾯创建了有4个成员:
target_name:是⼀个list,存放的是整个数据集的类别集合。
label:是⼀个list,存放的是所有⽂本的标签。
filenames:是⼀个list,存放的是所有⽂本⽂件的名字。
contents:是⼀个list,分词后⽂本⽂件词向量形式
代码如下:
import os
import pickle
from sklearn.datasets.base import Bunch
#Bunch 类提供了⼀种key,value的对象形式
#target_name 所有分类集的名称列表
#label 每个⽂件的分类标签列表
#filenames ⽂件路径
#contents 分词后⽂件词向量形式
def readfile(path):
fp = open(path,"r",encoding='gb2312',errors='ignore')
content = fp.read()
fp.close()
return content
bunch=Bunch(target_name=[],label=[],filenames=[],contents=[])
# wordbag_path="train_word_bag/train_set.dat"
# seg_path="train_seg/"
wordbag_path="test_word_bag/test_set.dat"#test_word_bag⽂件夹已经⾃⼰创建
seg_path="test_seg/"
catelist=os.listdir(seg_path)
bunch.d(catelist)#将类别信息保存到Bunch对象
for mydir in catelist:
class_path=seg_path+mydir+"/"
file_list=os.listdir(class_path)
for file_path in file_list:
fullname=class_path+file_path
bunch.label.append(mydir)#保存当前⽂件的分类标签
bunch.filenames.append(fullname)#保存当前⽂件的⽂件路径
#Bunch对象持久化
file_obj=open(wordbag_path,"wb")
pickle.dump(bunch,file_obj)
file_obj.close()
print("构建⽂本对象结束")
4.构建向量空间和权重策略
由于⽂本在储存的向量空间是维度较⾼,为节省储存空间和提⾼搜索效率,在⽂本分类之前会⾃动过滤掉某些字词,这些字或词被称为停⽤词,本⽂使⽤⽹上的常⽤停⽤词。
3.1.TF-IDF⽅法:
如果某个词或短语在⼀篇⽂章中出现的频率⾼,并且在其他⽂章中很少出现,那么认为这个词或者短语具有很好的类别区分能⼒,适合⽤来分类。
TF-IDF(Term Frequency-InversDocument Frequency)是⼀种常⽤于信息处理和数据挖掘的加权技术。该技术采⽤⼀种统计⽅法,根据字词的在⽂本中出现的次数和在整个语料中出现的⽂档频率来计算⼀个字词在整个语料中的重要程度。它的优点是能过滤掉⼀些常见的却⽆关紧要本的词语,同时保留影响整个⽂本的重要字词。计算⽅法如下⾯公式所⽰:
其中,式中tfidfi,j表⽰词频tfi,j和倒⽂本词频idfi的乘积。TF-IDF值越⼤表⽰该特征词对这个⽂本的重要性越⼤。
词频(TF):指的是某⼀个给定的词语在该⽂件中出现的频率。这个数字是对词数的归⼀化,以防⽌它偏向长的⽂件,对于某⼀个特定⽂件⾥的词语来说,它的重要性可表⽰为:
分⼦是该词在⽂件中出现的次数,分母是在⽂件中所有字词的出现次数之和
逆向⽂件频率(IDF)是⼀个词语普遍重要性的度量,某⼀特定词语的IDF,可以由总⽂件数⽬除以包含该词语的⽂件的数⽬,再将得到的商取对数:
|D|是语料库中的⽂件总数,j是包含词语的⽂件数⽬,如果该词语不在语料库中,就会导致分母为零,因此⼀般情况下分母还要额外再加上1。
之后计算词频和逆向⽂件频率的乘积,某⼀特定⽂件内的⾼词语频率,以及该词语在整个⽂件集合中的低⽂件频率,可以产⽣出⾼权重
的TF-IDF,因此TF-IDF倾向于过滤掉常见的词语,保留重要的词语。对训练数据的代码如下:
import os
from sklearn.datasets.base import Bunch
import pickle#持久化类
from sklearn import feature_extraction
from sklearn. import TfidfTransformer#TF-IDF向量转换类
from sklearn. import TfidfVectorizer#TF-IDF向量⽣成类
def readbunchobj(path):
file_obj=open(path,"rb")
bunch=pickle.load(file_obj)
file_obj.close()
return bunch
def writebunchobj(path,bunchobj):
file_obj=open(path,"wb")
pickle.dump(bunchobj,file_obj)
file_obj.close()
def readfile(path):
python怎么读取dat文件fp = open(path,"r",encoding='gb2312',errors='ignore')
content = fp.read()
fp.close()
return content
path="train_word_bag/train_set.dat"
bunch=readbunchobj(path)
#停⽤词
stopword_path=""
stpwrdlst=readfile(stopword_path).splitlines()
#构建TF-IDF词向量空间对象
tfidfspace=Bunch(target_name=bunch.target_name,label=bunch.label,filenames=bunch.filenames,tdm=[],vocabulary={})
#使⽤TfidVectorizer初始化向量空间模型
vectorizer=TfidfVectorizer(stop_words=stpwrdlst,sublinear_tf=True,max_df=0.5)
transfoemer=TfidfTransformer()#该类会统计每个词语的TF-IDF权值
#⽂本转为词频矩阵,单独保存字典⽂件
tfidfspace.tdm=vectorizer.fit_ts)
tfidfspace.vocabulary=vectorizer.vocabulary_
#创建词袋的持久化
space_path="train_word_bag/tfidfspace.dat"
writebunchobj(space_path,tfidfspace)
结果是⽣成⼀个训练集的词袋。对于测试集⽣成向量空间,在训练词向量模型时需要加载训练集词袋,将测试集产⽣的词向量映射到训练集词袋的词典中,⽣成向量空间模型,测试集⽣成向量空间的代码:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论