朴素贝叶斯

朴素贝叶斯:基于概率论的分类方法

  • 优点:在数据较少的情况下仍然有效,可以处理多类别问题。

  • 缺点:对于输入数据的准备方式较为敏感。

  • 适用数据类型:标称型数据。

  • 贝叶斯决策理论
    核心思想:选择具有最高概率的决策

    • 特征独立——变为朴素贝叶斯
  • 条件概率

    • 计算公式
      • 贝叶斯准则
    • 进行分类
  • 一般流程

    • 收集数据:可以使用任何方法。本章使用RSS源。
    • 准备数据:需要数值型或者布尔型数据。
    • 分析数据:有大量特征时,绘制特征作用不大,此时使用直方图效果更好。
    • 训练算法:计算不同的独立特征的条件概率。
    • 测试算法:计算错误率。
    • 使用算法:一个常见的朴素贝叶斯应用是文档分类。可以在任意的分类场景中使用朴素贝叶斯分类器,不一定非要是文本。
  • 假设

    • 特征独立
    • 每个特征同等重要
  • 手写重要代码
import numpy as np
def creatVocabList(dataSet):
    """
    创建词汇表
    params  dataSet:二维列表
    returns list(vocabset):词汇表
    """
    vocabset = set([])
    for document in dataSet:
        vocabset = vocabset | set(document)
    return list(vocabset)

def setOfWords2Vec(vocabList, inputSet):
    """
    文本转变为词向量,词集模型
    params vocabList:词汇表
    params inputSet:需要转化的单维列表
    returns returnVec:转化为数字的单维列表
    """
    returnVec = [0]*len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] = 1
        else: 
            print("the word: %s is not in my Vocabulary!" % word)
    return returnVec

def bagOfWords2VecMN(vocabList, inputSet):
    """
    文本转变为词向量,词袋模型
    params vocabList:词汇表
    params inputSet:需要转化的单维列表
    returns returnVec:转化为数字的单维列表
    """
    returnVec = [0]*len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] += 1
    return returnVec

def trainNB0(trainMat, trainCategory):
    """
    计算概率
    params trainMat:样本或者转化过的字典(二维列表)
    parmas trainCategory:trainMat所对应的标签
    returns p0Vect:在p0下的各个词的概率
    returns p1Vect:在p1下的各个词的概率
    """
    # trainMatrix=[]
    # for postinDoc in postingList:
    #     trainMatrix.append(setOfWords2Vec(myVocalList, postinDoc))  # 使用词集模型计算
    
    trainMatrix = trainMat
    numTrainDocs = len(trainMatrix)
    numWords = len(trainMatrix[0])
    pAbusive = sum(trainCategory) / float(numTrainDocs)
    p0Num = np.ones(numWords)
    p1Num = np.ones(numWords)  #change to np.ones()
    p0Denom = 2.0
    p1Denom = 2.0  #change to 2.0
    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 = np.log(p1Num / p1Denom)  #change to np.log()
    p0Vect = np.log(p0Num / p0Denom)  #change to np.log()
    return p0Vect, p1Vect, pAbusive

def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
    """
    计算朴素贝叶斯分类
    params vec2Classify:转化为词向量的需要测试的单维列表
    params p0Vec: trainNB0()的p0Vect输出
    params p1Vec: trainNB0()的p1Vect输出
    params pClass1: trainNB0()的pClass1输出
    returns 1/0: 分类标签
    """
    p1 = sum(vec2Classify * p1Vec) + np.log(pClass1)    #element-wise mult
    p0 = sum(vec2Classify * p0Vec) + np.log(1.0 - pClass1)
    if p1 > p0:
        return 1
    else:
        return 0

def testingNB(testEntry, listOPosts, listClasses):
    """
    测试函数
    params testEntry: 测试的一维数据列表
    params listOPosts: 数据集二维列表
    params listClasses: 数据集标签
    returns classified: 测试数据集的分类
    """
    myVocabList = creatVocabList(listOPosts)
    trainMat = []
    for postinDoc in listOPosts:
        trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
        # trainMat.append(bagOfWords2VecMN(myVocabList, postinDoc))
    p0V, p1V, pAb = trainNB0(np.array(trainMat), np.array(listClasses))
    # testEntry = ['love', 'my', 'dalmation']
    thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))
    classified = classifyNB(thisDoc, p0V, p1V, pAb)
    return classified
  • sklearn实现算法
    GaussianNB,MultinomialNB和BernoulliNB。其中GaussianNB就是先验为高斯分布的朴素贝叶斯,MultinomialNB就是先验为多项式分布的朴素贝叶斯,而BernoulliNB就是先验为伯努利分布的朴素贝叶斯。
    • sklearn.naive_bayes模块实现朴素贝叶斯模型
      • sklearn.naive_bayes.MultinomialNB
      class sklearn.naive_bayes.MultinomialNB(alpha=1.0, fit_prior=True, class_prior=None)
      
      • 参数

        • params alpha
          浮点型可选参数,默认为1.0,其实就是添加拉普拉斯平滑,即为上述公式中的λ ,如果这个参数设置为0,就是不添加平滑;
        • params fit_prior
          布尔型可选参数,默认为True。布尔参数fit_prior表示是否要考虑先验概率,如果是false,则所有的样本类别输出都有相同的类别先验概率。否则可以自己用第三个参数class_prior输入先验概率,或者不输入第三个参数class_prior让MultinomialNB自己从训练集样本来计算先验概率,此时的先验概率为P(Y=Ck)=mk/m。其中m为训练集样本总数量,mk为输出为第k类别的训练集样本数。
        • params class_prior
          可选参数,默认为None。
        fit_prior class_prior 最终先验概率
        False 填或不填没有意义 P(Y = Ck) = 1 / k
        True 不填 P(Y = Ck) = mk / m
        True P(Y = Ck) = class_prior
      • 方法

        • methods fit(self, X, y, sample_weight=None)
        • methods get_params(self, deep=True)
        • methods partial_fit(self, X, y, classes=None, sample_weight=None)
        • methods predict(self, X)
        • methods predict_log_proba(self, X)
        • methods predict_proba(self, X)
        • methods score(self, X, y, sample_weight=None)
        • methods set_params(self,**params)
      def TextClassifier(train_feature_list, test_feature_list, train_class_list, test_class_list):
      """
      params train_feature_list - 训练集向量化的特征文本
      params test_feature_list - 测试集向量化的特征文本
      params train_class_list - 训练集分类标签
      params test_class_list - 测试集分类标签
      returns test_accuracy - 分类器精度
      """
          classifier = MultinomialNB().fit(train_feature_list, train_class_list)
          test_accuracy = classifier.score(test_feature_list, test_class_list)
          return test_accuracy
      
      

参考

[1]作者:Jack-Cui
来源:CSDN
原文:https://blog.csdn.net/c406495762/article/details/77500679
版权声明:本文为博主原创文章,转载请附上博文链接!
[2]机器学习实战
[3]统计学习方法

你可能感兴趣的:(朴素贝叶斯)