基于朴素贝叶斯的文本分类

来源:互联网 发布:如何使用广电网络电视 编辑:程序博客网 时间:2024/05/22 01:47

最近在学习自然语言处理,做了一个文本分类的demo,主要是基于朴素贝叶斯算法和TF-IDF方法的文本分类挖掘,下面的代码如下:

# -*- coding:utf-8 -*-import numpy as npdef loadDataSet():    postingList=[['my','dog','has','flea','problems','help','please'],                 ['maybe','not','take','him','to','dog','park','stupid'],                 ['my','dalmation','is','so','cute','I','love','him','my'],                 ['stop','posting','stupid','worthless','garbage'],                 ['mr','licks','ate','my','steak','how','to','stop','stupid'],                 ['quit','buying','worthless','dog','food','stupid']]    classVec=[0,1,0,1,0,1]    return postingList,classVecclass NBayes(object):    def __init__(self): #初始化生成所需要的值        self.vocabulary=[]#字典        self.idf=0   #词典的idf权重向量        self.tf=0 #训练集的全值矩阵        self.Pcates={} #类别字典        self.labels=[] #对应每个文本的分类        self.doclenth=0 #训练集文本数        self.vocablen=0 #词典的词长        self.testset=0 #测试集    def train_set(self,trainset,classVec): #倒入训练集,生成算法必须的参数和数据结构        self.cate_prob(classVec)#计算每个类别在总类别中出现的概率        self.doclenth=len(trainset)  #计算类别的文本数        tempset=set()        [tempset.add(word) for doc in trainset for word in doc] #生成词典,也就是生成词的总数        self.vocabulary=list(tempset)    #将其转换为list 的数据类型        self.vocablen=len(self.vocabulary) #输出此时的字典的总长度        self.calc_wordfreq(trainset) #计算词频数据集        self.build_tdm() #按分类累计向量空间的每维值    def cate_prob(self,classVec):#计算数据集中每个分类的频率        self.labels=classVec  #将标签的数据集给类别标签        labeltemps=set(self.labels) #获取类别标签中不同的类,利用里面提到set函数        for labeltemp in labeltemps:            #self.labels.count(labeltemp)这段代码用于统计重复分类的次数            self.Pcates[labeltemp]=float(self.labels.count(labeltemp))/float(len(self.labels))#输出每个类别出现的频率    #生成普通的词频向量    def calc_wordfreq(self,trainset):        self.idf=np.zeros([1,self.vocablen])  #生成词向量        self.tf=np.zeros([self.doclenth,self.vocablen])#训练样本文件数        for indx in range(self.doclenth): #遍历所有文本            for word in trainset[indx]: #遍历文本中的每个词                self.tf[indx,self.vocabulary.index(word)]+=1                #找到文本词在词典中的位置+1            for signleword in set(trainset[indx]):  #看看这句话的含义                self.idf[0,self.vocabulary.index(signleword)]+=1 #计算在词典中的词中出现的总数,文件数    #按分类累计向量空间的每维值:    def build_tdm(self):        self.tdm=np.zeros([len(self.Pcates),self.vocablen])#类别行+词典列        sumlist=np.zeros([len(self.Pcates),1]) #统计每个分类的总值        for indx in range(self.doclenth):            self.tdm[self.labels[indx]]+=self.tf[indx] #将同一类别的此向量加总            #统计每个分类的总值——是一个标量            sumlist[self.labels[indx]]=np.sum(self.tdm[self.labels[indx]])        self.tdm=self.tdm/sumlist  #    def map2vecab(self,testdata):#将测试集映射到当前的词典        self.testset=np.zeros([1,self.vocablen])        for word in testdata:            self.testset[0,self.vocabulary.index(word)]+=1    def predict(self,testset): #预测分了结果,输出预测的分类类别        if np.shape(testset)[1]!=self.vocablen: #如果测试集长度与字典不相等,则退出程序 说明其超出了词袋的长度            print("输入错误")            exit(0)        predvalue=0 #初始化类别概率        predclass="" #初始化类别名称        for tdm_vect,keyclass in zip(self.tdm,self.Pcates):             temp=np.sum(testset*tdm_vect*self.Pcates[keyclass])            if temp >predvalue:                predvalue=temp                predclass=keyclass        return predclass    def calc_tfidf(self,trainset):        self.idf=np.zeros([1,self.vocablen])        self.tf=np.zeros([self.doclenth,self.vocablen])        for indx in range(self.doclenth):            for word in trainset[indx]:                self.tf[indx,self.vocabulary.index(word)]+=1            #消除不同句长产生的偏差            self.tf[indx]=self.tf[indx]/float(len(trainset[indx]))            for signleword in set(trainset[indx]):                self.idf[0,self.vocabulary.index(signleword)]+=1        self.idf=np.log(float(self.doclenth)/self.idf)        self.tf=np.multiply(self.tf,self.idf)

主程序的运行:

# -*- coding: utf-8 -*-import sysimport osfrom numpy import *import numpy as npfrom Nbays_lib import *dataSet,listClasses=loadDataSet()#倒入外部的数据集#dataSet:句子的词向量#listrClass是句子所处的类别nb=NBayes()nb.train_set(dataSet,listClasses)nb.map2vecab(dataSet[1])print(nb.predict(nb.testset))

输出的结果为

1
原创粉丝点击