机器学习:朴素贝叶斯算法(Python)

一、朴素贝叶斯算法的实现

naive_bayes_classifier.py

import numpy as np
import collections as cc  # 集合的计数功能
from scipy.stats import norm  # 极大似然估计样本的均值和标准方差
from data_bin_wrapper import DataBinsWrapperclass NaiveBayesClassifier:"""朴素贝叶斯分类器:对于连续属性两种方式操作,1是分箱处理,2是直接进行高斯分布的参数估计"""def __init__(self, is_binned=False, is_feature_all_R=False, feature_R_idx=None, max_bins=10):self.is_binned = is_binned  # 连续特征变量数据是否进行分箱操作,离散化if is_binned:self.is_feature_all_R = is_feature_all_R  # 是否所有特征变量都是连续数值,boolself.max_bins = max_bins  # 最大分箱数self.dbw = DataBinsWrapper()  # 分箱对象self.dbw_XrangeMap = dict()  # 存储训练样本特征分箱的段点self.feature_R_idx = feature_R_idx  # 混合式数据中连续特征变量的索引self.class_values, self.n_class = None, 0  # 类别取值以及类别数self.prior_prob = dict()  # 先验分布,键是类别取值,键是类别取值self.classified_feature_prob = dict()  # 存储每个类所对应的特征变量取值频次或者连续属性的高斯分布参数self.feature_values_num = dict()  # 训练样本中每个特征不同的取值数,针对离散数据self.class_values_num = dict()  # 目标集中每个类别的样本量,Dcdef _prior_probability(self, y_train):"""计算类别的先验概率:param y_train: 目标集:return:"""n_samples = len(y_train)  # 总样本量self.class_values_num = cc.Counter(y_train)  # Counter({'否': 9, '是': 8})# print(self.class_values_num)for key in self.class_values_num.keys():self.prior_prob[key] = (self.class_values_num[key] + 1) / (n_samples + self.n_class)# print(self.prior_prob)def _data_bin_wrapper(self, x_samples):"""针对特定的连续特征属性索引dbw_feature_idx,分别进行分箱,考虑测试样本与训练样本使用同一个XrangeMap:param x_samples: 样本:即可以是训练样本,也可以是测试样本:return:"""self.feature_R_idx = np.asarray(self.feature_R_idx)x_samples_prop = []  # 分箱之后的数据if not self.dbw_XrangeMap:# 为空,即创建决策树前所做的分箱操作for i in range(x_samples.shape[1]):if i in self.feature_R_idx:  # 说明当前特征是连续数值self.dbw.fit(x_samples[:, i])self.dbw_XrangeMap[i] = self.dbw.XrangeMapx_samples_prop.append(self.dbw.transform(x_samples[:, i]))else:x_samples_prop.append(x_samples[:, i])else:  # 针对测试样本的分箱操作for i in range(x_samples.shape[1]):if i in self.feature_R_idx:  # 说明当前特征是连续数值x_samples_prop.append(self.dbw.transform(x_samples[:, i], self.dbw_XrangeMap[i]))else:x_samples_prop.append(x_samples[:, i])return np.asarray(x_samples_prop).Tdef fit(self, x_train, y_train):"""朴素贝叶斯分类器训练,可将朴素贝叶斯分类器涉及的所有概率估值事先计算好存储起来:param x_train: 训练集:param y_train: 目标集:return:"""x_train, y_train = np.asarray(x_train), np.asarray(y_train)self.class_values = np.unique(y_train)  # 类别取值self.n_class = len(self.class_values)  # 类别数if self.n_class < 2:print("仅有一个类别,不进行贝叶斯分类器估计...")exit(0)self._prior_probability(y_train)  # 先验概率# 每个特征变量不同的取值数,类条件概率的分子D(x, xi)for i in range(x_train.shape[1]):self.feature_values_num[i] = len(np.unique(x_train[:, i]))if self.is_binned:self._binned_fit(x_train, y_train)  # 分箱处理else:self._gaussian_fit(x_train, y_train)  # 直接进行高斯分布估计def _binned_fit(self, x_train, y_train):"""对连续特征属性进行分箱操作,然后计算各概率值:param x_train::param y_train::return:"""if self.is_feature_all_R:  # 全部是连续self.dbw.fit(x_train)x_train = self.dbw.transform(x_train)elif self.feature_R_idx is not None:x_train = self._data_bin_wrapper(x_train)for c in self.class_values:class_x = x_train[y_train == c]  # 获取对应类别的样本feature_counter = dict()  # 每个离散变量特征中特定值的出现的频次,连续特征变量存u、sigmafor i in range(x_train.shape[1]):feature_counter[i] = cc.Counter(class_x[:, i])self.classified_feature_prob[c] = feature_counterprint(self.classified_feature_prob)def _gaussian_fit(self, x_train, y_train):"""连续特征变量不进行分箱,直接进行高斯分布估计,离散特征变量取值除外:param x_train::param y_train::return:"""for c in self.class_values:class_x = x_train[y_train == c]  # 获取对应类别的样本feature_counter = dict()  # 每个离散变量特征中特定值的出现的频次,连续特征变量存u、sigmafor i in range(x_train.shape[1]):if self.feature_R_idx is not None and (i in self.feature_R_idx):  # 连续特征# 极大似然估计均值和方差mu, sigma = norm.fit(np.asarray(class_x[:, i], dtype=np.float64))feature_counter[i] = {"mu": mu, "sigma": sigma}else:  # 离散特征feature_counter[i] = cc.Counter(class_x[:, i])self.classified_feature_prob[c] = feature_counterprint(self.classified_feature_prob)def predict_proba(self, x_test):"""预测测试样本所属类别的概率:param x_test: 测试样本集:return:"""x_test = np.asarray(x_test)if self.is_binned:return self._binned_predict_proba(x_test)else:return self._gaussian_predict_proba(x_test)def _binned_predict_proba(self, x_test):"""连续特征变量进行分箱离散化,预测:param x_test: 测试样本集:return:"""if self.is_feature_all_R:x_test = self.dbw.transform(x_test)elif self.feature_R_idx is not None:x_test = self._data_bin_wrapper(x_test)y_test_hat = np.zeros((x_test.shape[0], self.n_class))  # 存储测试样本所属各个类别概率for i in range(x_test.shape[0]):test_sample = x_test[i, :]  # 当前测试样本y_hat = []  # 当前测试样本所属各个类别的概率for c in self.class_values:prob_ln = np.log(self.prior_prob[c])  # 当前类别的先验概率,取对数# 当前类别下不同特征变量不同取值的频次,构成字典feature_frequency = self.classified_feature_prob[c]for j in range(x_test.shape[1]):  # 针对每个特征变量value = test_sample[j]  # 当前测试样本的当前特征取值cur_feature_freq = feature_frequency[j]  # Counter({'浅白': 4, '青绿': 3, '乌黑': 2})# 按照拉普拉斯修正方法计算prob_ln += np.log((cur_feature_freq.get(value, 0) + 1) /(self.class_values_num[c] + self.feature_values_num[j]))y_hat.append(prob_ln)  # 输入第c个类别的概率y_test_hat[i, :] = self.softmax_func(np.asarray(y_hat))  # 适合多分类,且归一化return y_test_hat@staticmethoddef softmax_func(x):"""softmax函数,为避免上溢或下溢,对参数x做限制:param x: 数组: 1 * n_classes:return:"""exps = np.exp(x - np.max(x))  # 避免溢出,每个数减去其最大值return exps / np.sum(exps)def _gaussian_predict_proba(self, x_test):"""连续特征变量不进行分箱,直接按高斯分布估计:param x_test: 测试样本集:return:"""y_test_hat = np.zeros((x_test.shape[0], self.n_class))  # 存储测试样本所属各个类别概率for i in range(x_test.shape[0]):test_sample = x_test[i, :]  # 当前测试样本y_hat = []  # 当前测试样本所属各个类别的概率for c in self.class_values:prob_ln = np.log(self.prior_prob[c])  # 当前类别的先验概率,取对数# 当前类别下不同特征变量不同取值的频次,构成字典feature_frequency = self.classified_feature_prob[c]for j in range(x_test.shape[1]):  # 针对每个特征变量value = test_sample[j]  # 当前测试样本的当前特征取值if self.feature_R_idx is not None and (j in self.feature_R_idx):  # 连续特征# 取极大似然估计的均值和方差# print(feature_frequency[j].values())mu, sigma = feature_frequency[j].values()prob_ln += np.log(norm.pdf(value, mu, sigma) + 1e-8)else:cur_feature_freq = feature_frequency[j]  # Counter({'浅白': 4, '青绿': 3, '乌黑': 2})# 按照拉普拉斯修正方法计算prob_ln += np.log((cur_feature_freq.get(value, 0) + 1) /(self.class_values_num[c] + self.feature_values_num[j]))y_hat.append(prob_ln)  # 输入第c个类别的概率y_test_hat[i, :] = self.softmax_func(np.asarray(y_hat))  # 适合多分类,且归一化return y_test_hatdef predict(self, x_test):"""预测测试样本所属类别:param x_test: 测试样本集:return:"""return np.argmax(self.predict_proba(x_test), axis=1)

