zoukankan      html  css  js  c++  java
  • 朴素贝叶斯——文本分类

    朴素贝叶斯是基于贝叶斯定理于独立分布假设的分类算法

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

    标称型数据和数值型数据的区别:

    1 标称型:标称型目标变量的结果只在有限目标集中取值,如真与假(标称型目标变量主要用于分类)一般在有限的数据中取,而且只存在‘是’和‘否’两种不同的结果(一般用于分类)
    2 数值型:数值型目标变量则可以从无限的数值集合中取值,如0.100,42.001等 (数值型目标变量主要用于回归分析)

    使用下面数据解释贝叶斯

    头发声音性别

    我们得到下面的概率分布:

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

    假设头发和声音都是相互独立

    1 男生头发长声音粗的概率=3/8*1/3*1=1/8 
    2 女生头发长声音粗的概率=5/8*3/5*3/5=9/40 
    3 因为1/8<9/40所以如果一个人,头发长,声音粗,那么这个人更可能是女生,于是出现这些特征就是女生。其他特征依次类推

    条件概率:

    贝叶斯公式:

     由条件概率可得:

     因此得到贝叶斯的常规形式:

    全概率和贝叶斯公式结合:

    公式中,事件Bi的概率为P(Bi),事件Bi已发生条件下事件A的概率为P(A│Bi),事件A发生条件下事件Bi的概率为P(Bi│A)

    判断头发长的人性别: 

    1 P(男|头发长)=P(头发长|男)*P(男)/P(头发长) 
    2 P(女|头发长)=P(头发长|女)*P(女)/P(头发长) 

    判断头发长、声音粗的人性别: 

    1 P(男|头发长声音粗)=P(头发长|男)P(声音粗|男)*P(男)/P(头发长声音粗) 
    2 P(女|头发长声音粗)=P(头发长|女)P(声音粗|女)*P(女)/P(头发长声音粗) 

    可以看到,比较最后比较概率,只用比较分子即可。也就是前面计算头发长声音粗的人是男生女生的概率

    # -*- coding: utf-8 -*-
    """
    Created on Mon May 18 17:53:32 2020
    
    @author: Admin
    """
    
    
    from numpy import *
    import re
    import random
    
    def loadDataSet(): #创建样例数据
        postingList = [['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
                       ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
                       ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
                       ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
                       ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
                       ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
        classVec = [0, 1, 0, 1, 0, 1]  #1代表脏话
        return postingList, classVec
    
    def createVocabList(dataSet):  #创建词库 这里就是直接把所有词去重后,当作词库
        vocabSet = set([])
        for document in dataSet:
            vocabSet = vocabSet | set(document)
        return list(vocabSet)
    
    #得到一个和词库长度一样的向量,该词在词库里存在,则该词在词库中的位置将被赋值1,否则0
    def setOfWords2Vec(vocabList, inputSet):  #文本词向量。词库中每个词当作一个特征,文本中就该词,该词特征就是1,没有就是0
        returnVec = [0] * len(vocabList)
        for word in inputSet:
            if word in vocabList:
                returnVec[vocabList.index(word)] = 1  #首先找到该词在词库中的位置索引,然后赋值为1 
            else:
                print("the word: %s is not in my Vocabulary!" % word)
        return returnVec
    
    
    def trainNB0(trainMatrix, trainCategory):
        numTrainDocs = len(trainMatrix)   #上面得到的词向量中共有多少行
        numWords = len(trainMatrix[0])  #第一行有多少个元素
        pAbusive = sum(trainCategory) / float(numTrainDocs)  #label的值相加(等于3),除以向量中共有多少行(6)
        p0Num = ones(numWords) #防止某个类别计算出的概率为0,导致最后相乘都为0,所以初始词都赋值1,分母赋值为2.
        p1Num = ones(numWords)
        p0Denom = 2
        p1Denom = 2
        for i in range(numTrainDocs):
            if trainCategory[i] == 1:
                p1Num += trainMatrix[i]
                p1Denom += sum(trainMatrix[i])
            else:
                p0Num += trainMatrix[i]
                p0Denom += sum(trainMatrix[i])
        p1Vect = log(p1Num / p1Denom)  #这里使用了Log函数,方便计算,因为最后是比较大小,所有对结果没有影响。
        p0Vect = log(p0Num / p0Denom)
        return p0Vect, p1Vect, pAbusive
    
    def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1): #比较概率大小进行判断,
        p1 = sum(vec2Classify*p1Vec)+log(pClass1)
        p0 = sum(vec2Classify*p0Vec)+log(1-pClass1)
        if p1>p0:
            return 1
        else:
            return 0
    
    def testingNB():
        listOPosts,listClasses = loadDataSet()
        myVocabList = createVocabList(listOPosts)
        trainMat=[]
        for postinDoc in listOPosts:
            trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
        p0V,p1V,pAb = trainNB0(array(trainMat),array(listClasses))
        testEntry = ['love', 'my', 'dalmation'] # 测试数据
        thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
        print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))
        testEntry = ['stupid', 'garbage'] # 测试数据
        thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
        print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))
    
    if __name__=='__main__':
        testingNB()

    问题:如果是晴天,这个人就能出去玩。这个说法是不是正确的?

    P(是|晴朗)=P(晴朗|是)×P(是)/P(晴朗)

    在这里,P(晴朗|是)= 3/9 = 0.33,P(晴朗)= 5/14 = 0.36,P(是)= 9/14 = 0.64

    现在,P(是|晴朗)=0.33×0.64/0.36=0.60,具有较高的概率。

  • 相关阅读:
    在IE和Firfox获取keycode
    using global variable in android extends application
    using Broadcast Receivers to listen outgoing call in android note
    help me!virtual keyboard issue
    using iscroll.js and iscroll jquery plugin in android webview to scroll div and ajax load data.
    javascript:jquery.history.js使用方法
    【CSS核心概念】弹性盒子布局
    【Canvas学习笔记】基础篇(二)
    【JS核心概念】数据类型以及判断方法
    【问题记录】ElementUI上传组件使用beforeupload钩子校验失败时的问题处理
  • 原文地址:https://www.cnblogs.com/cgmcoding/p/13453175.html
Copyright © 2011-2022 走看看