• 朴素贝叶斯文本分类(python代码实现)


    朴素贝叶斯(naive bayes)法是基于贝叶斯定理与特征条件独立假设的分类方法。

    • 优点:在数据较少的情况下仍然有效,可以处理多分类问题。
    • 缺点:对入输入数据的准备方式较为敏感。
    • 使用数据类型:标称型数据。

    下面从一个简单问题出发,介绍怎么使用朴素贝叶斯解决分类问题。 
    一天,老师问了个问题,只根据头发和声音怎么判断一位同学的性别。 
    为了解决这个问题,同学们马上简单的统计了7位同学的相关特征,数据如下:

    头发声音性别

    这个问题之前用决策树做过了,这里我们换一种思路。 
    要是知道男生和女生头发长短的概率以及声音粗细的概率,我们就可以计算出各种情况的概率,然后比较概率大小,来判断性别。 
    假设抽样样本足够大,我们可以近似认为可以代表所有数据,假设上位7位同学能代表所有数据,这里方便计算~ 
    由这7位同学,我们马上得出下面表格概率分布。

    性别头发长声音粗
    1/3 1
    3/5 3/5

    假设头发和声音都是独立特征,于是 
    男生头发长声音粗的概率=3/8*1/3*1=1/8 
    女生头发长声音粗的概率=5/8*3/5*3/5=9/40 
    因为1/8<9/40所以如果一个人,头发长,声音粗,那么这个人更可能是女生,于是出现这些特征就是女生。其他特征依次类推。 
    这就是朴素贝叶斯分类方法。是的,就是这么简单。 
    下面来解释原理,先看贝叶斯公式: 
    这里写图片描述

    公式中,事件Bi的概率为P(Bi),事件Bi已发生条件下事件A的概率为P(A│Bi),事件A发生条件下事件Bi的概率为P(Bi│A)。 
    带入我们的例子中,判断头发长的人性别: 
    P(男|头发长)=P(头发长|男)*P(男)/P(头发长) 
    P(女|头发长)=P(头发长|女)*P(女)/P(头发长) 
    判断头发长、声音粗的人性别: 
    P(男|头发长声音粗)=P(头发长|男)P(声音粗|男)*P(男)/P(头发长声音粗) 
    P(女|头发长声音粗)=P(头发长|女)P(声音粗|女)*P(女)/P(头发长声音粗) 
    可以看到,比较最后比较概率,只用比较分子即可。也就是前面计算头发长声音粗的人是男生女生的概率。

    下面应用于文本分类,文本分类不想上面例子有具体的特征,需先建立文本特征。以下为文本分类的一个简单例子。

     1 # _*_ coding:utf-8 _*_
     2 from numpy import *
     3 import re
     4 import random
     5 
     6 def loadDataSet(): #创建样例数据
     7     postingList = [['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
     8                    ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
     9                    ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
    10                    ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
    11                    ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
    12                    ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
    13     classVec = [0, 1, 0, 1, 0, 1]  #1代表脏话
    14     return postingList, classVec
    15 
    16 def createVocabList(dataSet):  #创建词库 这里就是直接把所有词去重后,当作词库
    17     vocabSet = set([])
    18     for document in dataSet:
    19         vocabSet = vocabSet | set(document)
    20     return list(vocabSet)
    21 
    22 def setOfWords2Vec(vocabList, inputSet):  #文本词向量。词库中每个词当作一个特征,文本中就该词,该词特征就是1,没有就是0
    23     returnVec = [0] * len(vocabList)
    24     for word in inputSet:
    25         if word in vocabList:
    26             returnVec[vocabList.index(word)] = 1
    27         else:
    28             print("the word: %s is not in my Vocabulary!" % word)
    29     return returnVec
    30 
    31 
    32 def trainNB0(trainMatrix, trainCategory):
    33     numTrainDocs = len(trainMatrix)
    34     numWords = len(trainMatrix[0])
    35     pAbusive = sum(trainCategory) / float(numTrainDocs)
    36     p0Num = ones(numWords) #防止某个类别计算出的概率为0,导致最后相乘都为0,所以初始词都赋值1,分母赋值为2.
    37     p1Num = ones(numWords)
    38     p0Denom = 2
    39     p1Denom = 2
    40     for i in range(numTrainDocs):
    41         if trainCategory[i] == 1:
    42             p1Num += trainMatrix[i]
    43             p1Denom += sum(trainMatrix[i])
    44         else:
    45             p0Num += trainMatrix[i]
    46             p0Denom += sum(trainMatrix[i])
    47     p1Vect = log(p1Num / p1Denom)  #这里使用了Log函数,方便计算,因为最后是比较大小,所有对结果没有影响。
    48     p0Vect = log(p0Num / p0Denom)
    49     return p0Vect, p1Vect, pAbusive
    50 
    51 def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1): #比较概率大小进行判断,
    52     p1 = sum(vec2Classify*p1Vec)+log(pClass1)
    53     p0 = sum(vec2Classify*p0Vec)+log(1-pClass1)
    54     if p1>p0:
    55         return 1
    56     else:
    57         return 0
    58 
    59 def testingNB():
    60     listOPosts,listClasses = loadDataSet()
    61     myVocabList = createVocabList(listOPosts)
    62     trainMat=[]
    63     for postinDoc in listOPosts:
    64         trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
    65     p0V,p1V,pAb = trainNB0(array(trainMat),array(listClasses))
    66     testEntry = ['love', 'my', 'dalmation'] # 测试数据
    67     thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
    68     print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))
    69     testEntry = ['stupid', 'garbage'] # 测试数据
    70     thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
    71     print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))
    72 
    73 if __name__=='__main__':
    74     testingNB()
    1 #输出结果
    2 ['love', 'my', 'dalmation'] classified as:  0
    3 ['stupid', 'garbage'] classified as:  1

    参考: 
    - Machine Learning in Action 
    - 统计学习方法

    转载:http://blog.csdn.net/csqazwsxedc/article/details/69488938

  • 相关阅读:
    SVN 使用锁实现独占式签出
    浏览器console中加入jquery方便调试
    nuget安装说明
    sql server 索引优化
    Windwos Server 2016 远程桌面授权
    tomcat的安装与配置
    业务监控
    敏捷话管理团队
    一键搞定多服务器的更新
    迁移历史sql数据
  • 原文地址:https://www.cnblogs.com/luozeng/p/8605090.html
Copyright © 2020-2023  润新知