二、可视化分类边界函数

plt_decision_function.py

import matplotlib.pyplot as plt
import numpy as npdef plot_decision_function(X, y, clf, is_show=True):"""可视化分类边界函数:param X: 测试样本:param y: 测试样本的类别:param clf: 分类模型:param is_show: 是否在当前显示图像,用于父函数绘制子图:return:"""if is_show:plt.figure(figsize=(7, 5))x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1xi, yi = np.meshgrid(np.linspace(x_min, x_max, 100),np.linspace(y_min, y_max, 100))y_pred = clf.predict(np.c_[xi.ravel(), yi.ravel()])  # 模型预测值y_pred = y_pred.reshape(xi.shape)plt.contourf(xi, yi, y_pred, cmap="winter", alpha=0.4)plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors="k")plt.xlabel("Feature 1", fontdict={"fontsize": 12})plt.ylabel("Feature 2", fontdict={"fontsize": 12})plt.title("NativeBayes Model Classification Boundary", fontdict={"fontsize": 14})if is_show:plt.show()

三、朴素贝叶斯算法的测试

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from naive_bayes_classifier import NaiveBayesClassifier
from sklearn.datasets import make_blobs
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from plt_decision_function import plot_decision_function# wm = pd.read_csv("watermelon.csv").dropna()
# X, y = np.asarray(wm.iloc[:, 1:-1]), np.asarray(wm.iloc[:, -1])
# # print(X)
# # print(y)
# nbc = NaiveBayesClassifier(is_binned=True, feature_R_idx=[6, 7], max_bins=10)
# nbc.fit(X, y)
# y_proba = nbc.predict_proba(X)
# print(y_proba)
# y_hat = nbc.predict(X)
# print(y_hat)X, y = make_blobs(n_samples=500, n_features=2, centers=4, cluster_std=0.85, random_state=0)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0, stratify=y)nbc = NaiveBayesClassifier(is_binned=True, max_bins=20, is_feature_all_R=True)
nbc.fit(X_train, y_train)
y_pred = nbc.predict(X_test)
print(classification_report(y_test, y_pred))
plt.figure(figsize=(14, 5))
plt.subplot(121)
plot_decision_function(X_train, y_train, nbc, is_show=False)nbc = NaiveBayesClassifier(is_binned=False, feature_R_idx=[0, 1])
nbc.fit(X_train, y_train)
y_pred = nbc.predict(X_test)
print(classification_report(y_test, y_pred))
plt.subplot(122)
plot_decision_function(X_train, y_train, nbc, is_show=False)
plt.show()# al = pd.read_csv("mushroom/agaricus-lepiota.data").dropna()

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2813563.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

