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

数据来源  https://www.sogou.com/labs/resource/cs.php
介绍:来自搜狐新闻2012年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
 8     for line in fileTrainRaw:
 9         fw.write(line.replace(‘&‘,‘&amp;‘)) #去除非法字符
10 fw.write(‘</data>‘)
11 fw.close()

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

import xml.etree.ElementTree as ET
tree = 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]]=1
    else:
        classfiy[url_split[sohu_index-1]]+=1
sorted_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 1643
sh 1298————上海
goabroad 1106
men 1094
2008 842
media 669
2010 558
chihe 532
green 521
astro 360
club 349
gongyi 239
bschool 230
korea 109
games 42
2012 31
dm 29
v 8
campus 2
tuan 1
expo2010 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带来的信息量。
信息量的计算参考这里(https://www.cnblogs.com/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 i
    raise 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():continue
        lable,text = line.strip().split(‘^_^‘,1)
        #print lable,text
        index = lable2id(lable) #类别索引
        #print index
        words = text.split(‘    ‘)
        for word in words:
            if word in stopword :continue
            elif word ==‘ ‘ :continue
            elif word ==‘    ‘ :continue
            wordCount[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
        #break
        for i in range(len(vs)):  #遍历每个分类,计算词项k与文档类别i的互信息MI
            N11 = 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,N00
            mi = 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] = mi
    fWords = 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,酷睿,NVIDIA
auto : 座椅,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,features

def 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 scores

def 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],text
        docCount[index] += 1
    for 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

原文地址:https://www.cnblogs.com/Micang/p/10348240.html

时间: 2024-08-28 05:10:55

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

朴素贝叶斯分类算法原理分析与代码实现

前言 本文介绍机器学习分类算法中的朴素贝叶斯分类算法并给出伪代码,Python代码实现. 词向量 朴素贝叶斯分类算法常常用于文档的分类,而且实践证明效果是挺不错的. 在说明原理之前,先介绍一个叫词向量的概念. --- 它一般是一个布尔类型的集合,该集合中每个元素都表示其对应的单词是否在文档中出现. 对应关系和词汇表一一对应. 比如说,词汇表只有三个单词:'apple', 'orange', 'melo',某文档中,apple和melo出现过,那么其对应的词向量就是 {1, 0, 1}. 这种模型

第五篇:朴素贝叶斯分类算法原理分析与代码实现

前言 本文介绍机器学习分类算法中的朴素贝叶斯分类算法并给出伪代码,Python代码实现. 词向量 朴素贝叶斯分类算法常常用于文档的分类,而且实践证明效果挺不错的. 在说明原理之前,先介绍一个叫词向量的概念. --- 它一般是一个布尔类型的集合,该集合中每个元素都表示其对应的单词是否在文档中出现. 比如说,词汇表只有三个单词:'apple', 'orange', 'melo',某文档中,apple和melo出现过,那么其对应的词向量就是 {1, 0, 1}. 这种模型通常称为词集模型,如果词向量元

利用搜狐新闻语料库训练100维的word2vec——使用python中的gensim模块

语料数据来自搜狐新闻2012年6月-7月期间国内,国际,体育,社会,娱乐等18个频道的新闻数据 数据处理参考这篇文章 模型训练: # -*- coding: utf-8-*- from gensim.models.word2vec import Word2Vec sentences = [['A1','A2'],['A1','A3','A2']] num=0 with open('sohu_train.txt') as trainText: #, encoding='utf-8' for lin

数据挖掘系列(8)朴素贝叶斯分类算法原理与实践

隔了很久没有写数据挖掘系列的文章了,今天介绍一下朴素贝叶斯分类算法,讲一下基本原理,再以文本分类实践. 一个简单的例子 朴素贝叶斯算法是一个典型的统计学习方法,主要理论基础就是一个贝叶斯公式,贝叶斯公式的基本定义如下: 这个公式虽然看上去简单,但它却能总结历史,预知未来.公式的右边是总结历史,公式的左边是预知未来,如果把Y看出类别,X看出特征,P(Yk|X)就是在已知特征X的情况下求Yk类别的概率,而对P(Yk|X)的计算又全部转化到类别Yk的特征分布上来. 举个例子,大学的时候,某男生经常去图

