机器学习算法—朴素贝叶斯(分类方法)超详细!!!

机器学习算法—朴素贝叶斯(分类方法)超详细!!!

相关概率论知识:

注:以下公式希望大家可以自己推导一下,有助于更好的理解我们的朴素贝叶斯算法,这一次的讲解,只是为了入门的宝贝可以更好的理解和 开始学会运用算法,后面的更新,将会是对于朴素贝叶斯算法的优化,基于这个例子的优化

1、相互独立事件:假设A、B相互独立,那么有:

**乘法公式:**P(AB)=P(A)*P(B)

2、表示事件B已经发生的前提下,事件A发生的概率,叫做事件B发生下事件A的条件概率。贝叶斯准则告诉我们,如果已知P(A|B),要求P(B|A),那么我们可以使用如下计算公式:

贝叶斯公式:

img

例子:

假设现分别有 A,B 两个容器,在容器 A 里分别有 7 个红球和 3 个白球,在容器 B 里有 1 个红球和 9 个白球,现已知从这两个容器里任意抽出了一个球,且是红球。

问这个红球是来自容器 A 的概率是多少?假设已经抽出红球为事件 B,从容器 A 里抽出球为事件 A,则有:P(B) = 8 / 20,P(A) = 1 / 2,P(B | A) = 7 / 10,按照公式,则有:P(A|B)=(7 / 10)*(1 / 2)/(8/20)=0.875。
原文链接:https://blog.csdn.net/hjimce/article/details/46054739

全概率公式

基本思想:

朴素贝叶斯为分类的一种算法,将各个样本在各个标签中的概率进行对比,并将样本归于概率最大的标签。(个人理解,可能不够完善,有误可评论或私发纠正,谢谢~~)

思路进阶:

一维:

我们现在有一个数据点X(点内有且只有一个特征),标签为C(C1,C2两个标签),现在需要对X进行分类。需要通过比较X为C1的概率P(C1|X)和X为C2的概率P(C2|X)

通过贝叶斯公式得出

img

img

两者比较可以发现最后是分子之间大小的比较

多维:

我们现在有一个数据点X(点内有N个特征),标签为C(C1,C2两个标签),现在需要对X进行分类。需要通过比较X为C1的概率P(C1|X)和X为C2的概率P(C2|X)

通过贝叶斯公式得出

img

img

由于朴素贝叶斯算法的思想是假设各个特征值相互独立,于是X中N个特征值X1 X2…Xn相互独立

思路进阶重点!!!

数据点X中的各个特征值在标签C中必须同时成立,于是使用乘法公式化简可得:

​ P(X|C1)*P(C1)=P(X1|C1)P(X2|C1)……P(Xn|C1)*P(C1)

​ P(X|C2)*P(C2)=P(X1|C2)P(X2|C2)……P(Xn|C2)*P(C2)

最后比较两者概率大小即可进行分类


多个数据点分类即循环该算法

多个标签即循环计算各个数据点在各个标签中的概率

多个特征值即循环计算每个数据点的每个特征值在每个标签中的概率


代码实战!!

我们借用《机器学习实战》的例题来运用一下我们的朴素贝叶斯算法。这次我们的目的是将文档进行自动分类。

准备数据(将单词转换成数字)

在这里插入图片描述

my dog has flea problems help please#复制放入新建的txt文件即可
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

定义一个load_data函数进行数据清洗:

def load_data(filename):
    data = []
    label = [0, 1, 0, 1, 0, 1]#文档对应的标签,1为负面言语,0为正常言语
    fr = open(filename)
    for line in fr.readlines():
        lineArr = line.split( )
        data.append(lineArr)
    return data,label

函数测试结果如图:
在这里插入图片描述
我们可以将每个句子看成一个数据点,组成句子的每个单词看成一个特征值,然后将其抽象化。于是我们需要一个特征集合,即所有可能出现的特征的集合。

相关知识点集合的特征:集合(set)是一个无序的不重复元素序列。可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。)

创建特征集合

