700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 利用朴素贝叶斯分类算法对搜狐新闻进行分类(python)

利用朴素贝叶斯分类算法对搜狐新闻进行分类(python)

时间:2019-01-01 02:46:04

相关推荐

利用朴素贝叶斯分类算法对搜狐新闻进行分类(python)

数据来源 /labs/resource/cs.php

介绍:来自搜狐新闻6月—7月期间国内,国际,体育,社会,娱乐等18个频道的新闻数据,提供URL和正文信息

格式说明:

<doc>

<url>页面URL</url>

<docno>页面ID</docno>

<contenttitle>页面标题</contenttitle>

<content>页面内容</content>

</doc>

注意:content字段去除了HTML标签,保存的是新闻正文文本

一、数据预处理

(1)数据中为上述doc标签的集合,并不是标准的xml文件,首先将数据开头和结尾分别加上'<data>'和</data>根标签。

1 #-*-coding:utf-8-*- 2 # 修复xml格式 3 filePath = 'news_sohusite_xml.dat' #语料路径 4 fileSeqWordDonePath = 'sougou.xml.parse.txt'# 分词后生成路径 5 fw=open(fileSeqWordDonePath, 'w', encoding='utf-8') 6 fw.write('<data>') 7 with open(filePath, 'r', encoding='gb18030' ) as fileTrainRaw: #python3 8for line in fileTrainRaw: 9 fw.write(line.replace('&','&amp;')) #去除非法字符10 fw.write('</data>')11 fw.close()

(2)提取数据中的分类信息并统计,按照二级域名分析相应类别

import xml.etree.ElementTree as ETtree = ET.parse(fileSeqWordDonePath)root = tree.getroot()# print(root.tag)classfiy={}for child in root:#print(child.tag, child.text)url = child.find('url')url_split=url.text.replace('http://','').split('.')sohu_index=url_split.index('sohu')if url_split[sohu_index-1] not in classfiy.keys():classfiy[url_split[sohu_index-1]]=1else:classfiy[url_split[sohu_index-1]]+=1sorted_classfiy=sorted(classfiy.items(),key=operator.itemgetter(1), reverse=True)#排序for c in sorted_classfiy:print(c[0],c[1])

输出结果并分析对应分类:

roll 720957————滚动新闻it 199871————科技auto 138576————汽车news 86052————新闻stock 52930————股票yule 50138————娱乐sports 44536————体育business 27489————财经health 23409————健康learning 13012————教育money 10616————理财s 8678————体育视频book 6532————图书women 5882————女性fund 5015————基金baobao 2693————母婴travel 2179————旅游cul 1924————文化gd 1843————广东tv 1643sh 1298————上海goabroad 1106men 1094 842media 669 558chihe 532green 521astro 360club 349gongyi 239bschool 230korea 109games 42 31dm 29v 8campus 2tuan 1expo 1

选取以下分类进bayes行分类:

it 199871————科技

auto 138576————汽车

stock 52930————股票

yule 50138————娱乐

sports 44536————体育

business 27489————财经

health 23409————健康

learning 13012————教育

money 10616————理财

s 8678————体育视频

book 6532————图书

women 5882————女性

fund 5015————基金

baobao 2693————母婴

travel 2179————旅游

(3)计算互信息,抽取各类中的特征词(对分类具有指示作用的词——增加信息量),统计各分类数量

一个常用的方法是计算文档中的词项t与文档类别c的互信息MI,MI度量的是词的存在与否给类别c带来的信息量。

信息量的计算参考这里(/fengfenggirl/p/text_feature_selection.html)

计算每个词与与每个分类的互信息,每个类别下,互信息排名前200个单词被保留,将他们加入特征词集合。

根据这里的代码做修改,使用jieba分词,并去除停用词,将新闻数据重新组织,仅保留分类和新闻标题及正文

