• 2022年11月26日NaiveBayes


    参考

    朴素贝叶斯算法的核心思想是通过考虑特征概率来预测分类,即对于给出的待分类样本,求解在此样本出现的条件下各个类别出现的概率,哪个最大,就认为此待分类样本属于哪个类别。

    ​ 我的理解是已知结果然后计算所有导致结果原因的概率,选择概率最大的作为他的原因。同样的思想可以迁移至分类,已知他的几个特征然后计算他是某个类别产生的。

    ​ 朴素贝叶斯算法也是对样本进行分类的方式,高斯朴素贝叶斯处理的是连续性随机变量的。多项式朴素贝叶斯和伯努利朴素贝叶斯处理的都是离散性随机变量。多项式朴素贝叶斯样本中可以重复,伯努利不能重复。

    ​ 处理概率为0可以利用拉普拉斯平滑

    ​ 我学习了算法思想没有很认真的学习代码实现。结尾贴代码。

    请添加图片描述


    参考

    请添加图片描述

    ​ 事件B1,B2可以看作“因”,事件A可以看作“果”,那么先验概率可以是求“肉加了醋后尝起来是酸的”概率( P ( A ∣ B 1 ) P(A|B1) P(A∣B1)),后验概率就是“肉尝起来是酸的,求是加了醋还是变质”概率。

    高斯朴素贝叶斯

    from sklearn import datasets
    iris = datasets.load_iris()
     
    from sklearn.naive_bayes import GaussianNB
    clf = GaussianNB()
    clf = clf.fit(iris.data, iris.target)
    y_pred=clf.predict(iris.data)
    print("高斯朴素贝叶斯,样本总数: %d 错误样本数 : %d" % (iris.data.shape[0],(iris.target != y_pred).sum()))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    多项分布朴素贝叶斯(MultinomialNB)

    from sklearn import datasets
    iris = datasets.load_iris()
     
    from sklearn.naive_bayes import MultinomialNB
    clf = MultinomialNB()
    clf = clf.fit(iris.data, iris.target)
    y_pred=clf.predict(iris.data)
    print("多项分布朴素贝叶斯,样本总数: %d 错误样本数 : %d" % (iris.data.shape[0],(iris.target != y_pred).sum()))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    伯努利分布朴素贝叶斯(BernoulliNB)

    from sklearn import datasets
    iris = datasets.load_iris()
     
    from sklearn.naive_bayes import BernoulliNB
    clf = BernoulliNB()
    clf = clf.fit(iris.data, iris.target)
    y_pred=clf.predict(iris.data)
    print("伯努利朴素贝叶斯,样本总数: %d 错误样本数 : %d" % (iris.data.shape[0],(iris.target != y_pred).sum()))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    from numpy import *
    import re
    
    def load_dataset():
        dataset = [['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']]
        class_vector = [0, 1, 0, 1, 0, 1]  # 1 is abusive, 0 not
        return dataset,class_vector
    dataset,class_vector=load_dataset()
    print('数据集为:\n',dataset)
    print('=='*30)
    print('数据标签为:\n',class_vector)
    print('=='*30)
    
    def create_vocab_list(dataset):
        """创建一个包含所有文档且不出现重复词的列表"""
        vocab_set = set([])  #create empty set
        for document in dataset:
            vocab_set = vocab_set | set(document) #set()去掉列表中的重复词
        return list(vocab_set)
    
    my_vacab_set=create_vocab_list(dataset)
    print(my_vacab_set)
    
    #词集模型
    """
    输入为词汇表和文档,检查文档中的单词是否在词汇表中
    采用词集模型:即对每条文档只记录某个词汇是否存在,而不记录出现的次数
    创建一个与词汇表长度一致的0向量,在当前样本中出现的词汇标记为1
    将一篇文档转换为词向量
    """
    def set_of_words_vector(vocab_list, input_set):
        return_vector = [0]*len(vocab_list)
        for word in input_set:
            if word in vocab_list:
                return_vector[vocab_list.index(word)] = 1
            else:
                print("the word: %s is not in my Vocabulary!" % word)
        return return_vector
    print(set_of_words_vector(my_vacab_set,dataset[0]))
    """
    朴素贝叶斯词袋模型
    如果一个词在文档中出现不止一次,这可能意味着包含该词是否出现中文档中所不能表达的某种信息
    """
    def bag_word_vector(vocab_list,input_set):
        return_vector=[0]*len(vocab_list)
        for word in input_set:
            if word in vocab_list:
                return_vector[vocab_list.index(word)]+=1
        return return_vector
    print(bag_word_vector(my_vacab_set,dataset[0]))
    """
    朴素贝叶斯分类器训练函数
    """
    def train_native_bayes(train_matrix,train_category):
        num_train_docs=len(train_matrix)
        num_words=len(train_matrix[0])
        p=sum(train_category)/float(num_train_docs)
        p_0_num=ones(num_words)
        p_1_num=ones(num_words)
        p_0_denom=2.0
        p_1_denom=2.0
        for i in range(num_train_docs):
            if train_category[i]==1:
                p_1_num+=train_matrix[i]
                p_1_denom+=sum(train_matrix[i])
            else:
                p_0_num+=train_matrix[i]
                p_0_denom+=sum(train_matrix[i])
        p_1_vector=log(p_1_num/p_1_denom)
        p_0_vector=log(p_0_num/p_0_denom)
        return p_0_vector,p_1_vector,p
    
    train_mat=[]
    for i in dataset:
        train_mat.append(set_of_words_vector(my_vacab_set,i))
    p_0_vector,p_1_vector,p=train_native_bayes(train_mat,class_vector)
    print(p)
    print(p_0_vector)
    
    def classify_native_bayes(need_to_classify_vector, p_0_vector, p_1_vector, p_class):
        p_1 = sum(need_to_classify_vector * p_1_vector) + log(p_class)    #element-wise mult
        p_0 = sum(need_to_classify_vector * p_0_vector) + log(1.0 - p_class)
        if p_1 > p_0:
            return 1
        else:
            return 0
    
    def testing_native_bayes():
        dataset,class_vector=load_dataset()
        my_vacab_set = create_vocab_list(dataset)
        my_vacab_set.sort()
        train_mat=[]
        for i in dataset:
            train_mat.append(set_of_words_vector(my_vacab_set, i))
        p_0_vector,p_1_vector,p = train_native_bayes(array(train_mat),array(class_vector))
        test_entry = ['love','my']
        this_doc = array(set_of_words_vector(my_vacab_set, test_entry))
        print(test_entry,'classified as: ',classify_native_bayes(this_doc,p_0_vector,p_1_vector,p))
        test_entry_1 = ['stupid','garbage']
        this_doc_1 = array(set_of_words_vector(my_vacab_set, test_entry_1))
        print(test_entry_1,'classified as: ',classify_native_bayes(this_doc_1,p_0_vector,p_1_vector,p))
    print(testing_native_bayes())
    
    """
    函数说明:接收一个大字符串并将其解析为字符串列表
    """
    def text_parse(big_string):
        # 将字符串转换为字符列表
        list_of_tokens = re.split(r"[0-9!@#$%^&*()?\n~]",big_string) # 将特殊符号作为切分标志进行字符串切分,即非字母、非数字
        return [tok.lower() for tok in list_of_tokens if len(tok) > 2] # 除了单个字母,例如大写的I,其它单词变成小写
    
    """
    函数说明:测试朴素贝叶斯分类器,使用朴素贝叶斯进行交叉验证
    """
    def spam_test():
        doc_list=[]
        class_vector=[]
        full_text=[]
        for i in range(1,26): # 遍历25个txt文件
            word_list=text_parse(open('native_bayes  email dataset/spam/%d.txt'%i,'r').read()) # 读取每个垃圾邮件,并字符串转换成字符串列表
            doc_list.append(word_list)
            full_text.extend(word_list)
            class_vector.append(1) # 标记垃圾邮件,1表示垃圾文件
            word_list=text_parse(open('native_bayes  email dataset/ham/%d.txt'%i,'r').read()) # 读取每个非垃圾邮件,并字符串转换成字符串列表
            doc_list.append(word_list)
            full_text.extend(word_list)
            class_vector.append(0) # 标记正常邮件,0表示正常文件
        vocab_list=create_vocab_list(doc_list) # 创建词汇表,不重复
        training_set=list(range(50))
        test_set=[] # 创建存储训练集的索引值的列表和测试集的索引值的列表
        for i in range(0,10): # 从50个邮件中,随机挑选出40个作为训练集,10个做测试集
            rand_index=int(random.uniform(0,len(training_set))) # 随机选取索索引值
            test_set.append(training_set[rand_index]) # 添加测试集的索引值
            del (training_set[rand_index]) # 在训练集列表中删除添加到测试集的索引值
        train_mat=[]
        train_class=[] # 创建训练集矩阵和训练集类别标签系向量
        for doc_index in training_set: # 遍历训练集
            train_mat.append(set_of_words_vector(vocab_list,doc_list[doc_index])) # 将生成的词集模型添加到训练矩阵中
            train_class.append(class_vector[doc_index]) # 将类别添加到训练集类别标签系向量中
        p_0_vector,p_1_vector,p=train_native_bayes(array(train_mat),array(train_class)) # 训练朴素贝叶斯模型
        error_count=0 # 错误分类计数
        for doc_index in test_set: # 遍历测试集
            word_vector=set_of_words_vector(vocab_list,doc_list[doc_index]) # 测试集的词集模型
            if classify_native_bayes(array(word_vector),p_0_vector,p_1_vector,p)!=class_vector[doc_index]: # 如果分类错误
                error_count+=1 # 错误计数加1
                print('classify error:',doc_list[doc_index])
        print('the error rate is:',float(error_count)/len(test_set))
    
    spam_test()
    
    def one_cross_validate(train_set,train_class,test_set,test_class):
        #训练模型
        p_0_vector,p_1_vector,p_c_1 = train_native_bayes(array(train_set),array(train_class))
        error_count = 0
        #验证集进行测试
        for i in range(10):
            c = classify_native_bayes(array(test_set[i]),p_0_vector,p_1_vector,p_c_1)
            if c != test_class[i]:
                error_count += 1
        return error_count/10
    
    def K_Cross_Validate(train_mat,train_class_vector):  #K折交叉验证 5
        rand_index = list(range(50))
        random.shuffle(rand_index)
        error_radio = 0.0
        for i in range(5):  #5次
            index = rand_index #随机索引
            #选取训练集、验证集索引
            train_set = []
            train_cls = []
            test_set = []
            test_cls = []
            test_set_index = set(rand_index[10*i:10*i+10])  # 测试集10
            train_set_index = set(index)-test_set_index  # 验证集
            #选取训练集、验证集数据
            for idx in train_set_index:
                train_set.append(train_mat[idx])
                train_cls.append(train_class_vector[idx])
            for idx in test_set_index:
                test_set.append(train_mat[idx])
                test_cls.append(train_class_vector[idx])
            print('第%d个子集的误差率为:'%(i+1),one_cross_validate(train_set,train_cls,test_set,test_cls))
            error_radio += one_cross_validate(train_set,train_cls,test_set,test_cls)
        return error_radio/5
    
    def create_dataset():
        data_set_list=[]  #全部数据集
        class_vector = []    #标签值
        #获取数据
        spam_path = "native_bayes  email dataset/spam/{}.txt"  #获取文件路径
        ham_path = "native_bayes  email dataset/ham/{}.txt"
        for i in range(1, 26):  # 两个路径各有25个文件
            document_data_1 = open(spam_path.format(i), 'r').read()
            # 使用正则进行分割,除了空格、还有标点都可以用于分割
            word_vector = text_parse(document_data_1) # \W*表示匹配多个非字母、数字、下划线的字符
            data_set_list.append([item for item in word_vector if len(item) > 0])
            class_vector.append(1)
            document_data_2 = open(ham_path.format(i), 'r').read()
            # 使用正则进行分割,除了空格、还有标点都可以用于分割
            word_vector_2 = text_parse(document_data_2)  # \W*表示匹配多个非字母、数字、下划线的字符
            data_set_list.append([item for item in word_vector_2 if len(item) > 0])
            class_vector.append(0)
        return data_set_list, class_vector
    data_set_list, class_vector=create_dataset()
    vocab_list = create_vocab_list(data_set_list)
    trainMulList = []
    for doc in data_set_list:
        trainMulList.append(set_of_words_vector(vocab_list,doc))
    print('=='*30)
    print('5折交叉验证的错误率为:\n',K_Cross_Validate(trainMulList,class_vector))
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217

    代码来源及详解

    机器学习中要学习的概率论知识

    [对于朴素贝叶斯讲的很好](

  • 相关阅读:
    Ansible 自动化运维工具的使用
    新版软考高项试题分析精选(一)
    AutoDL使用手册
    Aspose.Words使用教程之表的合并与拆分
    Swift加载Lottie
    centos7下mongodb安装及开启副本
    【教程】MySQL数据库学习笔记(五)——约束(持续更新)
    PositiveSSL通配符SSL证书能保护几个域名
    H5自定义属性
    react-native android图标尺寸规范
  • 原文地址:https://blog.csdn.net/qq_61735602/article/details/128058730