统计学习方法中算法实现(基于Python)--- 朴素贝叶斯

1.朴素贝叶斯法是典型的生成学习方法。生成方法由训练数据学习联合概率分布 P ( X , Y ) P(X,Y) P(X,Y),然后求得后验概率分布 P ( Y ∣ X ) P(Y|X) P(YX)。具体来说,利用训练数据学习 P ( X ∣ Y ) P(X|Y) P(XY) P ( Y ) P(Y) P(Y)的估计,得到联合概率分布:

P ( X , Y ) = P ( Y ) P ( X ∣ Y ) P(X,Y)=P(Y)P(X|Y) P(X,Y)P(Y)P(XY)
概率估计方法可以是极大似然估计或贝叶斯估计。

2.朴素贝叶斯法的基本假设是条件独立性,

P ( X = x ∣ Y = c k ) = P ( X ( 1 ) = x ( 1 ) , ⋯   , X ( n ) = x ( n ) ∣ Y = c k ) = ∏ j = 1 n P ( X ( j ) = x ( j ) ∣ Y = c k ) \begin{aligned} P(X&=x | Y=c_{k} )=P\left(X^{(1)}=x^{(1)}, \cdots, X^{(n)}=x^{(n)} | Y=c_{k}\right) \\ &=\prod_{j=1}^{n} P\left(X^{(j)}=x^{(j)} | Y=c_{k}\right) \end{aligned} P(X=xY=ck)=P(X(1)=x(1),,X(n)=x(n)Y=ck)=j=1nP(X(j)=x(j)Y=ck)
这是一个较强的假设。由于这一假设,模型包含的条件概率的数量大为减少,朴素贝叶斯法的学习与预测大为简化。因而朴素贝叶斯法高效,且易于实现。其缺点是分类的性能不一定很高。

3.朴素贝叶斯法利用贝叶斯定理与学到的联合概率模型进行分类预测。

P ( Y ∣ X ) = P ( X , Y ) P ( X ) = P ( Y ) P ( X ∣ Y ) ∑ Y P ( Y ) P ( X ∣ Y ) P(Y | X)=\frac{P(X, Y)}{P(X)}=\frac{P(Y) P(X | Y)}{\sum_{Y} P(Y) P(X | Y)} P(YX)=P(X)P(X,Y)=YP(Y)P(XY)P(Y)P(XY)
将输入 x x x分到后验概率最大的类 y y y。分母对于所有的类别都相同的,所以我们在实际进行分类计算时直接把分母去掉用下面这个

y = arg ⁡ max ⁡ c k P ( Y = c k ) ∏ j = 1 n P ( X j = x ( j ) ∣ Y = c k ) y=\arg \max _{c_{k}} P\left(Y=c_{k}\right) \prod_{j=1}^{n} P\left(X_{j}=x^{(j)} | Y=c_{k}\right) y=argckmaxP(Y=ck)j=1nP(Xj=x(j)Y=ck)
后验概率最大等价于0-1损失函数时的期望风险最小化。

三种贝叶斯分类器:

1、高斯贝叶斯分类器,适用于连续型数值数据
特征的可能性被假设为高斯

概率密度函数: P ( x i ∣ y k ) = 1 2 π σ y k 2 e x p ( − ( x i − μ y k ) 2 2 σ y k 2 ) P(x_i | y_k)=\frac{1}{\sqrt{2\pi\sigma^2_{yk}}}exp(-\frac{(x_i-\mu_{yk})^2}{2\sigma^2_{yk}}) P(xiyk)=2πσyk2 1exp(2σyk2(xiμyk)2)

数学期望(mean): μ \mu μ

方差: σ 2 = ∑ ( X − μ ) 2 N \sigma^2=\frac{\sum(X-\mu)^2}{N} σ2=N(Xμ)2

2、多项式贝叶斯分类器,适用于离散型数值数据

先验概率的贝叶斯估计为:

P λ ( Y = c k ) = ∑ i = 1 N I ( y i = c k ) + λ N + K λ P_λ(Y=c_k)=\frac{\sum_{i=1}^{N}I(y_i=c_k)+\lambda}{N+K\lambda} Pλ(Y=ck)=N+Kλi=1NI(yi=ck)+λ

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

P λ ( X ( j ) = a j l ∣ Y = c k ) = ∑ i = 1 N I ( x i ( j ) = a j l , y i = c k ) + λ ∑ i = 1 N I ( y i = c k ) + S j λ P_λ(X^{(j)}=a_{jl}|Y=c_k)=\frac{\sum_{i=1}^{N}I(x_i^{(j)}=a_{jl},y_i=c_k)+\lambda}{\sum_{i=1}^{N}I(y_i=c_k)+S_j\lambda} Pλ(X(j)=ajlY=ck)=i=1NI(yi=ck)+Sjλi=1NI(xi(j)=ajl,yi=ck)+λ