def get_stopword_set(filename='stop_word.txt'):a=[]with open(filename, encoding='utf-8') as trainText:for line in trainText:a.append(line.strip())return sorted(set(a))lables = ['it','auto','stock','yule','sports','business','health','learning','money','s','book','women','fund','baobao','travel']def lable2id(lable):for i in range(len(lables)):if lable == lables[i]:return iraise Exception('Error lable %s' % (lable))def doc_dict():'''构造和类别数等长的0向量'''return [0]*len(lables)def mutual_info(N,Nij,Ni_,N_j):'''计算互信息,这里log的底取为2'''return Nij * 1.0 / N * math.log(N * (Nij+1)*1.0/(Ni_*N_j))/ math.log(2)def count_for_cates(trainText, featureFile):'''遍历文件,统计每个词在每个类别出现的次数,和每类的文档数并写入结果特征文件'''docCount = [0] * len(lables)wordCount = collections.defaultdict(doc_dict)stopword=get_stopword_set()#扫描文件和计数 for line in trainText:if not line.strip():continuelable,text = line.strip().split('^_^',1)#print lable,textindex = lable2id(lable) #类别索引#print indexwords = text.split(' ')for word in words:if word in stopword :continueelif word ==' ' :continueelif word ==' ' :continuewordCount[word][index] += 1 #每个单词在每个类别中的计数docCount[index] += 1 #各类别单词计数#计算互信息值print(u"计算互信息,提取关键/特征词中,请稍后...")miDict = collections.defaultdict(doc_dict)N = sum(docCount)for k,vs in wordCount.items(): #遍历每个单词#print 'k,vs', k,vs#breakfor i in range(len(vs)): #遍历每个分类,计算词项k与文档类别i的互信息MIN11 = vs[i] #类别i下单词k的数量N10 = sum(vs) - N11 #非类别i下单词k的数量N01 = docCount[i] - N11 #类别i下其他单词数量N00 = N - N11 - N10 - N01 #其他类别中非k单词数目#print N11,N10,N01,N00mi = mutual_info(N,N11,N10+N11,N01+N11) + mutual_info(N,N10,N10+N11,N00+N10)+ mutual_info(N,N01,N01+N11,N01+N00)+ mutual_info(N,N00,N00+N10,N00+N01)miDict[k][i] = mifWords = set()for i in range(len(docCount)): #遍历每个单词keyf = lambda x:x[1][i]sortedDict = sorted(miDict.items(),key=keyf,reverse=True)t=','.join([w[0] for w in sortedDict[:20]])print(lables[i] ,':',t)for j in range(1000):fWords.add(sortedDict[j][0])out = open(featureFile, 'w', encoding='utf-8')#输出各个类的文档数目out.write(str(docCount)+"\n")#输出互信息最高的词作为特征词for fword in fWords:out.write(fword+"\n")print(u"特征词写入完毕...")out.close()if __name__=="__main__":# print(get_stopword_set())_trainText=[]with open('sohu_train.txt', encoding='utf-8') as trainText:for line in trainText:id,catgre,body= line.split('^_^')#print id,catgre_trainText.append(catgre+'^_^'+body)#数据打乱分成两份,4/5用来训练,1/5用来测试 random.shuffle(_trainText)num = len(_trainText)_testText = _trainText[4*num//5:]_trainText = _trainText[:4*num//5]# #计算互信息,提取关键字count_for_cates(_trainText, 'featureFile')

打印每个类别中排名前20的特征词:

PS D:\学习\朴素贝叶斯-文本分类\news_sohusite_xml.full> python3 .\bayes_classfify.py计算互信息,提取关键/特征词中,请稍后...it : 系列,CPU,华硕,英寸,尺寸,主频,屏幕,硬盘容量,内存容量,芯片,显卡,Intel,参数,操作系统,型号,产品,Windows,酷睿,NVIDIAauto : 座椅,mm,调节,系列,CPU,华硕,电动,发动机,L,元,后排,汽车,方向盘,英寸,系统,车型,主频,车,屏幕stock : 万股,公司,系列,CPU,华硕,公告,股份,证券,英寸,股,尺寸,A股,参数,主频,屏幕,硬盘容量,内存容量,显卡,芯片yule : 娱乐,讯,电影,系列,CPU,导演,华硕,观众,演员,主演,英寸,产品,拍摄,尺寸,饰演,搜狐,参数,主频,屏幕sports : 比赛,球队,球员,系列,CPU,华硕,开出,赛季,号码,期,联赛,冠军,英寸,尺寸,产品,球迷,对手,主场,参数business : 系列,CPU,华硕,经济,市场,英寸,尺寸,主频,参数,屏幕,硬盘容量,内存容量,显卡,芯片,公司,Intel,企业,座椅,型号health : 本品,治疗,患者,主任医师,处方,看病,大夫,医院,服用,下夜,疾病,剂量,医生,用量,过程,就医,国药准字,应,禁用learning : 类,专业,考生,第二批,经济学,第一批,录取,高考,学校,学生,招生,教育,第三批,平均分,高校,批次,志愿,科学,电子信息money : 银行,信托,收益率,投资,理财产品,系列,终止,CPU,华硕,理财,美元,提前,收益,保障,预期,英寸,黄金,尺寸,资产s : 视频,体育,天下,时间,北京,CBA,集锦,广播节目,收看,轮,西甲,搜狐,破门,VS,赛季,日,系列,联赛,比赛book : 说,看着,币,系列,原创,想,走,CPU,华硕,凌天,黎涵,道,女人,里,七妹,产品,英寸,尺寸,馥薰women : 肌肤,肤质,功效,库,制造商,品牌,所属,保湿,官网,商品,精华,男人,CPU,华硕,女人,美白,皮肤,介绍,滋润fund : 基金,0.00,投资,证券,申购,代销,净值,起始,债券,开放式,代码,指数,费率,收益,股票,有限公司,管理,日常,机构,赎回baobao : 宝宝,孩子,妈妈,怀孕,胎儿,吃,孕妇,准妈妈,系列,婴儿,发育,父母,幼儿园,CPU,家长,华硕,食物,儿童,营养travel : 旅游,概述,攻略,位于,景区,简介,温泉,平方公里,系列,米,公里,公园,景点,面积,CPU,48262083,华硕,河南,版友

二、训练模型,计算先验概率,即每个类别下各个单词出现的概率

def load_feature_words(featureFile):'''从特征文件导入特征词'''f = open(featureFile, encoding='utf-8')#各个类的文档数目docCounts = eval(f.readline())features = set()#读取特征词for line in f:features.add(line.strip())f.close()return docCounts,featuresdef train_bayes(featureFile, textFile, modelFile):'''训练贝叶斯模型,实际上计算每个类中特征词的出现次数'''print(u"使用朴素贝叶斯训练中...")docCounts,features = load_feature_words(featureFile) #读取词频统计和特征词wordCount = collections.defaultdict(doc_dict)# #每类文档特征词出现的次数tCount = [0]*len(docCounts)# for line in open(textFile).readlines():for line in textFile: #遍历每个文档lable,text = line.strip().split('^_^',1)index = lable2id(lable) words = text.strip().split(' ')for word in words: #遍历文档中每个词if word in features and word !='':tCount[index] += 1#类别index中单词总数计数wordCount[word][index] += 1 #类别index中单词word的计数outModel = open(modelFile, 'w', encoding='utf-8')#拉普拉斯平滑print(u"训练完毕,写入模型...")for k,v in wordCount.items(): #遍历每个单词scores = [(v[i]+1) * 1.0 / (tCount[i]+len(wordCount)) for i in range(len(v))] #遍历每个类别i,计算该类别下单词的出现概率(频率)outModel.write(k+"\t"+str(scores)+"\n") #保存模型,记录类别i下单词k的出现概率(频率) outModel.close()if __name__=="__main__":# print(get_stopword_set())_trainText=[]with open('sohu_train.txt', encoding='utf-8') as trainText:for line in trainText:id,catgre,body= line.split('^_^')#print id,catgre_trainText.append(catgre+'^_^'+body)#数据打乱分成两份,4/5用来训练,1/5用来测试 random.shuffle(_trainText)num = len(_trainText)_testText = _trainText[4*num//5:]_trainText = _trainText[:4*num//5]# #计算互信息,提取关键字count_for_cates(_trainText, 'featureFile')#训练,计算先验概率train_bayes('./featureFile', _trainText, './modelFile')

三、模型测试,通过贝叶斯公式预测分类,并评价分类精度

