假设你正在处理一个分类问题,你已经形成了一些假设,建立了一套特征并且确定了各变量的重要性。你的数据集中有一大堆数据点,但是只有很少的变量,而你的上司希望你能在一小时内给出预测数据,你会怎么办?
如果我是你,我会用朴素贝叶斯分类器。相比较其他分类方法,朴素贝叶斯简单高效,适合预测未知类数据集。
在这篇文章中,我将解释该算法的基础知识,如果你是Python和R语言的新手,下次你遇到大型数据集,你就能学以致用。
什么是朴素贝叶斯算法?
朴素贝叶斯分类器是一种基于贝叶斯定理的弱分类器,所有朴素贝叶斯分类器都假定样本每个特征与其他特征都不相关。举个例子,如果一种水果其具有红,圆,直径大概3英寸等特征,该水果可以被判定为是苹果。尽管这些特征相互依赖或者有些特征由其他特征决定,然而朴素贝叶斯分类器认为这些属性在判定该水果是否为苹果的概率分布上独立的。
朴素贝叶斯分类器很容易建立,特别适合用于大型数据集,众所周知,这是一种胜过许多复杂算法的高效分类方法。
贝叶斯公式提供了计算后验概率P(X|Y)的方式:
朴素贝叶斯算法的分类流程
让我举一个例子。下面我设计了一个天气和响应目标变量“玩”的训练数据集(计算“玩”的可能性)。我们需要根据天气条件进行分类,判断这个人能不能出去玩,以下是步骤:
步骤1:将数据集转换成频率表;
步骤2:计算不同天气出去玩的概率,并创建似然表,如阴天的概率是0.29;
步骤3:使用贝叶斯公式计算每一类的后验概率,数据最高那栏就是预测的结果。
问题:如果是晴天,这个人就能出去玩。这个说法是不是正确的?
P(是|晴朗)=P(晴朗|是)×P(是)/P(晴朗)
在这里,P(晴朗|是)= 3/9 = 0.33,P(晴朗)= 5/14 = 0.36,P(是)= 9/14 = 0.64
现在,P(是|晴朗)=0.33×0.64/0.36=0.60,具有较高的概率。
朴素贝叶斯适合预测基于各属性的不同类的概率,因此在文本分类上有广泛应用。
朴素贝叶斯的优缺点
-
如果分类变量的类别(测试数据集)没有在训练数据集总被观察到,那这个模型会分配一个0(零)概率给它,同时也会无法进行预测。这通常被称为“零频率”。为了解决这个问题,我们可以使用平滑技术,拉普拉斯估计是其中最基础的技术。
-
朴素贝叶斯也被称为bad estimator,所以它的概率输出predict_proba不应被太认真对待。
-
朴素贝叶斯的另一个限制是独立预测的假设。在现实生活中,这几乎是不可能的,各变量间或多或少都会存在相互影响。
朴素贝叶斯的4种应用
实时预测
:毫无疑问,朴素贝叶斯很快。
多类预测
:这个算法以多类别预测功能闻名,因此可以用来预测多类目标变量的概率。
文本分类/垃圾邮件过滤/情感分析
:相比较其他算法,朴素贝叶斯的应用主要集中在文本分类(变量类型多,且更独立),具有较高的成功率。因此被广泛应用于垃圾邮件过滤(识别垃圾邮件)和情感分析(在社交媒体平台分辨积极情绪和消极情绪的用户)。
推荐系统
:朴素贝叶斯分类器和协同过滤结合使用可以过滤出用户想看到的和不想看到的东西。
如何建立朴素贝叶斯的基本模型(Python和R)
scikit learn里有3种朴素贝叶斯的模型:
高斯模型
:适用于多个类型变量,假设特征符合高斯分布。
多项式模型
:用于离散计数。如一个句子中某个词语重复出现,我们视它们每个都是独立的,所以统计多次,概率指数上出现了次方。
伯努利模型
:如果特征向量是二进制(即0和1),那这个模型是非常有用的。不同于多项式,伯努利把出现多次的词语视为只出现一次,更加简单方便。
你可以根据特定数据集选取上述3个模型中的合适模型。下面我们以高斯模型为例,谈谈怎么建立:
-
#Import Library of Gaussian Naive Bayes model
-
from sklearn.naive_bayes import GaussianNB
-
import numpy as np
-
-
#assigning predictor and target variables
-
x= np.array([[-3,7],[1,5], [1,2], [-2,0], [2,3], [-4,0], [-1,1], [1,1], [-2,2], [2,7], [-4,1], [-2,7]])
-
Y = np.array([3, 3, 3, 3, 4, 3, 3, 4, 3, 4, 4, 4])
-
-
#Create a Gaussian Classifier
-
model = GaussianNB()
-
-
# Train the model using the training sets
-
model.fit(x, y)
-
-
#Predict Output
-
predicted= model.predict([[1,2],[3,4]])
-
print predicted
-
-
Output: ([3,4])
关于朴素贝叶斯分类器的几个黑科技
以下是一些小方法,可以提升朴素贝叶斯分类器的性能:
-
如果连续特征不是正态分布的,我们应该使用各种不同的方法将其转换正态分布。
-
如果测试数据集具有“零频率”的问题,应用平滑技术“拉普拉斯估计”修正数据集。
-
删除重复出现的高度相关的特征,可能会丢失频率信息,影响效果。
-
朴素贝叶斯分类在参数调整上选择有限。我建议把重点放在数据的预处理和特征选择。
-
大家可能想应用一些分类组合技术 如ensembling、bagging和boosting,但这些方法都于事无补。因为它们的目的是为了减少差异,朴素贝叶斯没有需要最小化的差异。
感谢你耐心读到了这里,如果已经了解了文章内容,接下来你需要的是实践。在使用朴素贝叶斯分类器前,希望你能在数据预处理和特征选择上多花一些精力。
假设你正在处理一个分类问题,你已经形成了一些假设,建立了一套特征并且确定了各变量的重要性。你的数据集中有一大堆数据点,但是只有很少的变量,而你的上司希望你能在一小时内给出预测数据,你会怎么办?如果我是你,我会用朴素贝叶斯分类器。相比较其他分类方法,朴素贝叶斯简单高效,适合预测未知类数据集。在这篇文章中,我将解释该算法的基础知识,如果你是Python和R语言的新手,下次你遇到大型数据集,你就...
贝叶斯公式可以把求解后验概率的问题转化为求解先验概率的问题,一般情况下后验概率问题 难以求解。例如;一封邮件是垃圾邮件的概率。通过贝叶斯公式可以把这个难解的问题转化为;计算垃圾邮件们各种特征出现的概率以及垃圾邮件出现的概率。因此
朴素贝叶斯
可以通过对已经掌握的“经验”(数据)的学习来预测一个很有价值的
分类
结果。
引入独立性假设
分类器
最终的输出;选择最大概率的
分类
作为预测结果。
Python
实现
导入所需包
import numpy as np
import pandas as pd
import
本文实例讲述了
Python
实现的
朴素贝叶斯
分类器
。分享给大家供大家参考,具体如下:
因工作中需要,自己写了一个
朴素贝叶斯
分类器
。
对于未出现的属性,采取了拉普拉斯平滑,避免未出现的属性的概率为零导致整个条件概率都为零的情况出现。
朴素贝叶斯
的基本原理网上很容易查到,这里不再叙述,直接附上
代码
因工作中需要,自己写了一个
朴素贝叶斯
分类器
。对于未出现的属性,采取了拉普拉斯平滑,避免未出现的属性的概率为零导致整个条件概率都为零的情况出现。
class NBClassify(object):
def __init__(self, fillNa = 1):
self.fillNa = 1
核心思想:需要得到的参数是一个确定的值,虽然未知,但是不会因为样本的变化而变化,样本数据随机产生的,因此在数据样本无限大时,其计算出来的频率即为概率。其重点主要在于研究样本空间,分析样本的分布
延展应用:最大似然估计(MLE)
贝叶斯学派
核心思想:需要得到的参数是随机变量,而样本则是固定的,其重点主要在于研究参数的分布。
由于在贝叶斯
朴素贝叶斯
分类器
(附
代码
)
原文还包
含
一定的理论基础我没复制过来,我只在
代码
基础上加了注释。注释比较基础也比较
详细
,我也是初学因此该注释为小白学习自用,有错误敬请指出。
import math
import random
all_num = 0 # 样本总数
cla_num = {} # 字典,
分类
的集合,里面是类别
cla_tag_num = {} # 字典,
分类
的集合,里面元素还有字典
landa = 0.6 # 拉普拉斯修正值
# tag:某个特征
# feature
file=open(fname)
data=xlrd.open_workbook(fname) #将表格的内容进行读取
dataname=data.sheet_names() #生成的是一个列表
#shxrange=range...
# 导入需要的库
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import CountVectorizer
# 定义训练数据
# 这里的数据是一些短文本,每个文本都属于一个类别
# 每个文本用一个字符串表示
train_data = [
('这是一篇关于科学的文章', '科技'),
('这是一篇关于体育的文章', '体育'),
('这是一篇关于娱乐的文章', '娱乐')
# 将文本转换为数值特征
vectorizer = CountVectorizer()
X_train = vectorizer.fit_transform([text for text, _ in train_data])
# 将类别转换为数值
# 使用 sklearn 的 LabelEncoder 可以很方便地将类别转换为数值
from sklearn.preprocessing import LabelEncoder
label_encoder = LabelEncoder()
y_train = label_encoder.fit_transform([label for _, label in train_data])
# 创建
朴素贝叶斯
分类器
并训练
classifier = MultinomialNB()
classifier.fit(X_train, y_train)
# 对新的文本进行
分类
# 首先将新的文本转换为数值特征
X_test = vectorizer.transform(['这是一篇关于体育的文章'])
# 使用训练好的
分类器
进行预测
prediction = classifier.predict(X_test)
# 将预测结果转换为类别
predicted_label = label_encoder.inverse_transform(prediction)
print(predicted_label) # 输出 ['体育']