朴素贝叶斯假设各属性间相互独立,直接从已有样本中计算各种概率,以贝叶斯方程推导出预测样本的分类。

为了处理预测时样本的(类别,属性值)对未在训练样本出现,从而导致概率为0的情况,使用拉普拉斯修正(假设属性值与类别均匀分布)。

代码及注释如下:

一、离散值

1,朴素贝叶斯算法计算相关参数并返回,预测使用这些参数即可

# 手写拉普拉斯修正的朴素贝叶斯
import numpy as np
import pandas as pd
def naive_bayes(data):
'''data:pandas.DataFrame'''
# 列名
attrs=data.columns
# 类别
labels=data[attrs[-1]].unique()
# 类别数
N=labels.size
# 样本总数
D=data.index.size
# c类样本概率
pc=np.empty(shape=(N,1))
# c类中,第i个属性取值为xi的概率,这里计算了所有,而非只针对测试样本,保存后predict时直接从里面取值即可
p_xc=[]
# 包含每个属性的可取值
features=[data[i].unique() for i in attrs[:-1]]
for i in range(N):
df=data[data[attrs[-1]]==labels[i]]
Dc=df[attrs[0]].count()
pc[i]=np.array([(Dc+1)/(D+N)])
p_c=[]
for j in range(len(features)):
values=features[j]
Ni=values.size
c_attr=[]
for value in values:
Dc_xi=df[df[attrs[j]]==value].index.size
c_attr.append((Dc_xi+1)/(Dc+Ni))
p_c.append(c_attr)
p_xc.append(p_c)
return p_xc,pc,N,features,labels
# 预测一个样本
def predict(x,p_xc,pc,num_class,features,labels):
result=[]
for i in range(num_class):
res=1.
c=p_xc[i]
for j in range(len(c)):
feature_j=c[j]
for k in range(len(feature_j)):
if x[j]==features[j][k]:
res*=feature_j[k]
result.append(pc[i][0]*res)
max_c=0
max_index=-1
for i in range(len(result)):
if result[i]>max_c:
max_c=result[i]
max_index=i
return result,labels[max_index]
# 预测多个样本
def predicts(x,p_xc,pc,num_class,features,labels):
result=[]
for data in x:
_,clazz=predict(data,p_xc,pc,num_class,features,labels)
result.append(clazz)
return result

2,使用西瓜集2.0训练及测试

