机器学习4-朴素贝叶斯

标签: 机器学习-模型原理  机器学习  朴素贝叶斯

1.朴素贝叶斯模型

在这里插入图片描述
在这里插入图片描述

2.朴素贝叶斯代码实现

import numpy as np


# 定义加载数据的函数
def loaddata():
    X = np.array([[1, 'S'], [1, 'M'], [1, 'M'], [1, 'S'],
                  [1, 'S'], [2, 'S'], [2, 'M'], [2, 'M'],
                  [2, 'L'], [2, 'L'], [3, 'L'], [3, 'M'],
                  [3, 'M'], [3, 'L'], [3, 'L']])
    y = np.array([-1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1])
    return X, y


# 训练、计算各个概率值
def Train(trainset, train_labels):
    # 数据量
    m = trainset.shape[0]
    # 特征数
    n = trainset.shape[1]
    # 先验概率,key是类别值,value是类别的概率值
    prior_probability = {}
    # 条件概率,key的构造:类别,特征,特征值
    conditional_probability = {}

    # 类别的可能取值
    labels = set(train_labels)
    # 计算先验概率,此时没有计算总数据量m
    for label in labels:
        prior_probability[label] = len(train_labels[train_labels == label])
    print('prior_probabilit =', prior_probability)

    # 计算条件概率
    for i in range(m):
        for j in range(n):
            # key的构造:类别,特征,特征值
            key = str(y[i]) + ',' + str(j) + ',' + str(trainset[i][j])
            if key in conditional_probability:
                conditional_probability[key] += 1
            else:
                conditional_probability[key] = 1
    print('conditional_probability = ', conditional_probability)

    # 因字典在循环时不能改变,故定义新字典来保存值
    conditional_probability_final = {}
    for key in conditional_probability:
        # 取出当前的类别
        label = key.split(',')[0]
        conditional_probability_final[key] = conditional_probability[key] / prior_probability[int(label)]

    # 最终先验概率(除以总数据量m)
    for label in labels:
        prior_probability[label] = prior_probability[label] / m

    return prior_probability, conditional_probability_final, labels


# 定义预测函数
def predict(data):
    result = {}
    # 循环标签
    for label in train_labels_set:
        temp = 1.0
        for j in range(len(data)):
            key = str(label) + ',' + str(j) + ',' + str(data[j])
            # 条件概率连乘
            temp = temp * conditional_probability[key]
        # 在乘上先验概率
        result[label] = temp * prior_probability[label]
    print('result =', result)
    # 排序返回标签值
    return sorted(result.items(), key=lambda x: x[1], reverse=True)[0][0]


if __name__ == '__main__':
    X, y = loaddata()
    prior_probability, conditional_probability, train_labels_set = Train(X, y)
    print('conditional_probability = ', conditional_probability)

    # 预测
    y_hat = predict([2, 'S'])
    print('y_hat =', y_hat)
prior_probabilit = {1: 9, -1: 6}
conditional_probability =  {'-1,0,1': 3, '-1,1,S': 3, '-1,1,M': 2, '1,0,1': 2, '1,1,M': 4, '1,1,S': 1, '-1,0,2': 2, '1,0,2': 3, '1,1,L': 4, '1,0,3': 4, '-1,0,3': 1, '-1,1,L': 1}
conditional_probability =  {'-1,0,1': 0.5, '-1,1,S': 0.5, '-1,1,M': 0.3333333333333333, '1,0,1': 0.2222222222222222, '1,1,M': 0.4444444444444444, '1,1,S': 0.1111111111111111, '-1,0,2': 0.3333333333333333, '1,0,2': 0.3333333333333333, '1,1,L': 0.4444444444444444, '1,0,3': 0.4444444444444444, '-1,0,3': 0.16666666666666666, '-1,1,L': 0.16666666666666666}
result = {1: 0.02222222222222222, -1: 0.06666666666666667}
y_hat = -1

4.拉普拉斯修正及其代码实现

在这里插入图片描述

import numpy as np

# 定义加载数据的函数
def loaddata():
    X = np.array([[1, 'S'], [1, 'M'], [1, 'M'], [1, 'S'],
                  [1, 'S'], [2, 'S'], [2, 'M'], [2, 'M'],
                  [2, 'L'], [2, 'L'], [3, 'L'], [3, 'M'],
                  [3, 'M'], [3, 'L'], [3, 'L']])
    y = np.array([-1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1])
    return X, y