基础算法(二)( 枚举)

1.枚举算法介绍&#xff1a; 枚举算法是一种基本的算法思想&#xff0c;它通过穷举所有可能的情况来解决问题。它的基本思想是将问题的解空间中的每个可能的解都枚举出来&#xff0c;并进行验证和比较&#xff0c;找到满足问题条件的最优解或者所有解。枚举算法适用于问题规模…

Nginx ---- 高性能得WEB服务端(三)

一、重写功能 rewrite Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求&#xff0c;此功能依靠 PCRE(perl compatible regular expression)&#xff0c;因此编译之前要安装PCRE库&#xff0c;rewrite是nginx服务器的重要功能之一&#xff0c;重写功能(r…

基于springboot+vue的学科平台系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

Redis高可用三主三从集群部署(三种方式部署/18个节点的大集群)

文章目录 &#x1f50a;博主介绍&#x1f964;本文内容使用宝塔面板搭建集群规划配置验证 使用docker搭建使用脚本搭建规划防火墙端口配置脚本redis.conf配置文件执行过程 &#x1f4e2;文章总结&#x1f4e5;博主目标 &#x1f50a;博主介绍 &#x1f31f;我是廖志伟&#xff…

【递归】【回溯】Leetcode 112. 路径总和 113. 路径总和 II

【递归】【回溯】Leetcode 112. 路径总和 113. 路径总和 II 112. 路径总和解法&#xff1a;递归 有递归就有回溯 记得return正确的返回上去 113. 路径总和 II解法 递归 如果需要搜索整棵二叉树&#xff0c;那么递归函数就不要返回值 如果要搜索其中一条符合条件的路径&#xff…

AI入门笔记(二)

紧接着上一篇幅&#xff0c;点火条件的图形表示如下。 利用单位阶跃函数可表示点火的式子&#xff1a;yu(w1x1w2x2w3x3-θ) 因为u表示的是单位阶跃函数&#xff0c;那么一般化点火的式子可以表示为&#xff1a;ya(w1x1w2x2w3x3-θ)&#xff0c;此处的a表示激活函数&#xff0…

笔记:GO1.19 带来的优化(重新编译juicefs)

## 背景 go编写的应用程序&#xff08;juicefs&#xff09;在k8s&#xff08;docker&#xff09;中运行&#xff0c;时不时出现 OOM Killed。 ## 分析 发现某些应用使用juicefs会导致内存使用飙升&#xff1b; k8s的pod给的内存资源&#xff1a;request 2G&#xff0c;limit…

