精华内容
下载资源
问答
  • 机器学习 --- 朴素贝叶斯分类器 python

    千次阅读 多人点赞 2020-10-22 21:07:42
    本实训项目的主要内容是基于 Python 语言搭建朴素贝叶斯分类器,并使用sklearn 实现新闻文本进行主题分类的功能。 朴素贝叶斯分类算法流程 import numpy as np class NaiveBayesClassifier(ob

    简介
    朴素贝叶斯分类算法是基于贝叶斯理论和特征条件独立假设的分类算法。对于给定的训练集,首先基于特征条件独立假设学习数据的概率分布。然后基于此模型,对于给定的特征数据x,利用贝叶斯定理计算出标签y。朴素贝叶斯分类算法实现简单,预测效率很高,是一种常用的分类算法。
    本实训项目的主要内容是基于 Python 语言搭建朴素贝叶斯分类器,并使用sklearn 实现新闻文本进行主题分类的功能。

    朴素贝叶斯分类算法流程

    import numpy as np
    
    
    class NaiveBayesClassifier(object):
        def __init__(self):
            '''
            self.label_prob表示每种类别在数据中出现的概率
            例如,{0:0.333, 1:0.667}表示数据中类别0出现的概率为0.333,类别1的概率为0.667
            '''
            self.label_prob = {}
            '''
            self.condition_prob表示每种类别确定的条件下各个特征出现的概率
            例如训练数据集中的特征为 [[2, 1, 1],
                                  [1, 2, 2],
                                  [2, 2, 2],
                                  [2, 1, 2],
                                  [1, 2, 3]]
            标签为[1, 0, 1, 0, 1]
            那么当标签为0时第0列的值为1的概率为0.5,值为2的概率为0.5;
            当标签为0时第1列的值为1的概率为0.5,值为2的概率为0.5;
            当标签为0时第2列的值为1的概率为0,值为2的概率为1,值为3的概率为0;
            当标签为1时第0列的值为1的概率为0.333,值为2的概率为0.666;
            当标签为1时第1列的值为1的概率为0.333,值为2的概率为0.666;
            当标签为1时第2列的值为1的概率为0.333,值为2的概率为0.333,值为3的概率为0.333;
            因此self.label_prob的值如下:     
            {
                0:{
                    0:{
                        1:0.5
                        2:0.5
                    }
                    1:{
                        1:0.5
                        2:0.5
                    }
                    2:{
                        1:0
                        2:1
                        3:0
                    }
                }
                1:
                {
                    0:{
                        1:0.333
                        2:0.666
                    }
                    1:{
                        1:0.333
                        2:0.666
                    }
                    2:{
                        1:0.333
                        2:0.333
                        3:0.333
                    }
                }
            }
            '''
            self.condition_prob = {}
        def fit(self, feature, label):
            '''
            对模型进行训练,需要将各种概率分别保存在self.label_prob和self.condition_prob中
            :param feature: 训练数据集所有特征组成的ndarray
            :param label:训练数据集中所有标签组成的ndarray
            :return: 无返回
            '''
    
    
            #********* Begin *********#
            row_num = len(feature)
            col_num = len(feature[0])
            for c in label:
                if c in self.label_prob:
                    self.label_prob[c] += 1
                else:
                    self.label_prob[c] = 1
    
            for key in self.label_prob.keys():
                # 计算每种类别在数据集中出现的概率
                self.label_prob[key] /= row_num
                # 构建self.condition_prob中的key
                self.condition_prob[key] = {}
                for i in range(col_num):
                    self.condition_prob[key][i] = {}
                    for k in np.unique(feature[:, i], axis=0):
                        self.condition_prob[key][i][k] = 0
    
            for i in range(len(feature)):
                for j in range(len(feature[i])):
                    if feature[i][j] in self.condition_prob[label[i]]:
                        self.condition_prob[label[i]][j][feature[i][j]] += 1
                    else:
                        self.condition_prob[label[i]][j][feature[i][j]] = 1
    
            for label_key in self.condition_prob.keys():
                for k in self.condition_prob[label_key].keys():
                    total = 0
                    for v in self.condition_prob[label_key][k].values():
                        total += v
                    for kk in self.condition_prob[label_key][k].keys():
                        #计算每种类别确定的条件下各个特征出现的概率
                        self.condition_prob[label_key][k][kk] /= total
            #********* End *********#
    
    
        def predict(self, feature):
            '''
            对数据进行预测,返回预测结果
            :param feature:测试数据集所有特征组成的ndarray
            :return:
            '''
            # ********* Begin *********#
            result = []
            #对每条测试数据都进行预测
            for i, f in enumerate(feature):
                #可能的类别的概率
                prob = np.zeros(len(self.label_prob.keys()))
                ii = 0
                for label, label_prob in self.label_prob.items():
                    #计算概率
                    prob[ii] = label_prob
                    for j in range(len(feature[0])):
                        prob[ii] *= self.condition_prob[label][j][f[j]]
                    ii += 1
                #取概率最大的类别作为结果
                result.append(list(self.label_prob.keys())[np.argmax(prob)])
            return np.array(result)
            #********* End *********#
    
    

    拉普拉斯平滑

    import numpy as np
    
    class NaiveBayesClassifier(object):
        def __init__(self):
            '''
            self.label_prob表示每种类别在数据中出现的概率
            例如,{0:0.333, 1:0.667}表示数据中类别0出现的概率为0.333,类别1的概率为0.667
            '''
            self.label_prob = {}
            '''
            self.condition_prob表示每种类别确定的条件下各个特征出现的概率
            例如训练数据集中的特征为 [[2, 1, 1],
                                  [1, 2, 2],
                                  [2, 2, 2],
                                  [2, 1, 2],
                                  [1, 2, 3]]
            标签为[1, 0, 1, 0, 1]
            那么当标签为0时第0列的值为1的概率为0.5,值为2的概率为0.5;
            当标签为0时第1列的值为1的概率为0.5,值为2的概率为0.5;
            当标签为0时第2列的值为1的概率为0,值为2的概率为1,值为3的概率为0;
            当标签为1时第0列的值为1的概率为0.333,值为2的概率为0.666;
            当标签为1时第1列的值为1的概率为0.333,值为2的概率为0.666;
            当标签为1时第2列的值为1的概率为0.333,值为2的概率为0.333,值为3的概率为0.333;
            因此self.label_prob的值如下:     
            {
                0:{
                    0:{
                        1:0.5
                        2:0.5
                    }
                    1:{
                        1:0.5
                        2:0.5
                    }
                    2:{
                        1:0
                        2:1
                        3:0
                    }
                }
                1:
                {
                    0:{
                        1:0.333
                        2:0.666
                    }
                    1:{
                        1:0.333
                        2:0.666
                    }
                    2:{
                        1:0.333
                        2:0.333
                        3:0.333
                    }
                }
            }
            '''
            self.condition_prob = {}
    
        def fit(self, feature, label):
            '''
            对模型进行训练,需要将各种概率分别保存在self.label_prob和self.condition_prob中
            :param feature: 训练数据集所有特征组成的ndarray
            :param label:训练数据集中所有标签组成的ndarray
            :return: 无返回
            '''
    
            #********* Begin *********#
            row_num = len(feature)
            col_num = len(feature[0])
            unique_label_count = len(set(label))
    
            for c in label:
                if c in self.label_prob:
                    self.label_prob[c] += 1
                else:
                    self.label_prob[c] = 1
    
            for key in self.label_prob.keys():
                # 计算每种类别在数据集中出现的概率,拉普拉斯平滑
                self.label_prob[key] += 1
                self.label_prob[key] /= (unique_label_count+row_num)
    
                # 构建self.condition_prob中的key
                self.condition_prob[key] = {}
                for i in range(col_num):
                    self.condition_prob[key][i] = {}
                    for k in np.unique(feature[:, i], axis=0):
                        self.condition_prob[key][i][k] = 1
    
    
            for i in range(len(feature)):
                for j in range(len(feature[i])):
                    if feature[i][j] in self.condition_prob[label[i]]:
                        self.condition_prob[label[i]][j][feature[i][j]] += 1
    
            for label_key in self.condition_prob.keys():
                for k in self.condition_prob[label_key].keys():
                    #拉普拉斯平滑
                    total = len(self.condition_prob[label_key].keys())
                    for v in self.condition_prob[label_key][k].values():
                        total += v
                    for kk in self.condition_prob[label_key][k].keys():
                        # 计算每种类别确定的条件下各个特征出现的概率
                        self.condition_prob[label_key][k][kk] /= total
            #********* End *********#
    
    
        def predict(self, feature):
            '''
            对数据进行预测,返回预测结果
            :param feature:测试数据集所有特征组成的ndarray
            :return:
            '''
    
            result = []
            # 对每条测试数据都进行预测
            for i, f in enumerate(feature):
                # 可能的类别的概率
                prob = np.zeros(len(self.label_prob.keys()))
                ii = 0
                for label, label_prob in self.label_prob.items():
                    # 计算概率
                    prob[ii] = label_prob
                    for j in range(len(feature[0])):
                        prob[ii] *= self.condition_prob[label][j][f[j]]
                    ii += 1
                # 取概率最大的类别作为结果
                result.append(list(self.label_prob.keys())[np.argmax(prob)])
            return np.array(result)
    
    

    新闻文本主题分类

    from sklearn.feature_extraction.text import CountVectorizer  # 从sklearn.feature_extraction.text里导入文本特征向量化模块
    from sklearn.naive_bayes import MultinomialNB
    from sklearn.feature_extraction.text import TfidfTransformer
    
    
    def news_predict(train_sample, train_label, test_sample):
        '''
        训练模型并进行预测,返回预测结果
        :param train_sample:原始训练集中的新闻文本,类型为ndarray
        :param train_label:训练集中新闻文本对应的主题标签,类型为ndarray
        :test_sample:原始测试集中的新闻文本,类型为ndarray
        '''
    
        # ********* Begin *********#
        vec = CountVectorizer()
        train_sample = vec.fit_transform(train_sample)
        test_sample = vec.transform(test_sample)
    
        tfidf = TfidfTransformer()
    
        train_sample = tfidf.fit_transform(train_sample)
        test_sample = tfidf.transform(test_sample)
    
        mnb = MultinomialNB(alpha=0.01)  # 使用默认配置初始化朴素贝叶斯
        mnb.fit(train_sample, train_label)  # 利用训练数据对模型参数进行估计
        predict = mnb.predict(test_sample)  # 对参数进行预测
        return predict
        # ********* End *********#
    

    感谢大家的支持!!!!!记得点赞!!!

    展开全文
  • 朴素贝叶斯分类器训练函数: 伪代码: 计算每个类别中的文档数目 对每篇训练文档: 对每个类别: 如果词条出现在文档中 —>增加该词条的计数值 增加所有词条的计数值 对每个类别: 对每个词条 : 将该...

    本文所有代码存储在bayes.py文件中,以便于代码测试和程序运行。


    from numpy import *

     

    def loadDataSet():

        """

    功能:词表到向量的转换函数

    输出:1.进行此条切分后的文档集合。2.类别标签的集合,这些文本类别由人工标注,这些标注信息用于训练程序以便自动检测侮辱性留言。

        """

        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]

        return postingList,classVec

     

    def createVocabList(dataSet):

        """

        功能:创建一个包含在所有文档中出现的不重复词的列表

        """

        vocabSet = set([])  #创建一个空集,将每篇文档返回的新词添加到该集合中

        for document in dataSet:

            vocabSet = vocabSet | set(document) #输入词条列表返回不重复的词表.操作符|用于求两个集合的并集。

        return list(vocabSet)

     

    def setOfWords2Vec(vocabList, inputSet):

        """

        输入:词汇表及某个文档

        输出:文档向量,向量的每一个元素为10,分别表示词汇表中的单词在输入文档中是否出现。

        """

        returnVec = [0]*len(vocabList)  #创建一个和词汇表等长的向量,并将其元素都设为0

        for word in inputSet:  #遍历文档中的所有词,如果出现词汇表中的词则将输出文档向量中的对应值设为1.

            if word in vocabList:

                returnVec[vocabList.index(word)] = 1

            else: print("the word: %s is not in my Vocabulary!" % word)

    return returnVec

    代码测试:

    import bayes

    listOPosts,listClass =  bayes.loadDataSet()

    myVocabList = bayes.createVocabList(listOPosts)

    print(myVocabList)

    print(bayes.setOfWords2Vec(myVocabList,listOPosts[0]))

    print(bayes.setOfWords2Vec(myVocabList,listOPosts[3])

    结果:

    ['to', 'problems', 'maybe', 'ate', 'my', 'love', 'dog', 'take', 'so', 'I', 'quit', 'food', 'park', 'licks', 'help', 'worthless', 'stupid', 'flea', 'how', 'buying', 'has', 'him', 'posting', 'garbage', 'mr', 'dalmation', 'is', 'cute', 'stop', 'steak', 'please', 'not']

    检查上述词表,就会发现这里不会出现重复的单词。

    [0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0]

    myVocabList中的单词出现在postingList第一列的则为1未出现的则为零。

    [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0]

    myVocabList中的单词出现在postingList第四列的则为1未出现的则为零。

    通过检验,可以发现函数运行正确。

    朴素贝叶斯分类器训练函数:

    伪代码:

    计算每个类别中的文档数目

    对每篇训练文档:

    对每个类别:

    如果词条出现在文档中—>增加该词条的计数值

    增加所有词条的计数值

    对每个类别:

    对每个词条:

    将该词条数目除以总词条数目得到条件概率

    返回每个类别的条件概率

     

    def trainNB0(trainMatrix,trainCategory):

        """

        输入:1.文档矩阵;2.每篇文档类别标签所构成的向量

        输出:两个向量和一个概率

        """

        numTrainDocs = len(trainMatrix)

        numWords = len(trainMatrix[0])

        pAbusive = sum(trainCategory)/float(numTrainDocs)

        p0Num = ones(numWords); p1Num = ones(numWords)

    p0Denom = 2.0; p1Denom = 2.0

    #利用贝叶斯分类器时,要计算多个概率的乘积以获得文档属于某个类别的概率,即计算p(|1)p(w1|1)p(w2|1)。如果其中一个概率值为0,那么最后的乘积也为0。为讲点这种影响,可以将所有词的出现数初始化为1,并将分母初始化为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)

    p0Vect = log(p0Num/p0Denom)

    #另一个遇到的问题是下溢出,这是由于太多很小的数相乘造成的。当计算乘积:p(w0|ci)p(w1| ci)p(w2| ci)…p(wN|ci)时,由于大部分因子都非常小,所以程序会下溢出或者得不到正确的答案。所以此处对该数取对数。再代数中有ln(a*b)=ln(a)+ln(b)于是通过求对数可以避免下溢出或者浮点数舍入导致的错误。同时采用对数进行处理不会有任何损失。(他们在相同区域内同时增加或者减少,并且在相同点上取到极值。他们的取值虽然不同但是不影响最终结果。)

    return p0Vect,p1Vect,pAbusive

    代码测试:

    from numpy import*

    import bayes

    listOPosts,listClasses =  bayes.loadDataSet()

    myVocabList = bayes.createVocabList(listOPosts)

    print(myVocabList)

    trainMat = []

    for postinDoc in listOPosts:

        trainMat.append(bayes.setOfWords2Vec(myVocabList,postinDoc))

    p0V,p1V,pAb = bayes.trainNB0(trainMat,listClasses)

    print(pAb)

    print(p0V)

    print(p1V)

    结果1

    ['dog', 'has', 'quit', 'dalmation', 'to', 'licks', 'stupid', 'stop', 'my', 'love', 'park', 'how', 'ate', 'I', 'cute', 'steak', 'not', 'take', 'flea', 'help', 'food', 'garbage', 'mr', 'is', 'please', 'maybe', 'worthless', 'him', 'posting', 'so', 'problems', 'buying']

    0.5

    我们发现文档属于类别1的概率为0.5,该值是正确的。

    下面是给定文档类别条件下词汇表中单词出现的概率。由于我们对数值进行了初始化所以下值与原数值不同。想要看原数值,应该把p0Denom设置为2p1Denom设置为2,取对数操作去除,得到结果2

    [-2.56494936 -2.56494936 -3.25809654 -2.56494936 -2.56494936 -2.56494936

     -3.25809654 -2.56494936 -1.87180218 -2.56494936 -3.25809654 -2.56494936

     -2.56494936 -2.56494936 -2.56494936 -2.56494936 -3.25809654 -3.25809654

     -2.56494936 -2.56494936 -3.25809654 -3.25809654 -2.56494936 -2.56494936

     -2.56494936 -3.25809654 -3.25809654 -2.15948425 -3.25809654 -2.56494936

     -2.56494936 -3.25809654]

    [-1.94591015 -3.04452244 -2.35137526 -3.04452244 -2.35137526 -3.04452244

     -1.65822808 -2.35137526 -3.04452244 -3.04452244 -2.35137526 -3.04452244

     -3.04452244 -3.04452244 -3.04452244 -3.04452244 -2.35137526 -2.35137526

     -3.04452244 -3.04452244 -2.35137526 -2.35137526 -3.04452244 -3.04452244

     -3.04452244 -2.35137526 -1.94591015 -2.35137526 -2.35137526 -3.04452244

     -3.04452244 -2.35137526]

    结果2

    ['worthless', 'maybe', 'dalmation', 'steak', 'buying', 'help', 'park', 'my', 'please', 'posting', 'quit', 'I', 'garbage', 'dog', 'mr', 'not', 'licks', 'food', 'so', 'is', 'him', 'flea', 'ate', 'how', 'love', 'stop', 'take', 'cute', 'has', 'stupid', 'problems', 'to']

    0.5

    词汇表中第一个单词是worthless,其在类别0文档中出现0次,而在类别1文档中出现2次。对应的条件概率分别为0.00.10526316

    stupid在类别1中的概率最大,大小为0.15789474,这意味着stupid是最能代表类别1的单词。

    [ 0.          0.          0.04166667  0.04166667  0.          0.04166667

      0.          0.125       0.04166667  0.          0.          0.04166667

      0.          0.04166667  0.04166667  0.          0.04166667  0.

      0.04166667  0.04166667  0.08333333  0.04166667  0.04166667  0.04166667

      0.04166667  0.04166667  0.          0.04166667  0.04166667  0.

      0.04166667  0.04166667]

    [ 0.10526316  0.05263158  0.          0.          0.05263158  0.

      0.05263158  0.          0.          0.05263158  0.05263158  0.

      0.05263158  0.10526316  0.          0.05263158  0.          0.05263158

      0.          0.          0.05263158  0.          0.          0.          0.

      0.05263158  0.05263158  0.          0.          0.15789474  0.

      0.05263158]

    def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):

        p1 = sum(vec2Classify * p1Vec) + log(pClass1)    

    p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)

    #使用numpy的数组来计算两个函数相乘的结果。这里的相乘是指对应元素相乘,即先对两个向量中的第一个元素相乘,然后将第二个元素相乘以此类推。接下来将词汇表中对应的所有词的对应值相加,然后将该值加到类别的对数概率上。最后,比较类别的概率返回大概率对应的类别标签。

        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))

    结果:

    ['love', 'my', 'dalmation'] classified as:  0

    ['stupid', 'garbage'] classified as:  1

    None

    多项式模型实现:考虑词在文档中出现的次数。

    词集模型set-of-words:将每个词出现与否作为一个特征,

    词袋模型(bag-of-words model):一个词在文档中不止出现一次,这可能意味着该词是否出现在文档中所不能表达的某种信息。

    在词袋中每个单词可以出现多次,而在词集中,每个单词只能出现一次。为适应词袋模型需要对函数setOfWords2Vec()稍加修改,修改后的函数为bagOfWords2Vec()

    def bagOfWords2VecMN(vocabList, inputSet):

        returnVec = [0]*len(vocabList)

        for word in inputSet:

            if word in vocabList:

                returnVec[vocabList.index(word)] += 1

        return returnVec

    切分文本测试:

    import re

    mySent = "This book is the best book on Python or M.L. I have ever laid eyes upon."

    print(mySent.split())

    regEx = re.compile("\\W*")

    listOfTokens = regEx.split(mySent)

    print(listOfTokens)

    结果:

    ['This', 'book', 'is', 'the', 'best', 'book', 'on', 'Python', 'or', 'M.L.', 'I', 'have', 'ever', 'laid', 'eyes', 'upon.']

    ['This', 'book', 'is', 'the', 'best', 'book', 'on', 'Python', 'or', 'M', 'L', 'I', 'have', 'ever', 'laid', 'eyes', 'upon', '']

    提取email进行测试:

    emailText = open("email/ham/6.txt").read()

    regEx = re.compile("\\W*")

    listOfTokens = regEx.split(emailText)

    print(listOfTokens)

    结果:

    ['Hello', 'Since', 'you', 'are', 'an', 'owner', 'of', 'at', 'least', 'one', 'Google', 'Groups', 'group', 'that', 'uses', 'the', 'customized', 'welcome', 'message', 'pages', 'or', 'files', 'we', 'are', 'writing', 'to', 'inform', 'you', 'that', 'we', 'will', 'no', 'longer', 'be', 'supporting', 'these', 'features', 'starting', 'February', '2011', 'We', 'made', 'this', 'decision', 'so', 'that', 'we', 'can', 'focus', 'on', 'improving', 'the', 'core', 'functionalities', 'of', 'Google', 'Groups', 'mailing', 'lists', 'and', 'forum', 'discussions', 'Instead', 'of', 'these', 'features', 'we', 'encourage', 'you', 'to', 'use', 'products', 'that', 'are', 'designed', 'specifically', 'for', 'file', 'storage', 'and', 'page', 'creation', 'such', 'as', 'Google', 'Docs', 'and', 'Google', 'Sites', 'For', 'example', 'you', 'can', 'easily', 'create', 'your', 'pages', 'on', 'Google', 'Sites', 'and', 'share', 'the', 'site', 'http', 'www', 'google', 'com', 'support', 'sites', 'bin', 'answer', 'py', 'hl', 'en', 'answer', '174623', 'with', 'the', 'members', 'of', 'your', 'group', 'You', 'can', 'also', 'store', 'your', 'files', 'on', 'the', 'site', 'by', 'attaching', 'files', 'to', 'pages', 'http', 'www', 'google', 'com', 'support', 'sites', 'bin', 'answer', 'py', 'hl', 'en', 'answer', '90563', 'on', 'the', 'site', 'If', 'youe', 'just', 'looking', 'for', 'a', 'place', 'to', 'upload', 'your', 'files', 'so', 'that', 'your', 'group', 'members', 'can', 'download', 'them', 'we', 'suggest', 'you', 'try', 'Google', 'Docs', 'You', 'can', 'upload', 'files', 'http', 'docs', 'google', 'com', 'support', 'bin', 'answer', 'py', 'hl', 'en', 'answer', '50092', 'and', 'share', 'access', 'with', 'either', 'a', 'group', 'http', 'docs', 'google', 'com', 'support', 'bin', 'answer', 'py', 'hl', 'en', 'answer', '66343', 'or', 'an', 'individual', 'http', 'docs', 'google', 'com', 'support', 'bin', 'answer', 'py', 'hl', 'en', 'answer', '86152', 'assigning', 'either', 'edit', 'or', 'download', 'only', 'access', 'to', 'the', 'files', 'you', 'have', 'received', 'this', 'mandatory', 'email', 'service', 'announcement', 'to', 'update', 'you', 'about', 'important', 'changes', 'to', 'Google', 'Groups', ''


    def textParse(bigString):

    “””

    输入:一个大字符串并将其解析为字符串列表

    功能:去掉少于两个字符的字符串,并将所有字符串转换为小写。

    ”””

        import re

        listOfTokens = re.split(r'\W*', bigString)

        return [tok.lower() for tok in listOfTokens if len(tok) > 2]

     

    def spamTest():

    “””

    功能:将导入的文件解析成词列表。本次测试共有50个邮件,其中10封被选为测试集。这种随机选择数据的一部分作为训练集,而其他部分作为测试集的过程被称为留存交叉验证。

    ”””

        docList = []

        classList = []

        fullText = []

        for i in range(1, 26):

            wordList = textParse(open('email/spam/%d.txt' % i).read())

            docList.append(wordList)

            fullText.extend(wordList)

            classList.append(1)

            wordList = textParse(open('email/ham/%d.txt' % i ).read())

            docList.append(wordList)

            fullText.extend(wordList)

            classList.append(0)

        vocabList = createVocabList(docList)

        trainingSet = list(range(50))

        testSet = []

        for i in range(10):

            randIndex = int(random.uniform(0, len(trainingSet)))

            testSet.append(trainingSet[randIndex])

            del (trainingSet[randIndex])

        trainMat = []

        trainClasses = []

        for docIndex in trainingSet:

            trainMat.append(bagOfWords2VecMN(vocabList, docList[docIndex]))

            trainClasses.append(classList[docIndex])

        p0V, p1V, pSpam = trainNB0(array(trainMat), array(trainClasses))

        errorCount = 0

        for docIndex in testSet:

            wordVector = bagOfWords2VecMN(vocabList, docList[docIndex])

            if classifyNB(array(wordVector), p0V, p1V, pSpam) != classList[docIndex]:

                errorCount += 1

                print("classification error", docList[docIndex])

    print('the error rate is: ', float(errorCount) / len(testSet))

    函数测试:

    print(bayes.spamTest())
    函数会给出总的错误的百分比,在分类错误时会输出错分文档的词表。

    为了很好的估计错误概率,将上述过程成重复多次取平均值。

    结果1

    classification error ['home', 'based', 'business', 'opportunity', 'knocking', 'your', 'door', 'don', 'rude', 'and', 'let', 'this', 'chance', 'you', 'can', 'earn', 'great', 'income', 'and', 'find', 'your', 'financial', 'life', 'transformed', 'learn', 'more', 'here', 'your', 'success', 'work', 'from', 'home', 'finder', 'experts']

    classification error ['yeah', 'ready', 'may', 'not', 'here', 'because', 'jar', 'jar', 'has', 'plane', 'tickets', 'germany', 'for']

    the error rate is:  0.2

    None

    结果2

    the error rate is:  0.0

    结果3

    classification error ['scifinance', 'now', 'automatically', 'generates', 'gpu', 'enabled', 'pricing', 'risk', 'model', 'source', 'code', 'that', 'runs', '300x', 'faster', 'than', 'serial', 'code', 'using', 'new', 'nvidia', 'fermi', 'class', 'tesla', 'series', 'gpu', 'scifinance', 'derivatives', 'pricing', 'and', 'risk', 'model', 'development', 'tool', 'that', 'automatically', 'generates', 'and', 'gpu', 'enabled', 'source', 'code', 'from', 'concise', 'high', 'level', 'model', 'specifications', 'parallel', 'computing', 'cuda', 'programming', 'expertise', 'required', 'scifinance', 'automatic', 'gpu', 'enabled', 'monte', 'carlo', 'pricing', 'model', 'source', 'code', 'generation', 'capabilities', 'have', 'been', 'significantly', 'extended', 'the', 'latest', 'release', 'this', 'includes']

    classification error ['benoit', 'mandelbrot', '1924', '2010', 'benoit', 'mandelbrot', '1924', '2010', 'wilmott', 'team', 'benoit', 'mandelbrot', 'the', 'mathematician', 'the', 'father', 'fractal', 'mathematics', 'and', 'advocate', 'more', 'sophisticated', 'modelling', 'quantitative', 'finance', 'died', '14th', 'october', '2010', 'aged', 'wilmott', 'magazine', 'has', 'often', 'featured', 'mandelbrot', 'his', 'ideas', 'and', 'the', 'work', 'others', 'inspired', 'his', 'fundamental', 'insights', 'you', 'must', 'logged', 'view', 'these', 'articles', 'from', 'past', 'issues', 'wilmott', 'magazine']

    the error rate is:  0.2

    None

    结果4

    the error rate is:  0.0

    None

    结果5

    classification error ['yeah', 'ready', 'may', 'not', 'here', 'because', 'jar', 'jar', 'has', 'plane', 'tickets', 'germany', 'for']

    the error rate is:  0.1

    None

    结果6

    the error rate is:  0.0

    结果7

    classification error ['home', 'based', 'business', 'opportunity', 'knocking', 'your', 'door', 'don', 'rude', 'and', 'let', 'this', 'chance', 'you', 'can', 'earn', 'great', 'income', 'and', 'find', 'your', 'financial', 'life', 'transformed', 'learn', 'more', 'here', 'your', 'success', 'work', 'from', 'home', 'finder', 'experts']

    the error rate is:  0.1

    结果8

    classification error ['home', 'based', 'business', 'opportunity', 'knocking', 'your', 'door', 'don', 'rude', 'and', 'let', 'this', 'chance', 'you', 'can', 'earn', 'great', 'income', 'and', 'find', 'your', 'financial', 'life', 'transformed', 'learn', 'more', 'here', 'your', 'success', 'work', 'from', 'home', 'finder', 'experts']

    the error rate is:  0.1

    结果9

    the error rate is:  0.0

    结果10

    classification error ['benoit', 'mandelbrot', '1924', '2010', 'benoit', 'mandelbrot', '1924', '2010', 'wilmott', 'team', 'benoit', 'mandelbrot', 'the', 'mathematician', 'the', 'father', 'fractal', 'mathematics', 'and', 'advocate', 'more', 'sophisticated', 'modelling', 'quantitative', 'finance', 'died', '14th', 'october', '2010', 'aged', 'wilmott', 'magazine', 'has', 'often', 'featured', 'mandelbrot', 'his', 'ideas', 'and', 'the', 'work', 'others', 'inspired', 'his', 'fundamental', 'insights', 'you', 'must', 'logged', 'view', 'these', 'articles', 'from', 'past', 'issues', 'wilmott', 'magazine']

    the error rate is:  0.1

    None

    对上述错误率进行平均得出错误率为8%。由于把重要文件划分为垃圾文件所要承担的风险更大,是人们比起收到垃圾邮件更加不希望看到的情况,所以本文中把垃圾文件错分成非垃圾文件的错误在实际生活中是可以接受的。

    展开全文
  • 主要为大家详细介绍了python实现朴素贝叶斯分类器,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 主要介绍了Python实现的朴素贝叶斯分类器,结合具体实例形式分析了基于Python实现的朴素贝叶斯分类器相关定义与使用技巧,需要的朋友可以参考下
  • 贝叶斯公式/朴素贝叶斯分类器python自实现

    万次阅读 多人点赞 2018-11-20 21:26:44
    通过两个实例理解贝叶斯的思想与流程,然后梳理了朴素贝叶斯分类器的算法流程,最后从零开始实现了朴素分类器的算法。 文章目录1.起源、提出与贝叶斯公式2.以实例感受贝叶斯决策:癌症病人计算 问题3.以实例感受...

    本文从贝叶斯与频率概率的对比入手理解贝叶斯决策的思维方式。通过两个实例理解贝叶斯的思想与流程,然后梳理了朴素贝叶斯分类器的算法流程,最后从零开始实现了朴素分类器的算法。

    1.起源、提出与贝叶斯公式

    贝叶斯派别主要是与古典统计学相比较区分的。

    古典统计学基于大数定理,将一件事件经过大量重复实验得到的频率作为事件发生的概率,如常说的掷一枚硬币,正面朝上的概率为0.5。但,如果事先知道硬币的密度分布并不均匀,那此时的概率是不是就不为0.5呢?这种不同于“非黑即白”的思考方式,就是贝叶斯式的思考方式。

    贝叶斯除了提出上述思考方式之外,还特别提出了举世闻名的贝叶斯定理。贝叶斯公式:

    P(BiA)=P(Bi)P(ABi)j=1nP(Bj)P(ABj) P(B_i|A) = \frac{P(B_i)P(A|B_i)}{\sum_{j=1}^nP(B_j)P(A|B_j)}

    这里通过全概率公式,我们可以将上式等同于

    P(BA)=P(B)P(AB)P(A)=P(B)P(AB)P(A) P(B|A) = \frac{P(B)P(A|B)}{P(A)} = P(B)\frac{P(A|B)}{P(A)}

    右边的分式中,分子的P(A)称为先验概率,是B事件未发生前,对A事件概率的判断;P(A|B)即是在B事件发生之后,对A事件发生的后验概率。这整个分式我们也称之为‘’可能性函数(Likelyhood)‘’,这是一个调整因子,对A事件未发生之前B的概率进行调整,以得到A事件发生的前提下B事件发生的后验概率P(B|A)。

    以一句话与一张图概括:贝叶斯定理是一种在已知其他概率的情况下求概率的方法。

    在这里插入图片描述

    2.以实例感受贝叶斯决策:癌症病人计算 问题

    有一家医院为了研究癌症的诊断,对一大批人作了一次普查,给每人打了试验针,然后进行统计,得到如下统计数字:

    1. 这批人中,每1000人有5个癌症病人;
    2. 这批人中,每100个正常人有1人对试验的反应为阳性
    3. 这批人中,每100个癌症病人有95入对试验的反应为阳性。

    通过普查统计,该医院可开展癌症诊断。现在某人试验结果为阳性,诊断结果是什么?

    在这里插入图片描述
    (全是公式实在不好打,就用自己笔记代替啦)

    上述例子是基于最小错误率贝叶斯决策,即哪类的概率大判断为哪类,也是我们常见的分类决策方法。但是将正常人错判为癌症病人,与将癌症病人错判为正常人的损失是不一样的。将正常人错判为癌症病人,会给他带来短期的精神负担,造成一定的损失,这个损失比较小。如果把癌症病人错判为正常人,致使患者失去挽救的机会,这个损失就大了。这两种不同的错判所造成损失的程度是有显著差别的。

    所以,在决策时还要考虑到各种错判所造成的不同损失,由此提出了最小风险贝叶斯决策

    我们将IijI_{ij}记为将j类误判为i类所造成的损失。此处类别为2,如将样本x判为癌症病人c1c_1造成损失的数学期望为:

    R1=I11P(C1X)+I12P(C2X)R_1=I_{11}P(C_1|X)+I_{12}P(C_2|X)​

    同理,将样本x判为癌症病人c2c_2造成损失的数学期望为

    R2=I21P(C1X)+I22P(C2X)R_2=I_{21}P(C_1|X)+I_{22}P(C_2|X)

    选择最小风险作为决策准则,若R1<R2R_1<R_2,则样本XϵR1\epsilon R_1,否则XϵR2\epsilon R_2

    3.以实例感受贝叶斯修正先验概率:狼来了

    给出一些合理解释:

    事件A表示:“小孩说谎”;事件B表示:“小孩可信”。

    村民起初对这个小孩的信任度为0.8,即P(B)=0.8。

    我们认为可信的孩子说谎的可能性为0.1。即P(A|B)=0.1。

    不可信的孩子说谎的可能性为0.5,即P(A|^B)=0.5(用 ^B表示B的对立事件)。

    求小孩第一次说谎、第二次说谎后,村民对这个小孩的信任度从P(B)=0.8会发生什么变化?

    在这里插入图片描述

    由此我们可以得到贝叶斯决策另一个道理,**贝叶斯决策会不断用后验概率,逐渐修正先验概率。**投射到现实生活,我们也可以理解为当对某件事进行判断决策时,关于此事得到的信息越多,对此事的决策越准,而绝非yes/no的五五开决策。

    还是狼来的例子,如果这个孩子要改邪归正,他需要多少次才能把信任度提高到80%?

    如果要把信任度提高,那接下来就需要通过几次 不说谎 的经历来修正村民的观念,那可信度的计算,要记得将P(A|B)换成P((fei)A|B),(A上方的横线打不出来…),就是可信的孩子不说谎的可能性为1-P(A|B)=1-0.1,同样,不可信的孩子不说谎的概率为1-0.5

    此时,我们就要用代码来实现而不是手算啦。代码如下:

    def calculateTrustDegree(pb):
      PB_A = float((1-PA_B)*pb)/((1-PA_B)*pb+(1-PA_Bf)*(1-pb))
      return PB_A
    PA_B = 0.1
    PA_Bf = 0.5
    pb = 0.138
    N = 0
    while(pb <=0.8):
        pb = calculateTrustDegree(pb)
        N+=1
    print("He need {0} times with honest saying,villager can trust him again.".format(N))
    
    # N = 6
    # He need 6 times with honest saying,villager can trust him again.
    

    4.朴素贝叶斯分类器

    贝叶斯分类算法是一大类分类算法的总称。

    贝叶斯分类算法以样本可能属于某类的概率来作为分类依据

    朴素贝叶斯分类算法是贝叶斯分类算法中最简单的一种,采用了**“属性条件独立性假设”**:对已知类别,假设所有属性互相独立,也就是在概率的计算时,可以将一个类别的每个属性直接相乘。这在概率论中应该学过,两个事件独立时,两个事件同时发生的概率等于两个事件分别发生的乘积。

    给定一个属性值,其属于某个类的概率叫做条件概率。对于一个给定的类值,将每个属性的条件概率相乘,便得到一个数据样本属于某个类的概率。

    我们可以通过计算样本归属于每个类的概率,然后选择具有最高概率的类来做预测。

    我们以鸢尾花分类实例来过算法流程,并不适用sklearn库自实现朴素贝叶斯分类器。

    实例数据集介绍:鸢尾花数据集包含4维的特征,共三类150个样本,每类均有50个样本。

    算法流程概括如下:

    1. 计算样本属于某类的先验概率,属于A类的概率为A\frac{属于A类的样本数}{所有样本数},以此类推
    2. 计算类条件概率,离散值通过类别数量比值,此数据集的属性特征为连续值所以通过 概率密度函数 来计算。首先计算在一个属性的前提下,该样本属于某类的概率;相乘合并所有属性的概率,即为某个数据样本属于某类的类条件概率
      • 计算每个特征属于每类的条件概率
        • 概率密度函数实现
        • 计算每个属性的均值和方差
        • 按类别提取属性特征,这里会得到 类别数目*属性数目 组 (均值,方差)
      • 按类别将每个属性的条件概率相乘,如下所示
        • 判断为A类的概率:p(A|特征1)*p(A|特征2)*p(A|特征3)*p(A|特征4)…
        • 判断为B类的概率:p(B|特征1)*p(B|特征2)*p(B|特征3)*p(B|特征4)…
        • 判断为C类的概率:p(C|特征1)*p(C|特征2)*p(C|特征3)*p(C|特征4)…
    3. 先验概率*类条件概率,回顾一下贝叶斯公式,P(BiA)=P(Bi)P(ABi)j=1nP(Bj)P(ABj) P(B_i|A) = \frac{P(B_i)P(A|B_i)}{\sum_{j=1}^nP(B_j)P(A|B_j)}。由于样本确定时,贝叶斯公式的分母都是相同的。所以判断样本属于哪类只需要比较分子部分:先验概率*类条件概率,最终属于哪类的概率最大,则判别为哪类,此处为最小错误率贝叶斯分类,若采用最小风险需要加上判断为每个类别的风险损失值。

    5.代码实现

    1.数据集载入,划分训练集与测试集

    data_df = pd.read_csv('IrisData.csv')
    def splitData(data_list,ratio):
      train_size = int(len(data_list)*ratio)
      random.shuffle(data_list)
      train_set = data_list[:train_size]
      test_set = data_list[train_size:]
      return train_set,test_set
    
    data_list = np.array(data_df).tolist()
    trainset,testset = splitData(data_list,ratio = 0.7)
    print('Split {0} samples into {1} train and {2} test samples '.format(len(data_df), len(trainset), len(testset)))
    
    # Split 150 samples into 105 train and 45 test samples 
    

    2.计算先验概率

    此时需要先知道数据集中属于各类别的样本分别有多少。我们通过一个函数实现按类别划分数据。

    两个返回值分别为划分好的数据字典,以及划分好的数据集中每个类别的样本数

    def seprateByClass(dataset):
      seprate_dict = {}
      info_dict = {}
      for vector in dataset:
          if vector[-1] not in seprate_dict:
              seprate_dict[vector[-1]] = []
              info_dict[vector[-1]] = 0
          seprate_dict[vector[-1]].append(vector)
          info_dict[vector[-1]] +=1
      return seprate_dict,info_dict
    
    train_separated,train_info = seprateByClass(trainset)
    
    # train_info:
    # {'Setosa': 41, 'Versicolour': 33, 'Virginica': 31}
    

    计算属于每个类别的先验概率

    def calulateClassPriorProb(dataset,dataset_info):
      dataset_prior_prob = {}
      sample_sum = len(dataset)
      for class_value, sample_nums in dataset_info.items():
          dataset_prior_prob[class_value] = sample_nums/float(sample_sum)
      return dataset_prior_prob
    
    prior_prob = calulateClassPriorProb(trainset,train_info)
    
    #{'Setosa': 0.3904761904761905,
    # 'Versicolour': 0.3142857142857143,
    # 'Virginica': 0.29523809523809524}
    

    3.计算类条件概率

    3.1 首先计算每个特征属于每类的条件概率,前面说过这里我们使用概率密度函数来计算

    概率密度函数实现:

    方差公式:$ var = \frac{\sum(x-avg)^{2}}{n-1},概率密度函数: p(xi|c) = \frac{1}{\sqrt{2\pi}\sigma_{c,i}}exp(-\frac{(xi-mean_{c,i}){2}}{2\sigma_{c,i}{2}})$ , σ\sigma是标准差(方差开方)

    # 均值
    def mean(list):
      list = [float(x) for x in list] #字符串转数字
      return sum(list)/float(len(list))
    # 方差
    def var(list):
      list = [float(x) for x in list]
      avg = mean(list)
      var = sum([math.pow((x-avg),2) for x in list])/float(len(list)-1)
      return var
    # 概率密度函数
    def calculateProb(x,mean,var):
        exponent = math.exp(math.pow((x-mean),2)/(-2*var))
        p = (1/math.sqrt(2*math.pi*var))*exponent
        return p
    

    每个属性特征属于每类的条件概率是个组合。举例来说,这里有3个类和4个数值属性,然后我们需要每一个属性(4)和类(3)的组合的类条件概率。

    为了得到这12个概率密度函数,那我们需要提前知道这12个属性分别的均值和方差,才可以带入到上述概率密度函数中计算。

    计算每个属性的均值和方差:

    def summarizeAttribute(dataset):
        dataset = np.delete(dataset,-1,axis = 1) # delete label
        summaries = [(mean(attr),var(attr)) for attr in zip(*dataset)]
        return summaries
    
    summary = summarizeAttribute(trainset)
    #[(5.758095238095239, 0.7345732600732595),
    # (3.065714285714285, 0.18592857142857133),
    # (3.5533333333333323, 3.2627051282051274),
    # (1.1142857142857148, 0.6014285714285714)]
    

    按类别提取属性特征,这里会得到 类别数目*属性数目 组 (均值,方差)

    def summarizeByClass(dataset):
      dataset_separated,dataset_info = seprateByClass(dataset)
      summarize_by_class = {}
      for classValue, vector in dataset_separated.items():
          summarize_by_class[classValue] = summarizeAttribute(vector)
      return summarize_by_class
    
    train_Summary_by_class = summarizeByClass(trainset)
    #{'Setosa': [(4.982926829268291, 0.12445121951219511),
    #  (3.3975609756097565, 0.1417439024390244),
    #  (1.4707317073170731, 0.03412195121951221),
    #  (0.24390243902439032, 0.012024390243902434)],
    # 'Versicolour': [(5.933333333333334, 0.2766666666666667),
    #  (2.7909090909090906, 0.08960227272727272),
    #  (4.254545454545454, 0.23755681818181815),
    #  (1.33030303030303, 0.03905303030303031)],
    # 'Virginica': [(6.596774193548387, 0.5036559139784946),
    #  (2.9193548387096775, 0.10427956989247314),
    #  (5.5612903225806445, 0.37711827956989247),
    #  (2.0354838709677416, 0.06369892473118278)]}
    
    

    按类别将每个属性的条件概率相乘。

    我们前面已经将训练数据集按类别分好,这里就可以实现,输入的测试数据依据每类的每个属性(就那个类别数*属性数的字典)计算属于某类的类条件概率。

    def calculateClassProb(input_data,train_Summary_by_class):
      prob = {}
      for class_value, summary in train_Summary_by_class.items():
          prob[class_value] = 1
          for i in range(len(summary)):
              mean,var = summary[i]
              x = input_data[i]
              p = calculateProb(x,mean,var)
          prob[class_value] *=p
      return prob
    
    input_vector = testset[1]
    input_data = input_vector[:-1]
    train_Summary_by_class = summarizeByClass(trainset)
    class_prob = calculateClassProb(input_data,train_Summary_by_class)
    
    #{'Setosa': 3.3579279836005993,
    # 'Versicolour': 1.5896628317396685e-07,
    # 'Virginica': 5.176617264913899e-12}
    

    4.先验概率*类条件概率

    朴素贝叶斯分类器

    def bayesianPredictOneSample(input_data):
      prior_prob = calulateClassPriorProb(trainset,train_info)
      train_Summary_by_class = summarizeByClass(trainset)
      classprob_dict = calculateClassProb(input_data,train_Summary_by_class)
      result = {}
      for class_value,class_prob in classprob_dict.items():
          p = class_prob*prior_prob[class_value]
          result[class_value] = p
      return max(result,key=result.get)
    

    终于把分类器写完啦,接下来就让我们看看测试数据的结果!

    单个样本测试:

    input_vector = testset[1]
    input_data = input_vector[:-1]
    result = bayesianPredictOneSample(input_data)
    print("the sameple is predicted to class: {0}.".format(result))
    
    # the sameple is predicted to class: Versicolour.
    

    看看分类准确率

    def calculateAccByBeyesian(dataset):
      correct = 0
      for vector in dataset:
          input_data = vector[:-1]
          label = vector[-1]
          result = bayesianPredictOneSample(input_data)
          if result == label:
              correct+=1
      return correct/len(dataset)
    
    acc = calculateAccByBeyesian(testset)
    # 0.9333333333333333
    

    全部代码及数据集已上传至github,也可访问我的博客,第一次写博客不足之处欢迎大家提出交流学习。最近会持续性进行输出的~而且每一次输出都是一次新的输入

    6. 参考文献

    机器学习之用Python从零实现贝叶斯分类器

    知乎-你对贝叶斯统计都有怎样的理解?

    贝叶斯公式由浅入深大讲解—AI基础算法入门

    先验乘后验贝叶斯定理

    展开全文
  • 主要介绍了Python实现朴素贝叶斯分类器的方法,详细分析了朴素贝叶斯分类器的概念、原理、定义、使用方法及相关操作注意事项,需要的朋友可以参考下
  • 朴素贝叶斯分类器python版)

    热门讨论 2014-08-04 18:06:25
    python写的简单的朴素贝叶斯分类器,一共有两个主文件,nbayes1和nbayes1_run1还有两个训练数据文件,望大家多多指教。
  • 朴素贝叶斯分类算法Python代码

    千次阅读 2018-04-16 19:55:47
    贝叶斯分类器就是求P(C|F1F2...Fn) = P(F1F2...Fn|C)P(C) / P(F1F2...Fn) 最大值,由于 P(F1F2...Fn) ... 朴素贝叶斯分类器则是更进一步,假设所有特征都彼此独立,因此P(F1F2...Fn|C)P(C)= P(F1|C)P(F2|C) ... P...

    贝叶斯分类器就是求P(C|F1F2...Fn) = P(F1F2...Fn|C)P(C) / P(F1F2...Fn) 最大值,由于 P(F1F2...Fn) 对于所有的类别都是相同的,可以省略,问题就变成了求 P(F1F2...Fn|C)P(C) 的最大值。 

    朴素贝叶斯分类器则是更进一步,假设所有特征都彼此独立,因此P(F1F2...Fn|C)P(C)= P(F1|C)P(F2|C) ... P(Fn|C)P(C)

    朴素贝叶斯算法进行分类,是根据朴素贝叶斯公式分别计算测试数据为类别0,类别1,类别2...的概率,假如计算得出类别i概率高,就可以说测试数据属于类别i的概率最大,把测试数据归到类别i,达到分类的目的。

    封装在类里,方便以后使用。

    import numpy
    class Bayes: 
        def __init__(self):      
            self.length=-1   #用来判断是否训练过    
            self.labelcount=dict()  #字典类型{label:频数...}  
            self.vectorcount=dict() #字典类型{label:vector...}
        #训练数据
        #dataset是二维列表,格式[[],[]...],每一行是属于某一个label,labels是一维列表
        def fit(self,dataset:list,labels:list):       
            if(len(dataset)!=len(labels)):            
                raise ValueError("输入数组与类别数组长度不同")       
            #训练数据特征值长度       
            self.length=len(dataset[0])
            labelsnum=len(labels)
            #set去掉重复label
            norlabels=set(labels)        
            for item in norlabels:           
                thislabel=item
                #计算当前类别占总数的比例
                labelcount[]=labels.count(thislabel)/labelsnum
                #zip()整合dataset和labels
            for vector,label in zip(dataset,labels):
                if(label not in vectorcount):                    
                    self.vectorcount[label]=[]
                    #往当前类别下添加向量
                self.vectorcount[label].append(vector)
            print("训练结束")
            return self
        #测试
        def btest(self,testdata,labelsset):        
            if(self.length==-1):            
                raise ValueError("未进行训练")        
            lbdict=dict()        
            for thislb in labelsset:            
                p=1            
                alllabel=self.labelcount[thislb]  #当前label占总label的比例          
                allvector=self.vectorcount[thislb]        #属于当前label下的所有向量    
                vnum=len(allvector)            
                allvector=numpy.array(allvector).T           
                 for index in range(0,len(testdata)):     #一个一个计算测试数据的概率           
                    vector=list(allvector[index])                
                    p*=vector.count(testdata[index])/vnum               
                lbdict[thislb]=p*alllabel
            thislabel=sorted(lbdict,key=lamba x:lbdict[x],reverse=True)[0]#按照lbdict[x]排降序
            return thislabel

    展开全文
  • 朴素贝叶斯分类器假设每个属性相互独立,. 对于所有类别来说,相同,因此朴素贝叶斯分类器对的类标判别.  令表示训练集中第类样本组成的集合,表示类别数,则类先验概率(拉普拉斯平滑) 对于离散属性,令表示...
  • 朴素贝叶斯分类(Python)

    万次阅读 2019-03-12 16:58:47
    一、贝叶斯公式及分类 贝叶斯公式是在条件概率和全概率公式的基础上得来的,详细请参考: https://blog.csdn.net/Hearthougan/article/details/75174210 贝叶斯公式p(yi|X) = p(X|yi) p(yi) / p(X) = p(yi) p(x1|...
  • 朴素贝叶斯分类文本 python实现

    千次阅读 2017-04-27 22:10:05
    朴素贝叶斯(naive bayes)模型主要用于文本分类,比如要将邮件分类为正常邮件和带侮辱性词汇邮件 对于一封邮件来说其特征可以表示为该邮件中单词出现的情况。 比如我们有一个5000个词的词典表,那么邮件的特征可...
  • 一个实现朴素贝叶斯分类器简单的Python
  • 参考链接: Python朴素贝叶斯分类器 本文实例讲述了Python实现朴素贝叶斯分类器的方法。分享给大家供大家参考,具体如下: 贝叶斯定理 贝叶斯定理是通过对观测值概率分布的主观判断(即先验概率)进行修正的定理,...
  • 贝叶斯分类 两组文本(一组属于a类,一组属于b类) NBC(贝叶斯)通过计算样本在各个分类中的概率来进行分类 1.相关模块导入 import numpy as np import re import feedparser as fp import operator as op 2....
  • 徒手实现一个贝叶斯分类器引子代码新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右...
  • Python实现朴素贝叶斯分类器
  • 贝叶斯分类器(贝叶斯决策论,极大似然估计,朴素贝叶斯分类器,半朴素贝叶斯分类器,贝叶斯网)学习笔记 一、条件概率,全概率公式,贝叶斯公式 !]...
  • 朴素贝叶斯分类算法的python实现,有需要的同学可以自取。如果积分涨得过高请联系我,我随时可以下调
  • 贝叶斯公式中,P(A)称为"先验概率"(Prior probability),即在B事件发生之前,对A事件概率的一个判断。 P(A|B)称为"后验概率"(Posterior probability),即在B事件发生之后,对A事件概率的重新评估。 举个简单...
  • 试编程实现拉普拉斯修正的朴素贝叶斯分类器和半朴素贝叶斯分类器中的AODE分类器,并以⻄瓜数据集3.0为训练集,对P.151“测1”样本进⾏判别。 数据集 编号 色泽 根蒂 敲声 纹理 脐部 触感 密度 含糖率 好瓜 0 1 青绿 ...
  • 朴素贝叶斯分类器 朴素贝叶斯分类器是一个以贝叶斯定理为基础的多分类的分类器。对于给定数据,首先基于特征的条件独立性假设,学习输入输出的联合概率分布, 然后基于此模型,对给定的输入x,利用贝叶斯定理求出后...
  • 朴素贝叶斯分类器python实现

    千次阅读 2019-04-24 18:41:57
    贝叶斯公式概率论的一些基本知识: 条件概率:P(A|B)P(A|B) 联合概率:P(AB)=P(B)∗P(A|B)=P(A)∗P(B|A)P(AB)=P(B)*P(A|B)=P(A)*P(B|A) 从而导出贝叶斯式:P(A|B)=P(AB)|P(B)=P(A)∗P(B|A)/P(B)P(A|B)=P(AB)|P...
  • 朴素贝叶斯分类器

    2021-01-06 21:45:00
    朴素贝叶斯分类器是基于贝叶斯公式的概率分类器,是建立在独立性假设基础上的。   贝叶斯公式可以把求解后验概率的问题转化为求解先验概率的问题,一般情况下后验概率问题 难以求解。例如;一封邮件是垃圾邮件的...
  • 朴素贝叶斯分类器Python实现)

    千次阅读 2017-07-15 22:51:10
    基本思想:朴素贝叶斯分类器,在当给出了特征向量w情况下,分类为ci的条件概率p(ci | w)。 利用贝叶斯公式:p(ci | w) = p(w | ci) * p(ci) / p(w),可以完成转化,观察公式可以发现分母p(w)都一样,所以只要比较...
  • 朴素贝叶斯NaiveBayes以及python实现 https://blog.csdn.net/CarryLvan/article/details/109236906 上面的博客有代码实现,但要实现测试集上每一个样本的预测时出错,这篇代码要求在测试集上要用的样本要在训练集上...
  • 朴素贝叶斯和半朴素贝叶斯(AODE)分类器Python实现

    千次阅读 多人点赞 2019-12-28 21:30:41
    由于老师说可以调用现成的相关机器学习的库,所以我一开始在做朴素贝叶斯分类器的时候,直接调用了sklearn库,很方便,可是问题来了,在做AODE半朴素贝叶斯分类器的时候,并没有找到集成好的方法。所以就想着自己把...
  • 贝叶斯分类器是以贝叶斯原理为基础的分类器的总称,是一种生成式模型,朴素贝叶斯分类器是其中最简单的一种。要高明白贝叶斯分类器的原理,首先得明白一些基本概念。 预备知识 基本概念 先验概率:根据统计/经验...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,623
精华内容 3,849
关键字:

朴素贝叶斯分类器python

python 订阅