python基于朴素贝叶斯算法实现新闻分类

#_*_ coding=UTF-8 _*_ import os import random from numpy import* import math 

函数声明:朴素贝叶斯新闻分类器训练函数
变量声明:
train_data: 文档特征向量
train_class: 文档类的特征集
numtrain: 训练集的总文件数目
numwords: 矩阵每行占据的长度
myclass: 类名称的列表
pn: 每一个类中每一个词的数目
ps: 该类的单词总数
返回值类型:
pi = [] 类别i的出现概率
pw=[] 类别下各个特征词的频率

 def trainNB(train_data, train_class): numtrain = len(train_data) #总文件数 numwords = len(train_data[0]) #总单词数 p1=p2=p3=p4=p5=p6=p7=p8=p9=ones(numwords) #分子数+1,拉普拉斯平滑处理 sum1=sum2=sum3=sum4=sum5=sum6=sum7=sum8=sum9=9.0 #分母数加9,拉普拉斯平滑处理 num1=num2=num3=num4=num5 =num6=num7=num8=num9=0 #各类文档数目初始为0 pn=array([p1,p2,p3,p4,p5,p6,p7,p8,p9]) ps=array([sum1,sum2,sum3,sum4,sum5,sum6,sum7,sum8,sum9]) classnum=array([num1,num2,num3,num4,num5,num6,num7,num8,num9]) myclass=["财经","房产","健康","教育","军事","科技","体育","娱乐","证券"] for i in range(numtrain): #遍历每篇训练文档 for j in range(9): #遍历每个类别 if train_class[i] == myclass[j]: #如果在类别下的文档 pn[j]+=train_data[i] #统计该类每一个词的数目 ps[j] += sum(train_data[i]) #计算该类下的单词数目,用于计算特征集中每一个词在yi中的概率 classnum[j] +=1 #该类文档数目加1 break pw,pi = [],[] for i in range(9): pw.append(pn[i]/ps[i]) #每一个类中单词出现的概率 pi.append(classnum[i] / float(numtrain)) #类别的先验概率 return pw, pi 

函数声明:朴素贝叶斯的测试函数
变量声明:
test_data: 测试集向量
pw 每一个类中某一单词出现的概率
maxclass: 文档分类到各类的概率值列表
pi 各类出现的概率
返回值:
myclass[i]: 返回该测试数据属于哪一个类别

def classNB(test_data, pw,pi): #文档分类到各类的概率值列表 maxclass=[] for x in range(9): #乘法计算词频累加得到P(xi|C)总和 summ=0 for i in range(len(test_data)): if test_data[i]!=0: summ+=math.log(test_data[i]*pw[x][i],10) maxclass.append(summ + math.log(pi[x],10)) myclass = ["财经","房产","健康","教育","军事","科技","体育","娱乐","证券" ] #分类集合 i=0 for x in range(9): if maxclass[i]<maxclass[x]: i=x return myclass[i] 

函数声明:根据最后的单词表/final_words将文本向量化
变量说明:
train_data: 训练集数据
test_data: 测试集数据
final_words: 特征集数据
返回值说明:
final_train_data: 训练集向量化列表
final_test_data: 测试集向量化列表

def DataVectoring(train_data,test_data,final_words): def TF(text, final_words): #计算向量值,出现在特征集中为1不然为0 text_set=set(text) returnVec = [1 if word in text_set else 0 for word in final_words] return returnVec final_train_data=[TF(text, final_words) for text in train_data] final_test_data=[TF(text, final_words) for text in test_data] return final_train_data, final_test_data #返回结果 

函数声明: 数据的读入和处理
变量说明
news_toot: 新闻文件夹名称
data_list: 数据集
class_list: 数据集类别
train: 训练集
返回值说明
class_data: 所有的单词分类表
everyclassnum:每一类下的文件数目

def TextPrepare(news_toot): folder_list=os.listdir(news_toot) #找到新闻数据下的子文件 data_list=[] #数据集数据 class_list=[] #数据集的类别 for folder in folder_list: new_child_path=os.path.join(news_toot,folder) files=os.listdir(new_child_path) #存放子文件夹下的txt文件 for file in range(len(files)): with open(os.path.join(new_child_path,files[file]),"r",encoding="utf-8",errors="ignore") as f: data=f.read() word_list=list(data.split()) #将字符串里每一个词提取 data_list.append(word_list) #将其放入训练集 class_list.append(folder) class_data=list(zip(class_list,data_list)) #数据匹配 return class_data 