ui设计:利用即使设计设计出漂亮样式

目录 一、基本操作 二、具体介绍 6-1 填充图片 6-2 填充色 6-3 图标 右边栏基础设置 右边栏导出​编辑 一、基本操作 二、具体介绍 6-1 填充图片 选择其一图片填充 6-2 填充色 6-3 图标 右边栏基础设置 右边栏导出

面试redis篇-12Redis集群方案-分片集群

原理 主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决&#xff1a; 海量数据存储问题高并发写的问题 使用分片集群可以解决上述问题&#xff0c;分片集群特征&#xff1a; 集群中有多个master&#xff0c;每个master保存不同数据每个master都可以有…

腾讯云4核8g的服务器能承受多少并发?

腾讯云4核8G服务器支持多少人在线访问&#xff1f;支持25人同时访问。实际上程序效率不同支持人数在线人数不同&#xff0c;公网带宽也是影响4核8G服务器并发数的一大因素&#xff0c;假设公网带宽太小&#xff0c;流量直接卡在入口&#xff0c;4核8G配置的CPU内存也会造成计算…

ADS-B Ground Receiver Radarcape

目录 Radarcape ADS-B MLAT Receiver Web Browser User Interface Radarcape Technical Data Radarcape Software Features Radarcape Basics Radarcape ADS-B MLAT Receiver Radarcape is a professional ADS-B receiver made for 24/7 operation. High performance rec…

AI赚钱套路总结和教程

最近李一舟和Sora 很火&#xff0c;作为第一批使用Sora赚钱的男人&#xff0c;一个清华学美术的跟人讲AI&#xff0c;信的人太多了&#xff0c;钱太好赚了。3年时间&#xff0c;李一舟仅通过卖课就赚了1.75亿元&#xff0c;其中《每个人的人工智能课》收入2786万元&#xff0c;…

【Flink】Flink 中的时间和窗口之窗口(Window)

1. 窗口的概念 Flink是一种流式计算引擎&#xff0c;主要是来处理无界数据流&#xff0c;数据流的数据是一直都有的&#xff0c;等待流结束输入数据获取所有的流数据在做聚合计算是不可能的。为了更方便高效的处理无界流&#xff0c;一种方式就是把无限的流数据切割成有限的数…

XINDOO的2023年总结

这篇文章是我的第十年年终总结&#xff0c;本来想很正式的写&#xff0c;由于元旦偷懒&#xff0c;春节又特种式狂奔四个城市给自己和妹妹订婚&#xff0c;横跨几千公里&#xff0c;几乎一半的假期都在路上。我23年的年终总结难产至今&#xff0c;最后赶在2月结束前开始动笔。 …

vscode与vue/react环境配置

一、下载并安装VScode 安装VScode 官网下载 二、配置node.js环境 安装node.js 官网下载 会自动配置环境变量和安装npm包(npm的作用就是对Node.js依赖的包进行管理)&#xff0c;此时可以执行 node -v 和 npm -v 分别查看node和npm的版本号&#xff1a; 配置系统变量 因为在执…

Nginx -3

接着上文写 七. 重写功能 Nginx 服务器利用 ngx_http_rewrite_module 模块解析和处理 rewrite 请求&#xff0c;此功能依靠 PCRE (perl compatible regular expression)&#xff0c;因此编译之前要安装PCRE库&#xff0c;rewrite 是 nginx 服务器的重要功能之一&#xff0c;用…

Flask基础学习4

19-【实战】问答平台项目结构搭建_剪_哔哩哔哩_bilibili 参考如上大佬的视频教程&#xff0c;本博客仅当学习笔记&#xff0c;侵权请联系删除 问答发布的web前端页面实现 register.html {% extends base.html %}{% block head %}<link rel"stylesheet" href&q…

LeetCode--代码详解 230. 二叉搜索树中第K小的元素

230. 二叉搜索树中第K小的元素 题目 给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计一个算法查找其中第 k 个最小元素&#xff08;从 1 开始计数&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,1,4,null,2], k 1 输出&#…

MFC web文件 CHttpFile的使用初探

MFC CHttpFile的使用 两种方式&#xff0c;第一种OpenURL&#xff0c;第二种SendRequest&#xff0c;以前捣鼓过&#xff0c;今天再次整结果发现各种踩坑&#xff0c;好记性不如烂笔头&#xff0c;记录下来。 OpenURL 这种方式简单粗暴&#xff0c;用着舒服。 try {//OpenU…

[C++][linux]Linux上内存共享内存用法

一&#xff0c;什么是共享内存 共享内存&#xff08;Shared Memory&#xff09;&#xff0c;指两个或多个进程共享一个给定的存储区。进程可以将同一段共享内存连接到它们自己的地址空间中&#xff0c;所有进程都可以访问共享内存中的地址&#xff0c;就好像它们是由用C语言函…