# 训练、计算各个概率值
def Train(trainset, train_labels):
    # 数据量
    m = trainset.shape[0]
    # 特征数
    n = trainset.shape[1]
    # 先验概率,key是类别值,value是类别的概率值
    prior_probability = {}
    # 条件概率,key的构造:类别,特征,特征值
    conditional_probability = {}

    # 类别的可能取值
    labels = set(train_labels)
    # 计算先验概率,此时没有计算总数据量m
    for label in labels:
        prior_probability[label] = len(train_labels[train_labels == label]) + 1
    print('prior_probabilit =', prior_probability)

    # 计算条件概率
    for i in range(m):
        for j in range(n):
            # key的构造:类别,特征,特征值
            key = str(y[i]) + ',' + str(j) + ',' + str(trainset[i][j])
            if key in conditional_probability:
                conditional_probability[key] += 1
            else:
                conditional_probability[key] = 1
    print('conditional_probability = ', conditional_probability)

    # 因字典在循环时不能改变,故定义新字典来保存值
    conditional_probability_final = {}
    for key in conditional_probability:
        # 取出当前的类别
        label = key.split(',')[0]
        key1 = key.split(',')[1]
        Ni = len(set(trainset[:, int(key1)]))
        conditional_probability_final[key] = (conditional_probability[key]+1) / (prior_probability[int(label)] + Ni)

    # 最终先验概率(除以总数据量m)
    for label in labels:
        prior_probability[label] = prior_probability[label] / (m+len(labels))

    return prior_probability, conditional_probability_final, labels


# 定义预测函数
def predict(data):
    result = {}
    # 循环标签
    for label in train_labels_set:
        temp = 1.0
        for j in range(len(data)):
            key = str(label) + ',' + str(j) + ',' + str(data[j])
            # 条件概率连乘
            temp = temp * conditional_probability[key]
        # 在乘上先验概率
        result[label] = temp * prior_probability[label]
    print('result =', result)
    # 排序返回标签值
    return sorted(result.items(), key=lambda x: x[1], reverse=True)[0][0]


if __name__ == '__main__':
    X, y = loaddata()
    prior_probability, conditional_probability, train_labels_set = Train(X, y)
    print('conditional_probability = ', conditional_probability)

    # 预测
    y_hat = predict([2, 'S'])
    print('y_hat =', y_hat)

prior_probabilit = {1: 10, -1: 7}
conditional_probability =  {'-1,0,1': 3, '-1,1,S': 3, '-1,1,M': 2, '1,0,1': 2, '1,1,M': 4, '1,1,S': 1, '-1,0,2': 2, '1,0,2': 3, '1,1,L': 4, '1,0,3': 4, '-1,0,3': 1, '-1,1,L': 1}
conditional_probability =  {'-1,0,1': 0.4, '-1,1,S': 0.4, '-1,1,M': 0.3, '1,0,1': 0.23076923076923078, '1,1,M': 0.38461538461538464, '1,1,S': 0.15384615384615385, '-1,0,2': 0.3, '1,0,2': 0.3076923076923077, '1,1,L': 0.38461538461538464, '1,0,3': 0.38461538461538464, '-1,0,3': 0.2, '-1,1,L': 0.2}
result = {1: 0.027845457709711106, -1: 0.04941176470588235}
y_hat = -1

5.朴素贝叶斯如何处理连续数据

在这里插入图片描述

比较p(x|y=1)与p(x|y=-1)的大小,哪个大就取哪个类别

6.sklearn实现朴素贝叶斯

import numpy as np
from sklearn.naive_bayes import MultinomialNB
from sklearn.preprocessing import LabelEncoder


# 加载数据
def loaddata():
    X = np.array([[1, 'S'], [1, 'M'], [1, 'M'], [1, 'S'],
                  [1, 'S'], [2, 'S'], [2, 'M'], [2, 'M'],
                  [2, 'L'], [2, 'L'], [3, 'L'], [3, 'M'],
                  [3, 'M'], [3, 'L'], [3, 'L']])
    y = np.array([-1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1])
    return X, y


if __name__ == '__main__':
    X, y = loaddata()
    # 需把字符类型的转换为数字类型,即对字符类型进行编码
    X[:, 1] = LabelEncoder().fit_transform(X[:, 1])
    # 强制转化成整型
    X = X.astype(int)
    print(X)

    # 调用朴素贝叶斯模型并fit数据
    model = MultinomialNB()
    model.fit(X, y)

    # 预测
    # 对[2,'S']进行预测,将S转换成2
    y_hat = model.predict([[2, 2]])
    print('预测类别是', y_hat)
[[1 2]
 [1 1]
 [1 1]
 [1 2]
 [1 2]
 [2 2]
 [2 1]
 [2 1]
 [2 0]
 [2 0]
 [3 0]
 [3 1]
 [3 1]
 [3 0]
 [3 0]]
预测类别是 [-1]

7.垃圾邮件识别

from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split


# 获得词汇列表
def createVocabList(dataSet):
    # 创建空的词汇表
    vocabSet = set([])
    for document in dataSet:
        # 词汇表和set(document)取并集
        vocabSet = vocabSet | set(document)
    # 返回一个经过自然排序的词汇表
    return sorted(list(vocabSet))


# 把训练数据转换为向量
# 词集模型0与1
def setOfWords2Vec(vocabList, inputSet):
    # 初始化向量,其长度与词汇表长度一致
    returnVec = [0] * len(vocabList)
    for word in inputSet:
        if word in vocabList:
            # 把词汇表对应位置设为1
            returnVec[vocabList.index(word)] = 1
        else:
            print("词: %s 不在词汇表中!" % word)
    return returnVec