def load_model(modelFile):'''从模型文件中导入计算好的贝叶斯模型'''print(u"加载模型中...")f = open(modelFile, encoding='utf-8')scores = {}for line in f:word,counts = line.strip().rsplit('\t',1) scores[word] = eval(counts)f.close()return scoresdef predict(featureFile, modelFile, testText):'''预测文档的类标,标准输入每一行为一个文档'''docCounts,features = load_feature_words(featureFile) #读取词频统计和特征词 docScores = [math.log(count * 1.0 /sum(docCounts)) for count in docCounts] #每个类别出现的概率scores = load_model(modelFile) #加载模型,每个单词在类别中出现的概率rCount = [0]*len(lables)docCount = [0]*len(lables)print(u"正在使用测试数据验证模型效果...")for line in testText:lable,text = line.strip().split('^_^',1)index = lable2id(lable) words = text.split(' ')preValues = list(docScores)for word in words:if word in features and word !='':for i in range(len(preValues)):preValues[i]+=math.log(scores[word][i]) #利用贝叶斯公式计算对数概率,后半部分为每个类别中单词word的出现概率m = max(preValues)#取出最大值pIndex = preValues.index(m) #取出最大值类别的索引if pIndex == index: #预测分类正确rCount[index] += 1#print lable,lables[pIndex],textdocCount[index] += 1for r in range(len(lables)):print(u"类别:%s,测试文本量: %d , 预测正确的类别量: %d, 朴素贝叶斯分类器准确度:%f" %(lables[r],rCount[r],docCount[r],rCount[r] * 1.0 / docCount[r]))print(u"总共测试文本量: %d , 预测正确的类别量: %d, 朴素贝叶斯分类器准确度:%f" %(sum(rCount),sum(docCount),sum(rCount) * 1.0 / sum(docCount))) if __name__=="__main__":# print(get_stopword_set())_trainText=[]with open('sohu_train.txt', encoding='utf-8') as trainText:for line in trainText:id,catgre,body= line.split('^_^')#print id,catgre_trainText.append(catgre+'^_^'+body)#数据打乱分成两份,4/5用来训练,1/5用来测试 random.shuffle(_trainText)num = len(_trainText)_testText = _trainText[4*num//5:]_trainText = _trainText[:4*num//5]# #计算互信息,提取关键字# count_for_cates(_trainText, 'featureFile')#训练,计算先验概率# train_bayes('./featureFile', _trainText, './modelFile')#预测predict('./featureFile', './modelFile', _testText)

打印各类的分类精度和总体精度:

正在使用测试数据验证模型效果...类别:it,测试文本量: 35385 , 预测正确的类别量: 39647, 朴素贝叶斯分类器准确度:0.892501类别:auto,测试文本量: 23320 , 预测正确的类别量: 27658, 朴素贝叶斯分类器准确度:0.843156类别:stock,测试文本量: 6335 , 预测正确的类别量: 10769, 朴素贝叶斯分类器准确度:0.588263类别:yule,测试文本量: 9591 , 预测正确的类别量: 10091, 朴素贝叶斯分类器准确度:0.950451类别:sports,测试文本量: 8299 , 预测正确的类别量: 9007, 朴素贝叶斯分类器准确度:0.921394类别:business,测试文本量: 3025 , 预测正确的类别量: 5493, 朴素贝叶斯分类器准确度:0.550701类别:health,测试文本量: 4461 , 预测正确的类别量: 4662, 朴素贝叶斯分类器准确度:0.956885类别:learning,测试文本量: 2340 , 预测正确的类别量: 2569, 朴素贝叶斯分类器准确度:0.910860类别:money,测试文本量: 1440 , 预测正确的类别量: 2070, 朴素贝叶斯分类器准确度:0.695652类别:s,测试文本量: 1414 , 预测正确的类别量: 1786, 朴素贝叶斯分类器准确度:0.791713类别:book,测试文本量: 844 , 预测正确的类别量: 1328, 朴素贝叶斯分类器准确度:0.635542类别:women,测试文本量: 848 , 预测正确的类别量: 1196, 朴素贝叶斯分类器准确度:0.709030类别:fund,测试文本量: 942 , 预测正确的类别量: 1039, 朴素贝叶斯分类器准确度:0.906641类别:baobao,测试文本量: 429 , 预测正确的类别量: 542, 朴素贝叶斯分类器准确度:0.791513类别:travel,测试文本量: 410 , 预测正确的类别量: 455, 朴素贝叶斯分类器准确度:0.901099总共测试文本量: 99083 , 预测正确的类别量: 118312, 朴素贝叶斯分类器准确度:0.837472

参考

/fengfenggirl/p/bayes_classify.html

/han_xiaoyang/article/details/50629608

/fengfenggirl/p/text_feature_selection.html

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