朴素贝叶斯分类算法(1)

转自http://blog.csdn.net/lch614730/article/details/17031145 朴素贝叶斯分类算法(Naive Bayesian classification) PS:本文在讲解的时候会用通俗的例子来讲解 本文我们将学习到: (1)什么是朴素贝叶斯? (2)先验概率和条件概率是如何证明的? (3)文本分类的多项式模型和伯努利模型(附加例子说明) (4)垃圾邮件的分类及代码的演示(暂缺以后会补上) (1)什么是朴素贝叶斯(Naive Bayes,以后简称NB)?

搜狐新闻APP是如何使用HUAWEI DevEco IDE快速集成HUAWEI HiAI Engine

6月12日,搜狐新闻APP最新版本在华为应用市场正式上线啦! 那么,这一版本的搜狐新闻APP有什么亮点呢? 先抛个图,来直接感受下-- ? 模糊图片,瞬间清晰! 效果杠杠的吧. 而藏在这项神操作背后的幕后操手, 竟然是HUAWEI HiAI Engine的图像超分辨率能力. 通过HUAWEI HiAI的图像超分能力处理的照片, 会更清晰,更锐利! 再看下图-- 就是这么任性~ 除此之外,HUAWEI HiAI Engine还提供了人脸识别. 图片识别.码识别.文本识别. 自然语音处理.自动语音识

分类与监督学习,朴素贝叶斯分类算法

1.理解分类与监督学习.聚类与无监督学习. 简述分类与聚类的联系与区别? 分类与聚类:是把某个对象划分到某个具体的已经定义的类别当中,而聚类是把一些对象按照具体特征组织到若干个类别里. 虽然都是把某个对象划分到某个类别中,但是分类的类别是已经预定义的,而聚类操作时,某个对象所属的类别 却不是预定义的,而是可以根据情况做若干个聚类中心. 简述什么是监督学习与无监督学习. 监督学习与无监督学习:对于新的实例,监督学习可以用于映射出该实例的类别. 对于无监督学习,我们只知道特征,并不知 道答案,不同的

48岁单身女与60条流浪狗为伴续:多人向其示爱-搜狐新闻

48岁单身女与60条流浪狗为伴续:多人向其示爱-搜狐新闻 来源:搜狐网 更新时间:2015-04-14 06:43:05 分类:新闻 关键词:流浪狗,示爱 收到示爱电话,王国英既感动又有些哭笑不得.南都记者 陈坤荣 摄 "珠海48岁单身女与60条流浪狗'为伍"追踪 南都讯 记者杨亮 珠海48岁"狗妈妈"王国英放弃记者的工作,不结婚,不生小孩,十余年与60多条流浪狗为伴的动人故事9日经南都披露后引发广泛关注.全国各地不少人士近日纷纷打电话.发短信大胆示爱,让王国英感到

本溪市委书记冮瑞任辽宁省副省长(图)-搜狐新闻

本溪市委书记?瑞任辽宁省副省长(图)-搜狐新闻 来源:搜狐网 更新时间:2015-04-14 08:38:14 分类:新闻 关键词:副省长,市委 ?瑞,男,汉族,1958年5月生,辽宁彰武人,在职研究生学历.1980年2月参加工作,1984年10月入党. 1986.11 先后担任辽宁省商业厅计划业务处副处长.处长和省贸易厅市场处处长等职务 1995.12 辽宁省经贸委副主任.党组成员 2002.12 辽宁省经贸委副主任.党组成员,省口岸办主任(正厅级) 2005.05 辽宁省经委副主任.党组副书