def createDataSet():

    dataSet = [
#
['青绿', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '好瓜'],
#
['乌黑', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', '好瓜'],
#
['乌黑', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '好瓜'],
#
['青绿', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', '好瓜'],
#
['浅白', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '好瓜'],
#
['青绿', '稍蜷', '浊响', '清晰', '稍凹', '软粘', '好瓜'],
#
['乌黑', '稍蜷', '浊响', '稍糊', '稍凹', '软粘', '好瓜'],
#
['乌黑', '稍蜷', '浊响', '清晰', '稍凹', '硬滑', '好瓜'], # ----------------------------------------------------
#
['乌黑', '稍蜷', '沉闷', '稍糊', '稍凹', '硬滑', '坏瓜'],
#
['青绿', '硬挺', '清脆', '清晰', '平坦', '软粘', '坏瓜'],
#
['浅白', '硬挺', '清脆', '模糊', '平坦', '硬滑', '坏瓜'],
#
['浅白', '蜷缩', '浊响', '模糊', '平坦', '软粘', '坏瓜'],
#
['青绿', '稍蜷', '浊响', '稍糊', '凹陷', '硬滑', '坏瓜'],
#
['浅白', '稍蜷', '沉闷', '稍糊', '凹陷', '硬滑', '坏瓜'],
#
['乌黑', '稍蜷', '浊响', '清晰', '稍凹', '软粘', '坏瓜'],
#
['浅白', '蜷缩', '浊响', '模糊', '平坦', '硬滑', '坏瓜'],
#
['青绿', '蜷缩', '沉闷', '稍糊', '稍凹', '硬滑', '坏瓜']
] # 特征值列表
labels = ['色泽', '根蒂', '敲击', '纹理', '脐部', '触感','好坏']
dataset=pd.DataFrame(data=dataSet,columns=labels)
return dataset

3,训练及预测

这里预测使用训练数据,可以看到精度却不咋样,个人认为这跟样本太小、使用了修正(修正在大样本下的影响较小)及属性并非相互独立有关

dataset=createDataSet()
p_xc,pc,num_class,features,labels=naive_bayes(dataset) value=dataset[dataset.columns[:-1]].values
result=predicts(value,p_xc,pc,num_class,features,labels)
real=dataset[dataset.columns[-1]].values
df=pd.DataFrame([[result[i]==real[i] for i in range(len(result))]])
# 精度 0.8235294117647058
df.iloc[0].sum()/df.iloc[0].count()

二、连续值

1,贝叶斯方法

def normal_distribution(mean,var,x):
return np.power(np.e,-(x-mean)*(x-mean)/(2*var))/np.sqrt(2*np.pi*var)
# 连续值处理,假设数据服从正态分布,如上函数所示
def naive_bayes_2(X_train,y_train):
'''data:pandas.DataFrame'''
labels=list(set(y_train))
# 类别数
num_class=len(labels)
data=pd.DataFrame(X_train,columns=['l1','l2','l3','l4'])
data['label']=y_train
N=len(y_train)
# 均值和方差
means=[]
vals=[]
# c类样本概率
pc=np.empty(shape=(num_class,1))
# 对每一类求均值和方差
for i in range(num_class):
df=data[data['label']==labels[i]]
l=df.index.size
pc[i]=l/N
mean=[]
val=[]
# 各属性的均值和方差
for col in df.columns[:-1]:
mean.append(df[col].mean())
val.append(df[col].var())
means.append(mean)
vals.append(val) return means,vals,pc,labels
# 预测多个样本
def predict_2(x_test,means,vals,pc,labels):
num_class=len(labels)
results=[]
for x in x_test:
result=[]
for i in range(num_class):
res=1.
res*=pc[i][0]
j=0
for mean,val in zip(means[i],vals[i]):
res*=normal_distribution(mean,val,x[j])
j+=1
result.append(res)
results.append(labels[result.index(max(result))])
return results

2,使用sklearn中iris数据集

from sklearn.datasets import load_iris
data = load_iris() x=data['data']
y=data['target']
cols=data['target_names'] from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test=train_test_split(x,y,test_size=0.2,random_state=10)

3,训练及测试

means,vals,pc,labels=naive_bayes_2(X_train,y_train)

results=predict_2(X_test,means,vals,pc,labels)

from sklearn.metrics import accuracy_score
# 精度100%
accuracy_score(results,y_test)

三、总结

例举了2个例子,离散值的样本少,使用了修正,精度不咋样,连续值的精度100%,取得不错的效果,也说明各个类别下的各个特征基本符合正态分布。

手写朴素贝叶斯(naive_bayes)分类算法的更多相关文章

  1. 3.朴素贝叶斯和KNN算法的推导和python实现

    前面一个博客我们用Scikit-Learn实现了中文文本分类的全过程,这篇博客,着重分析项目最核心的部分分类算法:朴素贝叶斯算法以及KNN算法的基本原理和简单python实现. 3.1 贝叶斯公式的推 ...

  2. 机器学习集成算法--- 朴素贝叶斯,k-近邻算法,决策树,支持向量机(SVM),Logistic回归

    朴素贝叶斯: 是使用概率论来分类的算法.其中朴素:各特征条件独立:贝叶斯:根据贝叶斯定理.这里,只要分别估计出,特征 Χi 在每一类的条件概率就可以了.类别 y 的先验概率可以通过训练集算出 k-近邻 ...

  3. 朴素贝叶斯算法——实现新闻分类(Sklearn实现)

    1.朴素贝叶斯实现新闻分类的步骤 (1)提供文本文件,即数据集下载 (2)准备数据 将数据集划分为训练集和测试集:使用jieba模块进行分词,词频统计,停用词过滤,文本特征提取,将文本数据向量化 停用 ...

  4. Python机器学习笔记:朴素贝叶斯算法

    朴素贝叶斯是经典的机器学习算法之一,也是为数不多的基于概率论的分类算法.对于大多数的分类算法,在所有的机器学习分类算法中,朴素贝叶斯和其他绝大多数的分类算法都不同.比如决策树,KNN,逻辑回归,支持向 ...

  5. [机器学习] 分类 --- Naive Bayes(朴素贝叶斯)

    Naive Bayes-朴素贝叶斯 Bayes' theorem(贝叶斯法则) 在概率论和统计学中,Bayes' theorem(贝叶斯法则)根据事件的先验知识描述事件的概率.贝叶斯法则表达式如下所示 ...

  6. 统计学习方法与Python实现(三)——朴素贝叶斯法

    统计学习方法与Python实现(三)——朴素贝叶斯法 iwehdio的博客园:https://www.cnblogs.com/iwehdio/ 1.定义 朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设 ...

  7. scikit-learn 朴素贝叶斯类库使用小结

    之前在朴素贝叶斯算法原理小结这篇文章中,对朴素贝叶斯分类算法的原理做了一个总结.这里我们就从实战的角度来看朴素贝叶斯类库.重点讲述scikit-learn 朴素贝叶斯类库的使用要点和参数选择. 1. ...

  8. 机器学习Sklearn系列:(四)朴素贝叶斯

    3--朴素贝叶斯 原理 朴素贝叶斯本质上就是通过贝叶斯公式来对得到类别概率,但区别于通常的贝叶斯公式,朴素贝叶斯有一个默认条件,就是特征之间条件独立. 条件概率公式: \[P(B|A) = \frac ...

  9. Mahout朴素贝叶斯文本分类

    Mahout朴素贝叶斯文本分类算法 Mahout贝叶斯分类器按照官方的说法,是按照<Tackling the PoorAssumptions of Naive Bayes Text Classi ...

随机推荐

  1. 磁盘IO及性能指标

    一.磁盘 I/O 的概念 I/O 的概念,从字义来理解就是输入输出.操作系统从上层到底层,各个层次之间均存在 I/O.比如,CPU 有 I/O,内存有 I/O, VMM 有 I/O, 底层磁盘上也有 ...

  2. 我说CMMI之二:CMMI里有什么?--转载

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/dylanren/article/deta ...

  3. 各种环境下搭建ruby on rails开发环境

    win10上搭建raby on rails环境: 步骤如下 1.安装ruby (我选择的版本是ruby 2.2.3p173) 2.安装rails gem 在这之前建议先把gem的源换成淘宝的源,速度快 ...

  4. 2017noip总结

    day0 酒店位置很好,旁边就是玉树公园,3公里处还有万达广场: 晚上去万达吃喝玩乐, 不过,打车等了好久,手机还没电了. 同时水杯还在广州扎根了...(暗示后文悲惨结局) day1 8:30 监考老 ...

  5. d3 词云使用

    D3-Cloud是一个开源的词云实现,基于D3.js,使用HTML5 Canvas绘制输出,因为采用异步的方式处理,所以表现性能良好. 项目主页:https://www.jasondavies.com ...

  6. 27. ClustrixDB 分布式架构/一致性、容错和可用性

    一致性 许多分布式数据库都采用最终一致性而不是强一致性来实现可伸缩性.但是,最终的一致性会增加应用程序开发人员的复杂性,他们必须针对可能出现的数据不一致的异常进行开发. ClustrixDB提供了一个 ...

  7. Visual Studio 2008:路径设置

    造冰箱的大熊猫,本文适用于Visual Studio 2008中文版@cnblogs 2018/11/30 1.头文件路径设置 如果头文件所在路径未在环境变量中定义,编译时会出现C1083错误,提示无 ...

  8. System limit for number of file watchers reached

    https://blog.csdn.net/weixin_43760383/article/details/84326032 sudo xed /etc/sysctl.conf 在最下添加 fs.in ...

  9. 在vue项目中添加一个html页面,开启本地服务器

    在vue项目里新增一个不需要登录的页面,那么我只能新增一个html页面了,不经过路由,直接在浏览器输入路径打开,那么就需要用到本地服务器, 1.vue里面的html页面最好放过在public文件夹里面 ...

  10. [LOJ6433][PKUSC2018]最大前缀和:状压DP

    分析 我们让每个数列在第一个取到最大前缀和的位置被统计到. 假设一个数列在\(pos\)处第一次取到最大前缀和,分析性质,有: 下标在\([1,pos]\)之间的数形成的数列的每个后缀和(不包括整个数 ...