1.朴素贝叶斯法是典型的生成学习方法。生成方法由训练数据学习联合概率分布 P ( X , Y ) P(X,Y) P(X,Y),然后求得后验概率分布 P ( Y ∣ X ) P(Y|X) P(Y∣X)。具体来说,利用训练数据学习 P ( X ∣ Y ) P(X|Y) P(X∣Y)和 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(X∣Y)
概率估计方法可以是极大似然估计或贝叶斯估计。
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=x∣Y=ck)=P(X(1)=x(1),⋯,X(n)=x(n)∣Y=ck)=j=1∏nP(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(Y∣X)=P(X)P(X,Y)=∑YP(Y)P(X∣Y)P(Y)P(X∣Y)
将输入 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=1∏nP(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(xi∣yk)=2πσyk21exp(−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)=ajl∣Y=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)=ajl∣Y=ck)=pX(j)+(1−p)(1−X(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)=ajl∣Y=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)