300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > python基于朴素贝叶斯算法实现新闻分类

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

时间:2018-08-19 08:19:32

相关推荐

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

#_*_ coding=UTF-8 _*_import osimport randomfrom 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#各类文档数目初始为0pn=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#该类文档数目加1breakpw,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=0for 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=0for x in range(9):if maxclass[i]<maxclass[x]:i=xreturn 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不然为0text_set=set(text)returnVec = [1 if word in text_set else 0 for word in final_words]return returnVecfinal_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] += 1else:words[word] = 1mywords = 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=0for i in range(deletenum,len(mywords)):if sum1>2000: #训练集大小breakif stopwords.count(mywords[i])==0 and not mywords[i].isdigit() and 1<len(mywords[i]): #如果不是全是数字且不是停用词,那么就放进最终的单词表final_words.append(mywords[i])sum1+=1return 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=0myclass = ["财经","房产","健康","教育","军事","科技","体育","娱乐","证券" ]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+=1print("第"+str(i)+"次的正确率为:",yes_sum/len(test_class)) #输出每次的正确率sum_ratio+=yes_sum/len(test_class)print("十次十折后最终的正确率为:",sum_ratio/10) #得到平均的正确率

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。