第4章 朴素贝叶斯
引言
在众多机器学习分类算法中,本篇我们提到的朴素贝叶斯模型,和其他绝大多数分类算法都不同,也是很重要的模型之一。
在众多机器学习的分类算法中,朴素贝叶斯模型以其独特的方法和重要性,与其他算法显著不同。相对于KNN、逻辑回归、决策树等判别方法,这些算法直接学习输入特征X与输出Y之间的直接关系(决策函数 Y=f(x) 或者条件分布 P(Y∣X) ),朴素贝叶斯模型则采用了生成方法。它直接找出特征输出Y和特征 X的联合分布 P(X,Y) ,进而通过
P(Y∣X)=P(X)P(X,Y)
计算得出结果判定。
朴素贝叶斯算法原理
贝叶斯定理
贝叶斯理论是以18世纪的一位神学家托马斯.贝叶斯(Thomas Bayes)命名。通常,事件A在事件B (发生) 的条件下的概率,与事件B在事件A (发生) 的条件下的概率是不一样的。然而,这两者是有确定的关系的,贝叶斯定理就是这种关系的陈述。
P(A∣B)=P(B)P(B∣A)P(A)
- 条件概率:就是事件 A 在另外一个事件 B 已经发生条件下的发生概率。条件概率表示为 P(A∣B) ,即在 B 发生的条件下 A 发生的概率。
- 联合概率:表示两个事件共同发生(数学概念上的交集)的概率。 A 与 B 的联合概率表示为联合概率。联合概率表示为 P(AB)
P(AB)=P(A∣B)P(B)=P(B∣A)P(A), 若 AB 相互独立, 则P(AB)=P(A)P(B)
- 全概率公式: P(X)=k∑P(X∣Y=Yk)P(Yk), 其中 k∑P(Yk)=1
朴素贝叶斯
朴素贝叶斯方法是基于贝叶斯定理和特征条件独立假设的分类方法。
这是一个较强的假设。由于这一假设,模型包含的条件概率的数量大为减少,朴素贝叶斯法的学习与预测大为简化。因而朴素贝叶斯法高效,且易于实现。其缺点是分类的性能不一定很高。
对于给定的训练数据集:
- 首先基于特征条件独立假设学习输入 / 输出的联合概率分布
- 然后基于此模型,对给定的输入 x ,利用贝叶斯定理求出后验概率最大的输出 y :
P(X=x∣Y=ck)=P(X(1)=x(1),⋯,X(n)=x(n)∣Y=ck)=j=1∏nP(X(j)=x(j)∣Y=ck)(1)
原理
朴素贝叶斯方法属于生成模型的范畴。在给定输入 x 的情况下,这种方法通过已学习的模型计算后验概率分布 P(Y=ck∣X=x) 。它选择后验概率最高的类别 $c_k $ 作为输入 $x $ 的预测分类。其中后验概率的计算基于贝叶斯定理进行
P(Y=ck∣X=x)=k∑P(X=x∣Y=ck)P(Y=ck)P(X=x∣Y=ck)P(Y=ck)(2)
将式(1)代入式(2),有
P(Y=ck∣X=x)=k∑P(Y=ck)j∏P(X(j)=x(j)∣Y=ck)P(Y=ck)j∏P(X(j)=x(j)∣Y=ck),k=1,2,⋯,K(3)
这是朴素贝叶斯法分类的基本公式。于是, 朴素贝叶斯分类器可表示为
y=f(x)=argckmaxk∑P(Y=ck)j∏P(X(j)=x(j)∣Y=ck)P(Y=ck)j∏P(X(j)=x(j)∣Y=ck)(4)
注意到, 在式 (4) 中分母对所有 ck 都是相同的,所以
y=argckmaxP(Y=ck)j∏P(X(j)=x(j)∣Y=ck)(5)
后验概率最大化的含义
朴素贝叶斯法将实例分到后验概率最大的类中, 这等价于期望风险最小化。假设选择 0-1 损失函数:
L(Y,f(X))={1,0,Y=f(X)Y=f(X)(6)
式中 f(X) 是分类决策函数。这时,期望风险函数为
Rexp(f)=E[L(Y,f(X))](7)
期望是对联合分布 P(X,Y) 取的。由此取条件期望
Rexp(f)=EXk=1∑K[L(ck,f(X))]P(ck∣X)(8)
为了使期望风险最小化, 只需对 X=x 逐个极小化, 由此得到:
f(x)=argy∈Ymink=1∑KL(ck,y)P(ck∣X=x)=argy∈Ymink=1∑KP(y=ck∣X=x)=argy∈Ymin(1−P(y=ck∣X=x))=argy∈YmaxP(y=ck∣X=x)(9)
这样一来, 根据期望风险最小化准则就得到了后验概率最大化准则:
f(x)=argckmaxP(ck∣X=x)(10)
即朴素贝叶斯法所采用的原理。
极大似然估计
在朴素贝叶斯法中,学习意味着估计 P(Y=ck) 和 P(X(j)=x(j)∣Y=ck) 。可以应用极大似然估计法估计相应的概率。先验概率 P(Y=ck) 的极大似然估计是
P(Y=ck)=Ni=1∑NI(yi=ck),k=1,2,⋯,K(11)
设第 j 个特征 x(j) 可能取值的集合为 {aj1,aj2,⋯,ajSj},条件概率 P(X(j)=ajl∣Y=ck)的极大似然估计是
P(X(j)=ajl∣Y=ck)=i=1∑NI(yi=ck)i=1∑NI(xi(j)=ajl,yi=ck),j=1,2,⋯,n,l=1,2,⋯,Sj,k=1,2,⋯,K(12)
式中, xi(j) 是第 i 个样本的第 j 个特征; ajl 是第 j 个特征可能取的第 l 个值; I 为指示函数。
创建训练集和测试集
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
|
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, :]) return data[:, :-1], data[:, -1]
|
X, y = create_data() X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3) X_test[0], y_test[0]
|
Output[ ]
(array([6.6, 2.9, 4.6, 1.3]), 1.0)
|
-
高斯模型
GaussianNB 高斯朴素贝叶斯
特征的可能性被假设为高斯概率密度函数:
P(xi∣yk)=2πσyk21exp(−2σyk2(xi−μyk)2)(13)
数学期望: μ
方差: σ2=N∑(X−μ)2
实现一个朴素贝叶斯分类器
class NaiveBayes: 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([pow(x - avg, 2) for x in X]) / float(len(X)))
def gaussian_probability(self, x, mean, stdev): exponent = math.exp(-(math.pow(x - mean, 2) / (2 * math.pow(stdev, 2)))) return (1 / (math.sqrt(2 * math.pi) * stdev)) * exponent
def summarize(self, train_data): summaries = [(self.mean(i), self.stdev(i)) for i in zip(*train_data)] return summaries
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.summarize(value) for label, value in data.items() } return 'gaussianNB train done!'
def calculate_probabilities(self, input_data): probabilities = {} for label, value in self.model.items(): probabilities[label] = 1 for i in range(len(value)): mean, stdev = value[i] probabilities[label] *= self.gaussian_probability( input_data[i], mean, stdev) return probabilities
def predict(self, X_test): label = sorted( self.calculate_probabilities(X_test).items(), key=lambda x: x[-1])[-1][0] return label
def score(self, X_test, y_test): right = 0 for X, y in zip(X_test, y_test): label = self.predict(X) if label == y: right += 1
return right / float(len(X_test))
|
model = NaiveBayes() model.fit(X_train, y_train)
|
Output[ ]
print(model.predict([4.4, 3.2, 1.3, 0.2]))
|
Output[ ]
model.score(X_test, y_test)
|
Output[ ]
scikit-learn实例
from sklearn.naive_bayes import GaussianNB clf = GaussianNB() clf.fit(X_train, y_train)
|
clf.score(X_test, y_test)
|
Output[ ]
clf.predict([[4.4, 3.2, 1.3, 0.2]])
|
Output[ ]
而scikit-learn中的伯努利模型和多项式模型
from sklearn.naive_bayes import BernoulliNB, MultinomialNB
|
第4章朴素贝叶斯法-习题
1.用极大似然估计法推出朴素贝叶斯法中的概率估计公式(11)及公式 (12)。
解答:
**第1步:**证明公式(11):P(Y=ck)=Ni=1∑NI(yi=ck)
由于朴素贝叶斯法假设Y是定义在输出空间Y上的随机变量,因此可以定义P(Y=ck)概率为p。
令m=i=1∑NI(yi=ck),得出似然函数:
L(p)=fD(y1,y2,⋯,yn∣θ)=(mN)pm(1−p)(N−m)
使用微分求极值,两边同时对p求微分:
0=(mN)[mp(m−1)(1−p)(N−m)−(N−m)pm(1−p)(N−m−1)]=(mN)[p(m−1)(1−p)(N−m−1)(m−Np)]
可求解得到:
p=0,p=1,p=Nm
显然
P(Y=ck)=p=Nm=Ni=1∑NI(yi=ck)
公式(11)得证。
**第2步:**证明公式(11):
P(X(j)=ajl∣Y=ck)=i=1∑NI(yi=ck)i=1∑NI(xi(j)=ajl,yi=ck)
令
P(X(j)=ajl∣Y=ck)=p
m=i=1∑NI(yi=ck),q=i=1∑NI(xi(j)=ajl,yi=ck)
得出似然函数:
L(p)=(qm)pq(i−p)m−q
使用微分求极值,两边同时对p求微分:
0=(qm)[qp(q−1)(1−p)(m−q)−(m−q)pq(1−p)(m−q−1)]=(qm)[p(q−1)(1−p)(m−q−1)(q−mp)]
可求解得到
p=0,p=1,p=mq
显然
P(X(j)=ajl∣Y=ck)=p=mq=i=1∑NI(yi=ck)i=1∑NI(xi(j)=ajl,yi=ck)
公式(12)得证。