统计学习方法--朴素贝叶斯法
使用《统计学习方法》进行学习,仅需要学习资料的小伙伴可直接跳转至文章最下方。(注:只有第4章--朴素贝叶斯法部分,使用jupyter notebook打开,代码已通过测试,后续章节请追随更新)
补充:对于统计学习方法的第一章节的部分概念和数学公式已放置到文章最下方,需要的朋友可直接下滑到最下方下载
与CSDN同步更新,csdn ID:三维虫子
朴素贝叶斯法的学习与分类
基本方法
后验概率最大化的含义
朴素贝叶斯法的参数估计
极大似然估计
学习与分类算法
贝叶斯估计
代码部分
数据准备
GaussianNB高斯朴素贝叶斯
scikit-learn实例
第4章朴素贝叶斯法-习题
习题4.1
习题4.2
朴素贝叶斯(naïve Bayes) 法是基于贝叶斯定理与特征条件独立假设的分类方法。
朴素贝叶斯法与贝叶斯估计(Bayesian estimation) 是不同的概念。
对于给定的训练数据集,首先基于特征条件独立假设学习输入输出的联合概率分布:然后基于此模型,对给定的输入x,利用贝叶斯定理求出后验概率最大的输出y。
事情还没有发生,要求这件事情发生的可能性的大小,是先验概率。事情已经发生,要求这件事情发生的原因是由某个因素引起的可能性的大小,是后验概率。贝叶斯公式:
公式中,事件 的概率为 ,事件 已发生条件下事件 的概率为 ,事件 发生条件下事件 的概率为
朴素贝叶斯法的学习与分类
基本方法
设输入空间 为 维向量的集合,输出空间为类标记集合 。输入为特征向量 ,输出为类标记(class label) 。 是定义在输入空间 上的随机向量, 是定义在输出空间 上的随机变量。 是 和 的联合概率分布。训练数据集:
由 独立同分布产生。
朴素贝叶斯法通过训练数据集学习联合概率分布 。具体地,学习以下先验概率分布及条件概率分布。先验概率分布(4.1)
条件概率分布(4.2)
于是学习到联合概率分布 。
条件概率分布 有指数级数量的参数,其估计实际是不可行的。事实上,假设 可取值有 个, , 可取值有 个,那么参数个数为 。
朴素贝叶斯法对条件概率分布作了条件独立性的假设。由于这是一个较强的假设,朴素贝叶斯法也由此得名。具体地,条件独立性假设是(4.3)
朴素贝叶斯法实际上学习到生成数据的机制,所以属于生成模型。条件独立假设等于是说用于分类的特征在类确定的条件下都是条件独立的。这一假设使朴素贝叶斯法变得简单,但有时会牺牲一定的分类准确率。
朴素贝叶斯法分类时,对给定的输入 ,通过学习到的模型计算后验概率分布 , 将后验概率最大的类作为 的类输出。后验概率计算根据贝叶斯定理进行(4.4):
将式(4.3) 代入式(4.4) ,有(4.5)
这是朴素贝叶斯法分类的基本公式。于是, 朴素贝叶斯分类器可表示为(4.6)
注意到,在式(4.6) 中分母对所有 都是相同的,所以(4.7)
后验概率最大化的含义
朴素贝叶斯法将实例分到后验概率最大的类中。这等价于期望风险最小化。假设选择0-1 损失函数:
式中 是分类决策函数。这时,期望风险函数为
期望是对联合分布 取的。由此取条件期望
为了使期望风险最小化,只需对 逐个极小化,由此得到:
这样一来,根据期望风险最小化准则就得到了后验概率最大化准则:
即朴素贝叶斯法所采用的原理。相关理解:https://blog.csdn.net/rea_utopia/article/details/78881415
朴素贝叶斯法的参数估计
极大似然估计
在朴素贝叶斯法中,学习意味着估计 和 。可以应用极大似然估计法估计相应的概率。先验概率 的极大似然估计是(4.8)
设第 个特征 可能取值的集合为 ,条件概率 的极大似然估计是(4.9)
式中,
是第
个样本的第
个特征;
是第
个特征可能取的第
个值;
为指示函数。
指示函数:当
时
(不想等时为0),然后求和统计个数
学习与分类算法
算法4. 1 ( 朴素贝叶斯算法( naïve Bayes algorithm) )
输入:训练数据,其中是
个样本的第
个特征,是第
个特征可能取的第
个值,;实例
;
输出:实例
的分类。
(1)计算先验概率及条件概率
(2)对于给定的实例 ,计算
(3)确定实例 的类
例4.1 试由表4.1的训练数据学习一个朴素贝叶斯分类器并确定
的类标记
。表中
为特征,取值的集合分别为为类标记,
解 根据算法4.1,由表4.1,容易计算下列概率:对于给定的
计算:因为最大,所以
。
贝叶斯估计
用极大似然估计可能会出现所要估计的概率值为0 的情况。这时会影响到后验概率的计算结果,使分类产生偏差。解决这一问题的方法是采用贝叶斯估计。具体地,条件概率的贝叶斯估计是式中 。等价于在随机变量各个取值的频数上赋予一个正数 。当 时就是极大似然估计。常取 ,这时称为拉普拉斯平滑(Laplacian smoothing) 。显然,对任何 ,有
表明式(4.10) 确为一种概率分布。同样,先验概率的贝叶斯估计是例4.2 问题同例4.1,按照拉普拉斯平滑估计概率,即取
。
解 。按照式(4.10) 和式(4.11) 计算下列概率:对于给定的
,计算:由于最大,所以
。
代码部分
参考:https://machinelearningmastery.com/naive-bayes-classifier-scratch-python/
数据准备
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[:6])
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]
模型:
-
高斯模型 -
多项式模型 -
伯努利模型
GaussianNB高斯朴素贝叶斯
特征的可能性被假设为高斯概率密度函数(正态分布):
数学期望(mean):
方差:
class NaiveBayes:
def __init__(self):
self.model = None
# 数学期望;正态分布的期望、均数、中位数、众数相同,均等于μ
@staticmethod # @staticmethod: https://blog.csdn.net/polyhedronx/article/details/81911548
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
# 处理X_train
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) # data={(y:x),...}
self.model = {
label: self .summarize(value) # label: self .summarize(value)={(y:期望,标准差),...}
for label, value in data.items()
}
return 'gaussianNB train done!'
# 计算概率
def calculate_probabilities(self, input_data):
# summaries:{0.0: [(5.0, 0.37),(3.42, 0.40)], 1.0: [(5.8, 0.449),(2.7, 0.27)]}
# input_data:[1.1, 2.2]
probabilities = {}
for label, value in self.model.items():
probabilities[label] = 1 # {(y1:1),(y2:1)...}
for i in range(len(value)):
mean, stdev = value[i]
# x_test使用训练集的期望和标准差,计算其在相对于的y中的概率
probabilities[label] *= self.gaussian_probability( # {(y1:概率),(y2:概率)...}
input_data[i], mean, stdev)
return probabilities
# 类别
def predict(self, X_test):
# {0.0: 2.9680340789325763e-27, 1.0: 3.5749783019849535e-26}
label = sorted(
self.calculate_probabilities(X_test).items(),
key=lambda x: x[-1]) [-1][0] # 找出概率最大时相对应的y
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: # 若概率最大时相对应的y,与测试集中的y相等
right += 1
return right / float(len(X_test))
model = NaiveBayes()
model.fit(X_train, y_train)
print(model.predict([4.4, 3.2, 1.3, 0.2]))
model.score(X_test, y_test)
scikit-learn实例
from sklearn.naive_bayes import GaussianNB
clf = GaussianNB()
clf.fit(X_train, y_train)
clf.score(X_test, y_test)
clf.predict([[4.4, 3.2, 1.3, 0.2]])
from sklearn.naive_bayes import BernoulliNB, MultinomialNB # 伯努利模型和多项式模型
第4章朴素贝叶斯法-习题
习题4.1
用极大似然估计法推出朴素贝叶斯法中的概率估计公式(4.8)及公式 (4.9)。
解答:
第1步: 证明公式(4.8):
由于朴素贝叶斯法假设
是定义在输出空间
上的随机变量,因此可以定义
概率为
。
令
,得出似然函数:
显然 ,公式(4.8)得证。
第2步: 证明公式(4.9):
令
,
令,得出似然函数:
公式(4.11)得证。
数据来源:统计学习方法(第二版) &
https://github.com/fengdu78/lihang-code
百度网盘链接:https://pan.baidu.com/s/1JzRQCvgCUI32GmYmEeVAzg
百度网盘链接:https://pan.baidu.com/s/1kzhPX0flmPAusUafScNVtw