函数说明:获得训练集和测试集并且得到单词表
参数说明:
class_data: 所有的单词分类表
everyclassnum:每一类下的文件数目
变量说明
train: 训练集
返回值说明
train_data: 训练集单词
train_class: 训练集类别
test_data: 测试集单词
test_class: 测试集类别
mywords: 单词及其在训练集对应出现的次数

def GetTrain_Test(class_data): random.shuffle(class_data) #将其乱序 index=int(len(class_data)*0.1) #训练集和测试集的划分,每一类只抽取百分之八十 test=class_data[0:index] #测试集占比百分之十(每一类抽取百分之八十) train=class_data[index:] #训练集数据占比百分之九十(每一类抽取百分之八十) test_class,test_data=zip(*test) #对测试集解压缩 train_class,train_data=zip(*train) #对训练集解压缩 words={} #存放所有词的字典 for wordlist in train_data: #遍历训练集的数据 for word in wordlist: if word in words.keys(): #将单词放进我的字典并统计次数 words[word] += 1 else: words[word] = 1 mywords = list(words.items()) mywords.sort(key=lambda X:X[1],reverse=True) #对单词表按数目降序排序存储在我的单词表 return mywords,train_class,train_data,test_class,test_data #返回我的单词表,训练集类和数据,测试集类和数据 

函数说明:读取文件的内容并去重
新闻中出现的很多词语(我们,你们)频率很高,但是
他对新闻的分类没有一点帮助,所以我们将其删除
这类词语称为“停用词”,找到网上的停用词表读取内容
并将我的单词表中的停用词删除

变量名说明:
filename: 停用词表文件名
返回值说明:
stopword: 停用词列表

def StopWord(filename): #获得停用词列表 stopword=[] file=open(filename,"r",encoding="utf-8") words=file.read().splitlines() for word in words: if len(word)>0: stopword.append(word) return stopword #获得停用词列表 

函数声明:文本特征选取
变量名说明:
deletenum: 删除词频最高的deleten个词
stopwords: 得到的停用词
mywords: 文本中所有的词语
返回值说明:
final_words: 特征集合

def SelWords(mywords,deletenum,stopwords): #获得特征集 final_words=[] sum1=0 for i in range(deletenum,len(mywords)): if sum1>2000: #训练集大小 break if stopwords.count(mywords[i])==0 and not mywords[i].isdigit() and 1<len(mywords[i]): #如果不是全是数字且不是停用词,那么就放进最终的单词表 final_words.append(mywords[i]) sum1+=1 return final_words 

主函数:

if __name__=="__main__": classdata=TextPrepare("new_weibo_13638") #得到数据准备函数的返回值 stopwords=StopWord("stop.txt") sum_ratio=0 #正确率 for i in range(10): #十次十折交叉验证结果 mywords,train_class,train_data,test_class,test_data=GetTrain_Test(classdata) mywordslist,mywordsnum=zip(*mywords) final_words=SelWords(mywordslist,0,stopwords) #获得特征集 final_train_data,final_test_data=DataVectoring(train_data,test_data,final_words) #根据词向量模型创建数据的矩阵向量 pw,pi=trainNB(array(final_train_data), train_class) yes_sum=0 myclass = ["财经","房产","健康","教育","军事","科技","体育","娱乐","证券" ] for test in range(len(test_class)): a=classNB(array(final_test_data[test]),array(pw),array(pi)) if(test_class[test]==a): #print(test_class[test],i,len(test_class), '分类结果是: ', classNB(final_test_data[test], pw,pi)) yes_sum+=1 print("第"+str(i)+"次的正确率为:",yes_sum/len(test_class)) #输出每次的正确率 sum_ratio+=yes_sum/len(test_class) print("十次十折后最终的正确率为:",sum_ratio/10) #得到平均的正确率 

原文链接:https://blog.csdn.net/weixin_42317689/article/details/88809047?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165277607816782425152803%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=165277607816782425152803&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~times_rank-9-88809047-null-null.nonecase&utm_term=%E6%96%B0%E9%97%BB

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
文明发言,共建和谐米科社区
提交
头像

昵称

取消
昵称表情图片

    暂无评论内容