朴素贝叶斯算法
相关重点处:https://blog.csdn.net/xiaoyoupei/article/details/122641753
贝叶斯思想,其实就是计算出条件概率(也就是某条件情况下,导致的结果的概率,选择概率大的)
-
贝叶斯定理中必要知道什么是先验概率和后验概率。
-
什么是先验概率和后验概率?举个例子:
- 假设我们出门堵车的可能因素有两个:车辆太多和交通事故。
- 先验概率:
- 堵车的概率就是先验概率(不管有没有其他事件的发生造成的堵车)
- 后验概率/条件概率:
- 当准备出门前,听到新闻里说路上发生了交通事故,那现在计算在发生事故后堵车的概率就是后验概率。也就是P(堵车|交通事故)。这是有因求果。
-
那必然有一个条件概率的公式,在A事件发生下,B事件发生的概率:P(B|A) = P(AnB) / P(A),这其实很好理解,用面积的知识,发生A事件的概率面积作为分母,A和B相交的事件概率作为分子,这就求出了A事件发生情况下,B事件发生的概率
-
下面这个公式很好推导,也就是
P(B|A) = P(AnB) / P(A)
和P(A|B) = P(BnA) / P(B)
,就可算得
- 朴素贝叶斯分类算法核心就是上述理论公式转换如下,注意这个式子是需要
假设各个特征之间相互独立
,特征之间不会产生影响
sklearn主流的应用贝叶斯的计算算法是:1、高斯模型(针对连续型数据)2、多项式模型(针对离散型数据)
高斯模型
-
高斯模型
-
通过假设P(xi|Y)是服从高斯分布(也就是正态分布),来估计训练集数据的每个样本特征分到每个类别Y上的条件概率。对于每个样本特征下的对应每个分类结果概率的取值,高斯朴素贝叶斯有如下公式:
-
exp函数为高等数学里以自然常数e为底的指数函数
- 对于任意一个Y的取值,高斯函数都以求解最大化的P为目标,这样我们才能够比较在不同标签下我们的样本究竟更靠近哪一个取值。
-
-
高斯模型API
-
from sklearn.naive_bayes import GaussianNB
-
实例化模型对象的时候,我们不需要对高斯朴素贝叶斯类输入任何的参数,可以说是一个非常轻量级的类,操作非常容易。但过于简单也意味着贝叶斯没有太多的参数可以调整,因此贝叶斯算法的成长空间并不是太大,如果贝叶斯算法的效果不是太理想,我们一般都会考虑换模型。
-
方法说明:
predict_proba(): 给出每一个测试集样本属于每个类别的概率,最大的就是分类结果
predict_log_proba(): predict_proba的对数转化,最大的就是分类结果
-
-
# 鸢尾花案例,结果为三类
import sklearn.datasets as datasets
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
iris = datasets.load_iris()
feature = iris['data']
target = iris['target']
x_train,x_test,y_train,y_test = train_test_split(feature,target,test_size=0.2,random_state=2021)
model = GaussianNB()
model.fit(x_train,y_train) #求解高斯函数中的均值和标准差
#查看样本分到不同类别的概率
model.predict_proba(x_test[20].reshape((1,-1))) # array([[1.17467276e-110, 9.96533910e-001, 3.46608965e-003]])
model.predict_log_proba(x_test[20].reshape((1,-1))) # array([[-2.53123371e+02, -3.47211045e-03, -5.66472822e+00]])
model.score(x_test,y_test) # 0.9333333333333333
多项式模型
- 与高斯分布相反,多项式模型主要适用于离散特征的概率计算,且sklearn的多项式模型不接受输入负值。虽然sk-learn中的多项式模型也可以被用作在连续性特征概率计算中,但是我们如果想要处理连续性变量则最好选择使用高斯模型。
- 注意:因为多项式不接受负值的输入,所以如果样本数据的特征为数值型数据的话,务必要进行归一化处理保证特征数据中无负值出现!!!
特征(文章中出现的词) | 科技(30篇) | 娱乐(60篇) | 汇总(90篇) |
---|---|---|---|
商城 | 9 | 51 | 60 |
影院 | 8 | 56 | 64 |
支付宝 | 20 | 15 | 35 |
云计算 | 63 | 0 | 63 |
汇总 | 100 | 121 | 221 |
现有一个要预测的文档(出现了影院、支付宝、云计算)属于哪个类型?
避免为0,这里我们要使其平滑,常用的方法就是拉普拉斯修正
,分子加1,分母为N,N表示该分类情况下该属性的次数
-
多项式朴素贝叶斯API
- from sklearn.naive_bayes import MultinomialNB
- MultinomialNB(alpha=1.0, fit_prior=True, class_prior=None)
- alpha:拉普拉斯平滑系数
-
sklearn文本特征提取——TfidfVectorizer(求出Ni/N的值)
- 什么是TF-IDF
- 在信息检索中,tf-idf(词频-逆文档频率)是一种统计方法,用以评估一个单词在一个文档集合或语料库中的重要程度。
- 原理:
- TF-IDF实际上是:TF * IDF。主要思想是:如果某个词或短语在一篇文章中出现的频率高(即TF高),并且在其他文章中很少出现(即IDF高),则认为此词或者短语具有很好的类别区分能力,适合用来分类。
- TF:表示一个给定词语t在一篇给定文档d中出现的频率。TF越高,则词语t对文档d来说越重要,TF越低,则词语t对文档d来说越不重要。那是否可以以TF作为文本相似度评价标准呢?答案是不行的,举个例子,常用的中文词语如“我”,“了”,“是”等,在给定的一篇中文文档中出现的频率是很高的,但这些中文词几乎在每篇文档中都具有非常高的词频,如果以TF作为文本相似度评价标准,那么几乎每篇文档都能被命中。
- TF(w)=(词w在文档中出现的次数)/(文档的总词数) == P(F1|C)=Ni/N
- IDF:逆向文章频率。有些词可能在文本中频繁出现,但并不重要,也即信息量小,如is,of,that这些单词或者“我”,“了”,“是”等,这些单词在语料库中出现的频率也非常大,我们就可以利用这点,降低其权重。
- 什么是TF-IDF
from sklearn.naive_bayes import MultinomialNB
nb = MultinomialNB()
import sklearn.datasets as datasets
data = datasets.fetch_20newsgroups(data_home='./datasets',subset='all')
#基于TF-IDF进行特征值化
from sklearn.feature_extraction.text import TfidfVectorizer
tf = TfidfVectorizer()
n_feature = tf.fit_transform(feature)
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(n_feature,target,test_size=0.1,random_state=2021)
nb = MultinomialNB()
nb.fit(x_train,y_train)
nb.score(x_test,y_test) # 0.8440318302387267