# 词袋模型
def bagOfWords2Vec(vocabList, inputSet):
    # 初始化向量,其长度与词汇表长度一致
    returnVec = [0] * len(vocabList)
    for word in inputSet:
        if word in vocabList:
            # 把词汇表对应位置加1
            returnVec[vocabList.index(word)] += 1
    return returnVec


# 对邮件内容进行预处理
def textParse(bigString):
    import re
    listOfTokens = re.split(r'\W*', bigString)
    # 返回长度大于2的且转换为小写
    return [tok.lower() for tok in listOfTokens if len(tok) > 2]


# 读取邮件
def loaddata():
    docList = []
    classList = []

    num = 26
    for i in range(1, num):
        # 读取垃圾邮件
        wordList = textParse(open('E:\email\spam\%d.txt' % i).read())
        docList.append(wordList)
        classList.append(1)

        # 读取非垃圾邮件
        wordList = textParse(open('E:/email/ham/%d.txt' % i).read())
        docList.append(wordList)
        classList.append(0)

    vocabList = createVocabList(docList)

    X = []
    for docIndex in range(len(docList)):
        X.append(bagOfWords2Vec(vocabList, docList[docIndex]))
        # X.append(setOfWords2Vec(vocabList, docList[docIndex]))

    return X, classList, vocabList


if __name__ == '__main__':
    X, y, vocaList = loaddata()
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=33, test_size=0.20)
    model = MultinomialNB()
    model.fit(X_train, y_train)
    y_hat = model.predict(X_test)
    print("accuracy=", accuracy_score(y_test, y_hat))
版权声明:本文为weixin_46649052原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_46649052/article/details/108434959

智能推荐

26_Python基础_继承

面向对象三大特性: 封装 根据 职责 将 属性 和 方法 封装 到一个抽象的 类 中 继承 实现代码的重用, 相同的代码不需要重复的编写 多态 不同的对象调用相同的方法,  产生不同的执行结果,  增加代码的灵活度 1.  单继承 1.1 概念 继承的概念:&...

循环

与任何程序设计语言一样Java利用条件语句与循环结构确定流程控制,一下总结一下Java中的循环语句: while do while for switch 对于golang来说: switch非常灵活。从第一个expr为true的case开始执行,如果case带有fallthrough,程序会继续执行下一条case,不会再判断下一条case的expr,如果之后的case都有fallthrough,d...

1638 统计只差一个字符的子串数目(动态规划)

1. 问题描述: 给你两个字符串 s 和 t ,请你找出 s 中的非空子串的数目,这些子串满足替换一个不同字符以后,是 t 串的子串。换言之,请你找到 s 和 t 串中恰好只有一个字符不同的子字符串对的数目。比方说, "computer" 和 "computation"...

websocket基本原理

HTTP中一个request只能有一个response。而且这个response也是被动的,不能主动发起 因此过去的服务端推送信息是通过客户端不停的轮询实现的 websocket是双向通信协议,提供了服务端主动推送信息的能力 需要客户端(浏览器)和服务端同时支持 如果经过代理的话,还需要代理支持,否则有些代理在长时间无通信时会自动切断连接 因此WS为了保证连接不被断掉,会发心跳 WebSocket...

mybatis+ehcache二级缓存

导入jar包 mapper.xml文件开启二级缓存 pojo类实现序列化接口 配置ehcache.xml 测试...

猜你喜欢

python+opencv实现图像拼接

任务 拍摄两张图片去除相同部分,拼接在一起 原图 结果 步骤 读取两张图片 使用sift检测关键点及描述因子 匹配关键点 处理并保存关键点 得到变换矩阵 图像变换并拼接 代码实现 扩展 这里对右边图像进行变换,右边变得模糊,可以修改代码对左边图像变换 这里只有两张图片拼接,可以封装实现多张图片拼接 可以修改代码实现上下图片的拼接...

python_sklearn机器学习算法系列之AdaBoost------人脸识别(PCA,决策树)

          注:在读本文之前建议读一下之前的一片文章python_sklearn机器学习算法系列之PCA(主成分分析)------人脸识别(k-NearestNeighbor,KNN)         本文主要目的是通过一个简单的小...

memmove函数与memcpy函数的模拟实现

memmove函数和memcpy函数都是在内存复制任意类型的,但是它俩也有区别。当源区域和目标区域有重复的,memmove函数会复制缓冲区重叠的部分,而memcpy相反,会报出未知错误。 下面给出两个函数的实现 首先,memmove函数。 实现的基本原理如下图。 具体代码如下: memcpy函数的实现很简单,就直接给出源代码了...

SpringFramework核心 - IOC容器的实现 - 总结

1. 概述 把Spring技术内幕第一章和第二章过了一遍,也做了一些笔记, 对IOC容器的实现有了一定皮毛理解,现在跟着源码再过一遍总结一下IOC容器的初始化,Bean的初始化的过程,做一下总结 ① IOC容器和简单工厂模式 在开始之前,先想想我们平时是怎么使用IOC容器为我们管理Bean的,假设我们要把下面的User类交给IOC容器管理 我们不想关心如何创建一个User对象实例的,仅仅在需要他的...