其中, λ ≥ 0 \lambda\geq 0 λ0 为平滑系数,当其为0时,就是极大似然估计(极大似然估计下可能会出现概率值为 0 的情况,影响最后的计算结果,加入平滑系数就是为了消除这一影响)。常取 λ = 1 \lambda=1 λ=1 ,这时称之为拉普拉斯平滑。

3、伯努利分类器 , 适用于 0-1 分布数据

P ( X ( j ) = a j l ∣ Y = c k ) = p X ( j ) + ( 1 − p ) ( 1 − X ( j ) ) P(X^{(j)}=a_{jl}|Y=c_k)=pX^{(j)}+(1-p)(1-X^{(j)}) P(X(j)=ajlY=ck)=pX(j)+(1p)(1X(j))

条件概率计算公式也可以直接用多项式分类器的计算方法

P λ ( X ( j ) = a j l ∣ Y = c k ) = ∑ i = 1 N I ( x i ( j ) = a j l , y i = c k ) + λ ∑ i = 1 N I ( y i = c k ) + S j λ P_λ(X^{(j)}=a_{jl}|Y=c_k)=\frac{\sum_{i=1}^{N}I(x_i^{(j)}=a_{jl},y_i=c_k)+\lambda}{\sum_{i=1}^{N}I(y_i=c_k)+S_j\lambda} Pλ(X(j)=ajlY=ck)=i=1NI(yi=ck)+Sjλi=1NI(xi(j)=ajl,yi=ck)+λ

以高斯分类器为例:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

from collections import Counter
import math

# data
def create_data():
    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']
    data = np.array(df.iloc[:100, :])
    # print(data)
    return data[:,:-1], data[:,-1]

x,y=create_data()
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=.3)

class NavieBayes:
    def __init__(self):
        self.model=None
        
    # 数学期望
    @staticmethod
    def mean(x):
        return sum(x)/float(len(x))
    
    # 标准差
    def stdev(self,x):
        avg=self.mean(x)
        return math.sqrt(sum([(_-avg)**2 for _ in x]) / float(len(x)))
    
    # 概率密度函数
    def gaussian_probability(self,x,mean,stdev):
        exp=np.exp( - ((x-mean)**2) / (2*(stdev**2)) )
#         exponent = np.exp(-(math.pow(x - mean, 2) / (2 * math.pow(stdev, 2))))
#         print('gaussian:',(1/(math.sqrt(2*math.pi)*stdev))*exp)
        return (1/(math.sqrt(2*math.pi)*stdev))*exp
    
    # 处理x_train。
    def summarizer(self,train_data):
        """
        >>> a = [1,2,3]
        >>> b = [4,5,6]
        >>> c = [4,5,6,7,8]
        >>> zipped = zip(a,b)     # 打包为元组的列表
        [(1, 4), (2, 5), (3, 6)]
        >>> zip(a,c)              # 元素个数与最短的列表一致
        [(1, 4), (2, 5), (3, 6)]
        >>> zip(*zipped)          # 与 zip 相反,可理解为解压,为zip的逆过程,可用于矩阵的转置
        [(1, 2, 3), (4, 5, 6)]
        """
        summarizer=[(self.mean(i),self.stdev(i))  for i in zip(*train_data)]
        return summarizer
    
    # 分别求出数学期望和方差
    def fit(self,x,y):
        labels=list(set(y))
        data={label : [] for label in labels}
        for f,label in zip(x,y):
            data[label].append(f)
        self.model={label : self.summarizer(value) for label,value in data.items()}
        return 'gaussianNB train done!'
    
    # 计算概率
    def calculate_probabilities(self,input_data):
        probablities={}
        for label,value in self.model.items():
            probablities[label]=1
            for i in range(len(value)):
                mean,stdev=value[i]
                probablities[label] *= self.gaussian_probability(input_data[i],mean,stdev)
#                 print('概率密度:',probablities)
        return probablities
    
    # 类别
    def predict(self,x_test):
        
#         print(self.calculate_probabilities(x_test))
        label=sorted(self.calculate_probabilities(x_test).items(),key=lambda x:x[-1])[-1][0]
        
#       label = sorted(
#             self.calculate_probabilities(x_test).items(),
#             key=lambda x: x[-1])[-1][0]
        return label
    
    def score(self,x_test,y_test):
        rigth=0
        for x,y in zip(x_test,y_test):
            label=self.predict(x_test)
            if label == y:
                rigth+=1
                
            return rigth/float(len(x_test))

验证:

model=NavieBayes()
model.fit(x_train,y_train)
print(model.predict([4.4,  3.2,  1.3,  0.2]))

# out:  0.0

model.score(x_test,y_test)

# out: 1.0

sklearn 中朴素贝叶斯的使用:

from sklearn.naive_bayes import GaussianNB,BernoulliNB, MultinomialNB  # 高斯、伯努利、多项式贝叶斯分类器

clf = GaussianNB()
clf.fit(X_train, y_train)


clf.score(X_test, y_test)


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Systemd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值