《统计学习方法》第四章——朴素贝叶斯及python实现

一、概述

本文是《统计学习方法》的第四章,包含朴素贝叶斯分类器的原理与python实现。希望自己能坚持下去,完成整本书的学习

二、朴素贝叶斯算法

由于我们需要学习的参数为 P ( x , y ) P(x,y) P(x,y),而 P ( X = x , Y = y ) = P ( X = x ∣ Y = y ) P ( Y = y ) P(X=x,Y=y)=P(X=x|Y=y)P(Y=y) P(X=x,Y=y)=P(X=xY=y)P(Y=y),其中 P ( X = x ∣ Y = y ) P(X=x|Y=y) P(X=xY=y)的参数是指数级的。当维度较大时,会发送维度灾难。
具体地说,X和Y的组合很多,假设 x j xj xj可能取值 S j Sj Sj个,Y可能取值有 K K K个,那么参数的个数是参数个数 K ∗ ∏ j = 0 n S j K*\prod_{j=0}^nSj Kj=0nSj。特别地,取 x j = S xj=S xj=S,那么参数个数为 K S n KS^n KSn,当维数 n n n很大的时候,就会发生维数灾难。

基于维度灾难的问题,朴素贝叶斯对特征作了独立性假设,即假设所有特征之间相互独立,不存在相关性:
在这里插入图片描述
也就是各个维度的特征在类确定的情况下都是独立分布的。这一假设简化了计算,也牺牲了一定的分类准确率。计算出每个类别的以上条件概率,选择条件概率最大的类别 C k Ck Ck作为分类器的预测值。

三、朴素贝叶斯的学习与分类

先从训练数据中计算先验概率和条件概率,然后对于给定的实例计算最大的条件概率,输出该条件对应的类别。书中的形式化的描述如下:
在这里插入图片描述
以上公式虽然较多,但实际原理其实较为简单,理解之后会发现原理非常通俗易懂。

不过,朴素贝叶斯会有一个问题,那就是当训练集中不存在某种参数与类别的组合时,会得出该条件概率为0,但是不能保证测试集中不存在这样的参数组合。解决办法是平滑概率为0的组合,此时采用贝叶斯估计进行平滑:

四、条件概率的贝叶斯估计:

在这里插入图片描述
其中, λ \lambda λ是介于0到1的平滑因子。当其值为0,等同于极大似然估计;当其值等于1,为拉普拉斯平滑。 S j Sj Sj X X X的取值个数。有了以上平滑方法,则可以解决因参数组合在训练集中不存在而造成的条件概率为0的情况了。下面,本文将参考《snownlp》,利用拉普拉斯平滑的朴素贝叶斯分类器完成一个情感分类器的建模。

五、python实现朴素贝叶斯情感分类器

下面使用python3来实现朴素贝叶斯情感分类器:

from math import log,exp
class LaplaceEstimate(object):
    def __init__(self):
        self.d={}
        self.total=0.0#全部词的词频
        self.none=1#当一个词不存在时,它的词频为拉普拉斯平滑后分子为一的数
    def exists(self,key):
        return key in self.d
    def getsum(self):
        return self.total
    def get(self,key):
        if not self.exists(key):
            return False,self.none
        return True,self.d[key]
    def getprob(self,key):
        return float(self.get(key)[1])/self.total
    def samples(self):
        return self.d.keys()
    def add(self,key,value):
        self.total+=value
        if not self.exists(key):
            self.d[key]=1
            self.total+=1
        self.d[key]+=value
class Bayes(object):
    def __init__(self):
        self.d={}#d存储词链表和标签
        self.total=0
    def train(self,data):
        for d in data:
            c=d[1]
            if c not in self.d:
                self.d[c]=LaplaceEstimate()
            for word in d[0]:
                self.d[c].add(word,1)
        self.total=sum(map(lambda x:self.d[x].getsum(),self.d.keys()))
    def classify(self,x):
        tmp={}
        for c in self.d:
            tmp[c]=log(self.d[c].getsum())-log(self.total)#P(Y=ck)
            for word in x:
                tmp[c]+=log(self.d[c].getprob(word))#P(Xj=xj|Y=ck)
        ret,prob=0,0
        for c in self.d:
            now=0
            try:
                for otherc in self.d:
                    now+=exp(tmp[otherc]-tmp[c])
                now=1/now
            except OverflowError:
                now=0
            if now>prob:
                ret,prob=c,now
        return (ret,prob)
class Sentiment(object):
    def __init__(self):
        self.classifier=Bayes()
    def segment(self,sent):
        words=sent.split(' ')
        return words
    def train(self,neg_docs,pos_docs):
        data=[]
        for sents in neg_docs:
            data.append([self.segment(sents),u'neg'])
        for sents in pos_docs:
            data.append([self.segment(sents),u'pos'])
        self.classifier.train(data)
    def classify(self,sent):
        return self.classifier.classify(self.segment(sent))
s=Sentiment()
s.train([u'糟糕', u'好 差劲'], [u'优秀', u'很 好']) 
print(s.classify(u'好 优秀'))

上述代码的输出如下:
在这里插入图片描述
可见,预测为积极的概率为0.667。朴素贝叶斯分类器得到了正确的答案。

五、总结

朴素贝叶斯是一种较为简单的分类器,其没有显示的学习过程,直接利用训练集的条件概率来进行建模,并对特征进行了独立性假设。这简化了计算,同时牺牲了一定的分类精度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
朴素叶斯算法是一种基于概率统计的分类算法,它的核心思想是利用叶斯定理计算出每个类别的后验概率,然后选择具有最大后验概率的类别作为分类结果。在这个过程中,朴素叶斯假设每个特征之间相互独立,也就是说,每个特征对于分类的贡献是独立的。 在Python中,我们可以使用scikit-learn库来实现朴素叶斯算法。具体步骤如下: 1.准备数据:将数据集划分为训练集和测试集。 2.训练模型:使用训练集来训练朴素叶斯模型。 3.测试模型:使用测试集来测试模型的准确率。 下面是一个简单的朴素叶斯分类器的实现示例: ``` from sklearn.naive_bayes import GaussianNB from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split # 加载数据集 iris = load_iris() # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.3, random_state=0) # 创建朴素叶斯分类器对象 gnb = GaussianNB() # 训练模型 gnb.fit(X_train, y_train) # 预测测试集的结果 y_pred = gnb.predict(X_test) # 计算准确率 accuracy = sum(y_pred == y_test) / len(y_test) print("准确率:", accuracy) ``` 这里使用了iris数据集作为示例数据集进行分类。首先,我们使用`train_test_split`函数将数据集划分为训练集和测试集,然后创建一个`GaussianNB`对象,训练模型并使用测试集来测试模型的准确率。最后,我们计算出准确率并将其打印出来。 完整的代码可以在以下链接中找到: https://github.com/Light-City/NaiveBayesClassifier-Python/blob/master/NaiveBayesClassifier.py

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值