Press "Enter" to skip to content

朴素贝叶斯模型及python实现

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

1 朴素贝叶斯模型

 

朴素贝叶斯法是基于贝叶斯定理、特征条件独立假设的分类方法。在预测时,对输入x,找出对应后验概率最大的 y 作为预测。

 

NB模型:

 

输入:
先验概率分布:$$P\left(Y=c_ k}\right), \quad k=1,2, \cdots, K


P\left(X=x Y=c_{k
\right)=P\left(X^
(1)}=x^{(1)}, \cdots, X^{(n)}=x^{(n)} Y=c_{k
\right), \quad k=1,2, \cdots, K$$
其中,输入数据 X 维度为

.

输出:测试数据的后验概率
根据

, 有:

NB分类器即为:

其中,分母是归一化因子,可以忽略。
朴素贝叶斯可以分为高斯朴素贝叶斯、多项式朴素贝叶斯、贝努利朴素贝叶斯等多种。

 

2 朴素贝叶斯的参数估计

 

朴素贝叶斯需要估计先验概率

和条件概率

.以下只考虑离散属性情形。

 

2.1 极大似然法(MLE)

 

使用极大似然法估计(Maximum Likehood Estimation)先验概率:

条件概率:

2.2 贝叶斯估计

 

极大似然法可能出现概率值为 0 情况,贝叶斯估计使用了拉普拉斯平滑.
先验概率的贝叶斯估计为:

条件概率的贝叶斯估计为:

Q1:这里极大似然估计和贝叶斯估计感觉描述没什幺区别?
A1:《机器学习》书中,没有提拉普拉斯平滑当作贝叶斯估计,还是有点疑问。

 

3 朴素贝叶斯实现

 

3.1 高斯朴素贝叶斯实现

 

高斯朴素贝叶斯用于连续数据的预测,原理是假设训练集各个特征满足高斯分布,获得不同类别数据集对应不同特征的高斯分布均值和方差,然后计算测试样本各个特征属于相应高斯分布的概率,从而获得其属于某个类别的概率,并把概率最大的标签作为这个样本的标签。

 

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
import pandas as pd
from sklearn.model_selection import train_test_split
import math

sqrt, exp, pi = np.sqrt, np.exp, np.pi
def createData():
    iris = load_iris()
    df = pd.DataFrame(iris.data, columns = iris.feature_names)
    df['label'] = iris.target
    df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 
                  'label']
    return df.iloc[:,:-1],df.iloc[:,-1]
X,y = createData()
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X, y, test_size = 0.5, random_state = 1028)
class GaussianNaiveBayes(object):
    '''
    高斯朴素贝叶斯,用于处理连续数据,输入使用numpy.array.
    '''
    def __init__(self):
        self.model = None
    @staticmethod
    def mean(x):
        '''
        求array类型的特征(列)平均值
        '''
        return sum(x)/float(len(x))
    
    def var(self, x):
        '''
        求特征的方差
        '''
        return sum(pow(x-self.mean(x),2)*1.0/len(x))
    
    def gaussianProba(self, x, mean, var):
        '''
        使用高斯概率密度,求测试集属于某个特征的值
        '''
        return 1/(sqrt(2*pi*var))*exp(-pow(x-mean,2)/(2.0*var))
    
    def summarize(self, data):
        '''
        返回训练集每个特征的平均值,方差。
        '''
        data = np.array(data)
        return [self.mean(data),self.var(data)]
        
    def fit(self, x, y):
        '''
        获得训练集每个标签对应每个特征的平均值,方差。
        '''
        labels = np.unique(y)
        data = {label:[] for label in labels}
        for f, label in zip(x, y):
            data[label].append(f.tolist())
        self.model = {label: self.summarize(value) for label,
                      value in data.items()}
        return data,self.model
        
    def calculateProba(self, data):
        '''
        计算测试集对应在每个类别的概率。
        '''
        prob = {}     
        data = data.transpose()
        for label, value in self.model.items():
            prob[label] = 1
            for i in range(len(data)):
                prob[label] *= self.gaussianProba(data[i], value[0][i], 
                    value[1][i])
        return prob
    
    def predict(self, data):
        '''
        把概率最高的值作为样本的标签。
        '''
        res = []
        for label, value in self.calculateProba(data).items():
            res.append(value)
        res = np.array(res)
        return np.argmax(res, axis = 0)
            
    def score(self, x, y):
        '''
        计算预测的准确率。
        '''
        score = 0
        label = self.predict(x)
        for i in range(len(label)):
            if label[i] ==y[i]:
                score+=1
        return score*1.0/len(label)
            
            
if __name__ == '__main__':
    model = GaussianNaiveBayes()
    data, m1 = model.fit(Xtrain.values, Ytrain.values)
    prob = model.calculateProba(Xtest.values)
    label = model.predict(Xtest.values)
    score = model.score(Xtest.values, Ytest.values)
    print('accuary', score)

 

结果: accuary 0.9466666666666667

 

3.2 多项式朴素贝叶斯MultinomialNB

 

多项式朴素贝叶斯可以用于离散数据的分类中。
调用sklearn API:

 

import numpy as np
rng = np.random.RandomState(1)
X = rng.randint(5, size=(6, 100))
y = np.array([1, 2, 3, 4, 5, 6])
from sklearn.naive_bayes import MultinomialNB
clf = MultinomialNB()
clf.fit(X, y)
print(clf.predict(X[2:3]))

 

4. 拓展:极大似然估计与贝叶斯估计的区别

 

贝叶斯是 假定模型参数服从某种分布
,然后对模型参数分布进行估计。这和极大似然法非常不同(极大似然法假设参数是某个值,只是对参数估计,属于点估计范围)。
贝叶斯估计应用分为两种,对离散数据的估计及对连续数据的估计,其实差别不大,只是参数分布假设不同,连续数据时模型参数多假设为高斯分布。

 

参考:

GitHub贝叶斯详解及代码
CSDN.关于朴素贝叶斯法
黄海广 GitHub代码
wepon大神blog
Bayes 课件 Utdallas.edu
Bayes MLE MAP 区别 cmu
MLE 解释 英文
sklearn Naive Bayes

Be First to Comment

发表评论

电子邮件地址不会被公开。 必填项已用*标注