skilearn 高斯贝叶斯的一些理解

今天关于高斯朴素贝叶斯有一些新的理解,目前也尚存一些疑问,都记录下来,后续解决,如有朋友看到知道我的疑惑或我的理解中有错误的地方,请指正一下,谢谢!
对于连续的属性,若要使用朴素贝叶斯来做分类,则最常见的有两种方式:

  1. 连续属性离散化,然后就可以当做离散属性处理了;
  2. 但是最常见的还是使用高斯贝叶斯来处理,我这边主要也是一些关于高斯贝叶斯的理解;

理解1:
高斯贝叶斯实际上是假设各个属性在各个类别中均服从高斯分布,然后便可以使用极大似然估计得到高斯分布的参数——均值和方差,之后使用概率密度来得到某样本属于各个类别的“概率”,此处,我将概率打了引号,因为我认为这里的概率已经不是真正的概率了,概率密度只能衡量某个值时发生概率的大小,但是其本身不是概率。
不过用skilearn的GaussianNB输出的各个属性的“概率”相加确实等于1,这是为什么?因为skilearn中做了logsumexp处理,简单的说就是将各个利用朴素贝叶斯得到的“概率”值重新调整,变为相加等于1的各个概率值。
logsumexp详见:http://m.elecfans.com/article/805898.html
下面两张图片是skilearn中的朴素贝叶斯中截的源码的图,第一张是高斯贝叶斯计算联合概率(log),第二张是返回某样本处于各个类别的概率(log)。这可以验证上述我的理解的正确性。
在这里插入图片描述
在这里插入图片描述

理解2:
由于高斯贝叶斯只是用各个类别的样本去极大似然估计出高斯分布的均值和方差,因此,实际上高斯贝叶斯受类别不均衡的影响较小,我利用iris数据集做了验证确实是这样,验证代码及结果如下(结果见我的注释中)

# -*- coding: utf-8 -*-
"""
Created on Fri Jun  7 17:36:07 2019

@author: Administrator
"""

from sklearn.naive_bayes import GaussianNB
import pandas as pd
import numpy as np


def get_x_number(x , class_list):
    count = 0
    for i in class_list:
        if i == x:
            count += 1
    return count

df = pd.read_csv('iris.csv' , encoding = 'gbk')
df.rename(columns = {'sepal_length':'f1' , \
    'sepal_width':'f2' , 'petal_length':'f3' , 'petal_width':'f4' , 'species':'target'} , inplace = True)
# print(df)
train_set = df[['f1' , 'f2'  ,'f3' , 'f4']].values
target_set = df['target'].tolist()
'''
type1_num = get_x_number(0 , iris.target)
type2_num = get_x_number(1 , iris.target)
type3_num = get_x_number(2 , iris.target)
print(type1_num , type2_num , type3_num)
实验显示,三种种类各有50个sample,这里标记为0,1,2
'''
#实验一:原始数据,三种类别的数据各有50个,实验结果准确率为96%
clf = GaussianNB()
clf = clf.fit(train_set, target_set)
y_pred=clf.predict(train_set)
# print(target_set)
# print(y_pred)
print(clf.score(train_set, target_set))

#实验二:将第一个类的样本数量削减到20个,实验结果准确率95%
df = pd.read_csv('iris2.csv' , encoding = 'gbk')
df.rename(columns = {'sepal_length':'f1' , \
    'sepal_width':'f2' , 'petal_length':'f3' , 'petal_width':'f4' , 'species':'target'} , inplace = True)
# print(df)
train_set = df[['f1' , 'f2'  ,'f3' , 'f4']].values
target_set = df['target'].tolist()
clf = GaussianNB()
clf = clf.fit(train_set, target_set)
y_pred=clf.predict(train_set)
# print(target_set)
# print(y_pred)
print(clf.score(train_set, target_set))

#实验三:将第一个类和第二个类的样本数量削减到20个,实验结果准确率94.44%
df = pd.read_csv('iris3.csv' , encoding = 'gbk')
df.rename(columns = {'sepal_length':'f1' , \
    'sepal_width':'f2' , 'petal_length':'f3' , 'petal_width':'f4' , 'species':'target'} , inplace = True)
# print(df)
train_set = df[['f1' , 'f2'  ,'f3' , 'f4']].values
target_set = df['target'].tolist()
clf = GaussianNB()
clf = clf.fit(train_set, target_set)
y_pred=clf.predict(train_set)
# print(target_set)
# print(y_pred)
print(clf.score(train_set, target_set))

#实验四:在实验三的基础上,将类别一的样本数进一步减少到5个,实验结果准确率93.33%
df = pd.read_csv('iris4.csv' , encoding = 'gbk')
df.rename(columns = {'sepal_length':'f1' , \
    'sepal_width':'f2' , 'petal_length':'f3' , 'petal_width':'f4' , 'species':'target'} , inplace = True)
# print(df)
train_set = df[['f1' , 'f2'  ,'f3' , 'f4']].values
target_set = df['target'].tolist()
clf = GaussianNB()
clf = clf.fit(train_set, target_set)
y_pred=clf.predict(train_set)
# print(target_set)
# print(y_pred)
print(clf.score(train_set, target_set))

代码中的4个实验得到的分类器的正确性分别是:
0.96
0.95
0.9444444444444444
0.9333333333333333
因此,可以认为几乎没有收到类别不均衡的影响。

发布了41 篇原创文章 · 获赞 40 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_39805362/article/details/91129684
今日推荐