模型: 基于特征条件独立的假设学习数据的联合概率分布作为预测的模型
策略: 利用贝叶斯定理求出后验概率最大的类别作为输出类别
算法: 极大似然估计 或 贝叶斯估计。
1.朴素贝叶斯(naive Bayes)法是基于 贝叶斯定理和特征条件独立假设的分类方法, 这些假设使得朴素贝叶斯变得简单, 但会牺牲一定的分类准确率。
过程: 对于给定的训练数据集,首先基于特征条件独立的假设学习数据的联合概率分布作为预测的模型,再对于给定的输入x,利用贝叶斯定理求出后验概率最大的类别作为输出的y,即类别值。
2.朴素贝叶斯法是典型的生成学习方法。
之所以称为生成学习方法: 是因为模型表示了给定输入X产生输出Y的生成关系。
生成方法由训练数据学习联合概率分布 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)
3.朴素贝叶斯法的基本假设是条件独立性,即如下:
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)
这是一个较强的假设。由于这一假设,模型包含的条件概率的数量大为减少,朴素贝叶斯法的学习与预测大为简化。因而朴素贝叶斯法高效,且易于实现。缺点是分类的性能不一定很高。
4.朴素贝叶斯法利用贝叶斯定理与学到的联合概率模型进行分类预测。即得到后验概率:
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。
将后验概率最大的类作为x的类输出,并且由于分母对结果的变化无影响,故略去分母,故后验概率最大等价于分子最大,如下:
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损失函数时的期望风险最小化。
5.实现朴素贝叶斯基础模型: 高斯模型,多项式模型,伯努利模型…
属性之间不相互独立不能使用。
如果属性A和属性B都很重要,但是相关,也不能使用。
如果属性A和属性B相互独立,但是在属性C下有关,也不能使用。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import math
#获取iris数据集的数据
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']
#获取前100行数据,注意转换成np.array数组形式
data = np.array(df.iloc[:100,:])
#分离 前100行的特征数据和标签数据
return data[:,:-1],data[:,-1]
#获取数据
X,y = create_data()
#随机划分训练集和测试集(测试集占比0.3)
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3)
#print(len(X_train),len(X_test))
#print(*X_train)
"""
朴素贝叶斯模型有: 高斯模型,多项式模型,伯努利模型
------------------------------------------------
这里以 高斯模型的朴素贝叶斯为例
"""
# Naive-Bayes (高斯模型,正态分布)
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):
"""
在python中,*是’splat’运算符.它用于将列表解压缩为参数.
例如:foo(* [1、2、3])与foo(1、2、3)相同
注意: 只去掉 外层一层
"""
#这里对训练数据的处理是: 求出数据集中 每个样本点的特征数据的均值和标准差,组成一个关于样本点(均值,标准差)的列表
summaries = [(self.mean(i),self.stdev(i)) for i in zip(*train_data)]
#返回数据集的样本点的(均值,标准差)元组列表
return summaries
#分别求出数学期望和标准差
def fit(self,X,y):
#set用于标签数据去重,再将去重后的结果转换为列表
labels = list(set(y)) # [1,0]
#定义 字典,列表中存储对应类别的点的 特征数据
data = {label:[] for label in labels}# {1: [], 0: []}
#给 字典中的1/0列表 添加实例点的特征数据, 即完成对实例点的类别分类
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_probability(self,input_data):
#存储概率的字典
probabilities = {}
for label,value in self.model.items():
#由于对实例点已完成分类,故设置其 先验概率均为1
probabilities[label] = 1
for i in range(len(value)):
#提取出实例点的特征数据的 均值和标准差
mean,stdev = value[i]
#计算 后验概率
probabilities[label] *= self.gaussian_probability(input_data[i],mean,stdev)
#返回概率字典
#print(probabilities)
return probabilities
#给出输入示例的类别,即后验概率最大的类别
def predict(self,X_test):
#排序(默认按升序排列),选出概率最大的类别
label = sorted(self.calculate_probability(X_test).items(),key=lambda x:x[-1])[-1][0]
#返回最终分类的类别
return label
#模型对测试集的测试得分
def score(self,X_test,y_test):
#初始化分类正确为0个点
right = 0
for X,y in zip(X_test,y_test):
label = self.predict(X)
#分类正确,则分类正确的点数+1
if label==y:
right += 1
#返回测试集中分类正确的点所占的比例
return right/float(len(X_test))
#实例化Naive-Bayes对象模型
model = NaiveBayes()
#训练模型
print(model.fit(X_train, y_train))
print(model.predict([4.4, 3.2, 1.3, 0.2]))
#print(model.score(X_test, y_test))
"""
朴素贝叶斯模型有: 高斯模型,多项式模型,伯努利模型
from sklearn.naive_bayes import BernoulliNB, MultinomialNB # 伯努利模型和多项式模型
------------------------------------------------
这里以 高斯模型的朴素贝叶斯为例
"""
#从sklearn的朴素贝叶斯中导入 高斯朴素贝叶斯模型
from sklearn.naive_bayes import GaussianNB
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
#获取iris数据集的数据
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=0.3)
#print(len(X_train),len(X_test))
#实例化高斯朴素贝叶斯模型
model = GaussianNB()
model.fit(X_train, y_train)
#测试
print(model.score(X_test, y_test))
print(model.predict([[4.4, 3.2, 1.3, 0.2]]))
The End!!创作不易,欢迎点赞/评论!!欢迎关注个人公众号