def Create_Vocablist(data):
    vocabSet = set([]) #创建一个空集合
    for sentence in data:
        vocabSet = vocabSet | set(sentence) #利用两个集合的并集,将各个数据点(句子)中的各个出现过的特征值(单词)放入一个集合中
    return list(vocabSet)

函数测试结果如图:
在这里插入图片描述
我们标签库已经准备完毕,接下来就是定义一个函数****将我们每个数据点(句子)抽象化,即每个数据点拥有与特征库等长的特征向量,若存在该特征值,则为1,若不存在该特征值,则为0.(如果单词在词库中出现,则对应位置为1)

def transform_data_Vec(vocablist,sentence):
    vec = [0]*len(vocablist)
    for word in sentence:
        if word in vocablist:
            vec[vocablist.index(word)] = 1
        else:
            print("this word %s is not in my vocabulary!"%word)
    return vec

现在数据已经处理完成,并将每个数据点(句子)抽象化,接下来我们开始定义算法函数和训练算法

训练算法(最困难的地方)

公式回顾:

img

思路:

根据公式可以知道我们需要求出P(X|C1)、P(C1)、P(X|C2)、P(C2)。注:(C1、C2)分别代表着该例题的两个标签。

def train(sentence_Vec_Matrix,sentence_label):
    # sentence_Vec_Matrix 是每个数据点(句子)的特征向量矩阵
    # sentence_label 每个数据点(句子)的标签
    # 计算P(C1)
    num_sentence = len(sentence_Vec_Matrix) #数据点(句子)的总数量
    # 由于分类标签中,一类为0一类为1,所以求和所得数目即分类为1的数据点的总数
    P_C1 = sum(sentence_label) / float(num_sentence)
    P_C2 = 1-P_C1
    # 计算P(X|C1)
    num_words = len(sentence_Vec_Matrix[0])  # 特征库的长度,确保每个特征向量的长度一致
    p0Num = zeros(num_words)  # 记录每个特征值出现的次数
    p1Num = zeros(num_words)
    p0Denom = 0  # 所有出现过的特征值的总数
    p1Denom = 0
    for i in range(num_sentence):
        if sentence_label[i] == 1:
            #这里的求和原理和上面的P_C1中的sum(sentence_label)原理一致
            p1Num += sentence_Vec_Matrix[i]
            p1Denom += sum(sentence_Vec_Matrix[i])
        else:
            p0Num += sentence_Vec_Matrix[i]
            p0Denom += sum(sentence_Vec_Matrix[i])
    P_X_C1 = p1Num/p1Denom #P(X|C1)
    P_X_C2 = p0Num/p0Denom #P(X|C2)
    return P_C1,P_C2,P_X_C1,P_X_C2

def classify(vec,P_C1,P_C2,P_X_C1,P_X_C2):
    P_C1_X = sum(vec * P_X_C1 * P_C1)#因为矩阵相乘常熟为各个点分别相乘该常数,于是放入新的向量矩阵时,只需将该向量放入相乘即可,原理不变
    P_C2_X = sum(vec * P_X_C2 * P_C2)
    if P_C1_X > P_C2_X :
        return 1
    else:
        return 0

测试算法:

if __name__ == '__main__':
    data,label =load_data("text.txt")
    # print(data,label)
    vocabSet = Create_Vocablist(data)
    # print(vocabSet)
    sentence_vec = []
    for sentence in data:
        sentence_vec.append(transform_data_Vec(vocabSet,sentence))
    P_C1, P_C2, P_X_C1, P_X_C2 = train(array(sentence_vec),array(label))
    test_sentence = ['love', 'my', 'dalmation']
    print(test_sentence,classify(array(transform_data_Vec(vocabSet,test_sentence)),P_C1, P_C2, P_X_C1, P_X_C2))
    test_sentence = ['stupid', 'garbage']
    print(test_sentence, classify(array(transform_data_Vec(vocabSet, test_sentence)), P_C1, P_C2, P_X_C1, P_X_C2))

下图为测试结果
在这里插入图片描述

以上为朴素贝叶斯直接的学习与运用

猜你喜欢

转载自blog.csdn.net/komed/article/details/106577926