1、数据挖掘8朴素贝叶斯分类算法原理与实践数据挖掘(8):朴素贝叶斯分类算法原理与实践隔了很久没有写数据挖掘系列的文章了,今天介绍一下朴素贝叶斯分类算法,讲一下基本原理,再以文本分类实践。一个简单的例子朴素贝叶斯算法是一个典型的统计学习方法, 主要理论基础就是一个贝叶斯公式, 贝叶斯公式的基本定义如下:咖呵耳)5卜丿 p(r)p(|y.)j这个公式虽然看上去简单,但它却能总结历史,预知未来。公式的右边是总结历史,公式的左边是预知未来,如果把 Y看出类别,X看出特征,P(Yk|X)就是在已知特征 X的 情况下求Yk类别的概率,而对 P(Yk|X)的计算又全部转化到类别 Yk的特征分布上来。举个例子,
2、大学的时候,某男生经常去图书室晚自习,发现他喜欢的那个女生也常去那个自习室,心中窃喜,于是每天买点好吃点在那个自习室蹲点等她来,可是人家女生不 一定每天都来,眼看天气渐渐炎热,图书馆又不开空调,如果那个女生没有去自修室,该男生也就不去,每次男生鼓足勇气说: “嘿,你明天还来不?” ,“啊,不知道,看情况”。然后该男生每天就把她去自习室与否以及一些其他情况做一下记录, 用Y表示该女生是否去自习室,即 Y=去,不去,X是跟去自修室有关联的一系列条件,比如当天 上了哪门主课,蹲点统计了一段时间后,该男生打算今天不再蹲点,而是先预测一下她P(Y=去|常微分方会不会去,现在已经知道了今天上了常微分方法这
3、么主课,于是计算程)与P(Y=不去|常微分方程),看哪个概率大,如果 P(Y=去|常微分方程)P(Y=不去| 常微分方程),那这个男生不管多热都屁颠屁颠去自习室了,否则不就去自习室受罪了。P(Y=去|常微分方程)的计算可以转为计算以前她去的情况下, 那天主课是常微分的概率 P(常微分方程|Y=去),注意公式右边的分母对每个类别(去 /不去)都是一样的,所以 计算的时候忽略掉分母,这样虽然得到的概率值已经不再是 01之间,但是其大小还是能选择类别。后来他发现还有一些其他条件可以挖,比如当天星期几、当天的天气,以及上一次与她 在自修室的气氛,统计了一段时间后,该男子一计算,发现不好算了,因为总结历
4、史的 公式:尸(X二詛丫二住)二尸(乳二只久去的二*叫丫二耳)这里n=3 , x(1)表示主课,x(2)表示天气,x(3)表示星期几,x表示气氛,Y仍然是去,不去,现在主课有8门,天气有晴、雨、阴三种、气氛有 A+,A,B+,B,C五种,那么 总共需要估计的参数有 8*3*7*5*2=1680 个,每天只能收集到一条数据,那么等凑齐1 680条数据大学都毕业了,男生打呼不妙,于是做了一个独立性假设,假设这些影响她 去自习室的原因是独立互不相关的,于是P(XxY二兔)二P(无二 二曲)| Y二q匸疔P(无二凶)| 作y=i有了这个独立假设后,需要估计的参数就变为, (8+3+7+5)*2 = 4
5、6个了,而且每天 收集的一条数据,可以提供 4个参数,这样该男生就预测越来越准了朴素贝叶斯分类器讲了上面的小故事,我们来朴素贝叶斯分类器的表示形式:P(Y=ck)Y P(X =应” F 二)k小呷晋心护十呷豎子(命paowq当特征为为x时,计算所有类别的条件概率,选取条件概率最大的类别作为待分类的类 别。由于上公式的分母对每个类别都是一样的,因此计算时可以不考虑分母,即y- f (x) - arg max p(y = ) p( = .r朴素贝叶斯的朴素体现在其对各个条件的独立性假设上, 加上独立假设后,大大减少了参数假设空间。在文本分类上的应用文本分类的应用很多,比如垃圾邮件和垃圾短信的过滤就
6、是一个 2分类问题,新闻分类、文本情感分析等都可以看成是文本分类问题,分类问题由两步组成:训练和预测,要建 立一个分类模型,至少需要有一个训练数据集。贝叶斯模型可以很自然地应用到文本分 类上:现在有一篇文档 d( Document ),判断它属于哪个类别 ck,只需要计算文档d 属于哪一个类别的概率最大:在分类问题中,我们并不是把所有的特征都用上,对一篇文档 d,我们只用其中的部分特征词项 (nd表示d中的总词条数目),因为很多词项对分类是没有价 值的,比如一些停用词“的,是,在”在每个类别中都会出现,这个词项还会模糊分类的 决策面,关于特征词的选取,我的这篇文章有介绍。用特征词项表示文档后,
7、计算文档 d的类别转化为:=argmaxj /(8 + 6) = 1/14=仃 + 1)/(3+ 6) =2/9=(1 +1)/(3+ 6) =2/9注意分母(8+6 )中8表示China类的词项出现的总次数是 8,+6表示平滑,6是总词项的个数,然后计算测试文档属于各个类别的概率:P(c|d5) (K 3/4 - (3/7)3.1/14 1/14 * 0,0003.P(可如 ck 1/4 *(2/9) 3 *2/9 -2/9 O.OOOL可以看出该测试文档应该属于 CHina类别文本分类实践我找了搜狗的搜狐新闻数据的历史简洁版, 总共包括汽车、财经、it、健康等9类新闻, 一共16289条新
8、闻,搜狗给的数据是每一篇新闻用一个 txt文件保存,我预处理了一下, 把所有的新闻文档保存在一个文本文件中,每一行是一篇新闻,同时保留新闻的 id,id的首字母表示类标,预处理并分词后的示例如下:tags 三一 磴境 報名 m经 运束. 而 王一 黄金 哥 H后 的 投名 则 讦始 全】2 Hiog 离人 我之所以将誉輕茁和宋全阳这蒔金悪人归到穷人-3 F202 C新:t化投记者韩冰I 1SB *周六吗时 央视经济:&9S1 如M坪空军招飞 H作己幵皓预琏报名工作”荷合基本条件的学企5 E.79 詐天记者从延庆八运岭特区力事处了迢聖”以舒轍三蘇呈住 GA95 大学毕业生妻找的只是令工作而不是职
9、业更不是事业-H72 现在我是个咸功的商人可上世記八十年代-我晟个壮热得表 C1421 陌友:我孚亲年莉做了左乳疇手朮大夫给他母亲开了 -G32O 第说25歩一是女人幵始吒鱼星皱的年龄”養 f 紧张一一宜索张我用6289条新闻作为训练集,剩余1万条用于测试,采用互信息进行文本特征的提取, 总共提取的特征词是700个左右。分类的结果如下:8343100000.8343总共10000条新闻,分类正确的 8343条,正确率0.8343,这里主要是演示贝叶斯的分类过程,只考虑了正确率也没有考虑其他评价指标,也没有进行优化。贝叶斯分类的 效率高,训练时,只需要扫描一遍训练集,记录每个词出现的次数,以及各
10、类文档出现 的次数,测试时也只需要扫描一次测试集,从运行效率这个角度而言,朴素贝叶斯的效 率是最高的,而准确率也能达到一个理想的效果。我的实现代码如下:#!encoding=utf-8importrandomimportsysimportmathimportcollectionsimportsysdfef shuffle():8 ”将原来的文本打乱顺序,用于得到训练集和测试集9 datas =line.strip() for line in sys.stdin10 random.shuffle(datas)11 for line in datas:12print line13 14liable
11、s = A , B , C ,D , E , F , G , H , T 1def lable2id(lable):17 for i in xrange (len (lables):18 if lable =lablesi:19 return i20 raise Exception( Error lable %s %(lable)212fef docdict():23 return 0 * len (lables)2425ef mutallnfo(N,Nij,Ni_,N_j):26 #print N,Nij,Ni_,N _j27 return Nij * 1.0 /N * math.log(N
12、 *(Nij +1) * 1.0 / (Ni_ *N)/ math.log( 2)282fef countForMI():30 基于统计每个词在每个类别岀现的次数,以及每类的文档数 31 docCount = 0 *len (lables) #每个类的词数目32 wordCount =collections.defaultdict(docdict)33for linein sys.stdin:34lable,text= line.strip().split( ,1)35index=lable2id(lable0)36words=text.split( )37forword in words:3
13、8wordCountwordindex+=139docCountindex+=14041 miDict =collections.defaultdict(docdict) #互信息值42 N=sum(docCount)43for k,vsin wordCount.items():44fori in xrange ( len (vs):45N11=vsi46N10=sum(vs) - N1147N01=docCounti -N1148N00=N - N11 - N10 -N0149mi=mutalInfo(N,N11,N10 +N11,N01 +N11)5lmutalInfo(N,N10,N10
14、 +N11,N00+N10)+mutallnfo(N,N01,N01 +N11,N01 +N00)+mutallnfo(N,N005N00 +N10,N00 +N01)52 miDictki =mi53 fWords=set ()54for iin xrange (len (docCount):55keyf=lambda x:x 1i56sortedDict =sorted (miDict.items(),key= keyf,reverse =True)58 fWords.add(sortedDictj 0)59 print docCount #打印各个类的文档数目60 for fword i
15、n fWords:61 print fword626364ef loadFeatureWord():65 ”导入特征词”66 f =open (feature.txt )67 docCounts =eval (f.readline()68 features =set ()69 for line in f:70 features.add(line.strip()71 f.close()72 return docCounts,features7374ef MainBayes():75 ”训练贝叶斯模型,实际上计算每个类中特征词的岀现次数76 docCounts,features =loadFeat
16、ureWord()77 wordCount =collections.defaultdict(docdict)78 tCount = 0 * len (docCounts) #每类文档特征词出现的次数79 for line in sys.stdin:80lable,text =line.strip().split(81index =lable2id(lable 0)82words =text.split( )83for word in words:84if word in features:85tCountindex+=186wordCountwordindex87for k,v in wor
17、dCount.items():88scores =(vi+1) *1.0/ (tCounti819平滑90print %st%s%(k,scores)919fef loadModel():93”导入贝叶斯模型III94 f=open (model.txt)95 scores =96for line in f:97word,counts=line.strip().rsplit(98scoresword=eval (counts)t , 1),1)+=1+ len (wordCount) for i in xrange (len (v) #力口99 f.close()100 return scor
18、es101 10def predict。:103 ”预测文档的类标,标准输入每一行为一个文档107 rCount =0108 docCount =0109 for line in sys.stdin:114 for word in words:115 if word in features:for i in xrange (len (preValues):118 m =max(preValues)119 pIndex=preValues.index(m)120 if pIndex =index:121 rCount +=1122 print lable,lablesplndex,text123
19、 docCount +=1124 print rCount,docCount,rCount * 1.0 / docCount125125 127 _name_ =_main_ 128 #shuffle() #countForMI() #trainBayes() predict()main方法,比如计算特代码里面,计算特征词与训练模型、测试是分开的,需要修改 征词:$fcat train.txt | python bayes.py feature.txt训练模型:$fcat train.txt | python bayes.py model.txt预测模型:$Cat test.txt | python bayes.py predict.out总结本文介绍了朴素贝叶斯分类方法,还以文本分类为例,给出了一个具体应用的例子,朴素贝叶斯的朴素体现在条件变量之间的独立性假设, 应用到文本分类上,作了两个假设,一是各个特征词对分类的影响是独立的,另一个是词项在文档中的顺序是无关紧要的。朴素贝叶斯的独立性假设在实际中并不成立, 但在分类效上依然不错, 加上独立性假设后,对与属于类ck的谋篇文档d,其p(ck|d)往往会估计过高,即本来预期 p(ck|d)=0.55 ,而朴素贝叶斯却计算得到 p(ck|d)=0.99 ,但这并不影响分类结果,这是朴素贝叶 斯分类器在文本分类上效果优于预期的原因。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1