{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 贝叶斯分类器\n",
    "\n",
    "在前面的例子中，我们可以把所有的样本以表格的形式列出来：\n",
    "\n",
    "|箱子|球的类别|\n",
    "|----|------|\n",
    "|A|好|\n",
    "|A|坏|\n",
    "|A|好|\n",
    "|A|好|\n",
    "|A|好|\n",
    "|B|好|\n",
    "|B|坏|\n",
    "|B|坏|\n",
    "\n",
    "每一个样本都由两部分组成：特征和类别。可以看出这里只有一个特征（箱子编号），而且是二分类问题（好或坏）。\n",
    "\n",
    "所以贝叶斯定理天生具有分类功能，我们不妨推广到多特征多分类的情况，譬如把 $A_i$ 当作类标记，也就是说样本空间被划分成 $A_1, A_2, ..., A_n$，可以理解为样本空间可以分成 n 类，我们可以把 $B$ 当作样本数据的特征向量。类标记集合 $\\mathcal{Y} = \\{c_1, c_2, \\dots, c_K\\}$，输入为特征向量 $x$，输出为类标记 $y$，那么贝叶斯公式可以改成下面的形式：\n",
    "\n",
    "$$\n",
    "P(Y=c_k|X=x) = \\frac{P(X=x|Y=c_k)P(Y=c_k)}{\\sum_{i=1}^n P(X=x|Y=c_k)P(Y=c_k)}\n",
    "$$\n",
    "\n",
    "通过这个公式，可以计算出输入特征 $X$ 属于类别 $c_k$ 的概率，计算所有类别的概率，看看哪个类别的概率最大，就把输入特征归到这个类别，这就是**贝叶斯分类器**（Bayes classifier）的基本原理。\n",
    "\n",
    "### 朴素贝叶斯分类器\n",
    "\n",
    "我们再来看一个例子。假设某个医院早上来了8个门诊病人，如下表：\n",
    "\n",
    "|症状|职业|疾病|\n",
    "|---|----|----|\n",
    "|打喷嚏|护士|感冒|\n",
    "|打喷嚏|农夫|过敏|\n",
    "|头痛|建筑工人|脑震荡|\n",
    "|头痛|建筑工人|感冒|\n",
    "|打喷嚏|建筑工人|过敏|\n",
    "|打喷嚏|教师|感冒|\n",
    "|头痛|教师|脑震荡|\n",
    "|打喷嚏|教师|过敏|\n",
    "\n",
    "现在来了第9个病人，是一个打喷嚏的建筑工人，那么他最可能得的疾病是什么？\n",
    "\n",
    "很显然，从上表中的样本数据可以知道，这里的特征有两个（症状和职业），可能的疾病有：感冒、过敏、脑震荡，是个三分类问题。要想预测这个建筑工人的疾病，实际上就是求下面的三个条件概率，然后取概率值最大的那种情况：\n",
    "\n",
    "* $P(cold|sneeze \\cap builder)$\n",
    "* $P(allergy|sneeze \\cap builder)$\n",
    "* $P(concussion|sneeze \\cap builder)$\n",
    "\n",
    "根据贝叶斯定理，我们有：\n",
    "\n",
    "$$\n",
    "\\begin{align}\n",
    "P(cold|sneeze \\cap builder) = \\frac{P(sneeze \\cap builder|cold)P(cold)}{P(sneeze \\cap builder)}\n",
    "\\end{align}\n",
    "$$\n",
    "\n",
    "这里的 $P(sneeze \\cap builder|cold)$ 是个联合概率，当特征数非常多时，联合概率非常难求，所以我们在这里做了一个大胆的假设：**所有的特征是彼此独立的**。所以：\n",
    "\n",
    "$$\n",
    "\\begin{align}\n",
    "P(cold|sneeze \\cap builder) &= \\frac{P(sneeze \\cap builder|cold)P(cold)}{P(sneeze \\cap builder)} \\\\\n",
    "&= \\frac{P(sneeze|cold)P(builder|cold)P(cold)}{P(sneeze)P(builder)}\n",
    "\\end{align}\n",
    "$$\n",
    "\n",
    "根据这个假设得到的分类器，我们称之为**朴素贝叶斯分类器**（naive Bayes classifier）。英文 naive 的意思是天真的幼稚的，不过，尽管这个假设非常幼稚，但它在很多分类领域发挥着重要的作用。\n",
    "\n",
    "根据上面的表格，我们有：\n",
    "\n",
    "$$\n",
    "\\begin{align}\n",
    "P(cold) &= \\frac{3}{8} \\\\\n",
    "P(sneeze) &= \\frac{5}{8} \\\\\n",
    "P(builder) &= \\frac{3}{8} \\\\\n",
    "P(sneeze|cold) &= \\frac{2}{3} \\\\\n",
    "P(builder|cold) &= \\frac{1}{3}\n",
    "\\end{align}\n",
    "$$\n",
    "\n",
    "所以求得：\n",
    "\n",
    "$$\n",
    "P(cold|sneeze \\cap builder) = \\frac{\\frac{2}{3} \\times \\frac{1}{3} \\times \\frac{3}{8}}{\\frac{5}{8} \\times \\frac{3}{8}} = \\frac{16}{45}\n",
    "$$\n",
    "\n",
    "同理：\n",
    "\n",
    "$$\n",
    "P(allergy|sneeze \\cap builder) = \\frac{\\frac{3}{3} \\times \\frac{1}{3} \\times \\frac{3}{8}}{\\frac{5}{8} \\times \\frac{3}{8}} = \\frac{24}{45} \\\\\n",
    "P(concussion|sneeze \\cap builder) = \\frac{\\frac{0}{2} \\times \\frac{1}{2} \\times \\frac{2}{8}}{\\frac{5}{8} \\times \\frac{3}{8}} = 0\n",
    "$$\n",
    "\n",
    "可以推断出，这个建筑工人得过敏的可能性最大。\n",
    "\n",
    "在上面的计算过程中，三个概率的分母都是 $P(sneeze \\cap builder)$，而我们最后是要比较这三个概率的大小，所以这个值实际上可以不用算，这个值有时候又被为 **证据因子**（evidence）。\n",
    "\n",
    "最后，我们总结一下贝叶斯分类的公式：\n",
    "\n",
    "$$\n",
    "\\begin{align}\n",
    "y = f(x) &= \\mathop{\\arg\\max}_{c_k} P(Y=c_k|X=x) \\\\\n",
    "&= \\mathop{\\arg\\max}_{c_k} P(Y=c_k)P(X=x|Y=c_k) \\\\\n",
    "&= \\mathop{\\arg\\max}_{c_k} P(Y=c_k) \\prod_i P(X=x^{(i)}|Y=c_k)\n",
    "\\end{align}\n",
    "$$\n",
    "\n",
    "朴素贝叶斯法通过训练数据集学习到联合概率分布 $P(X,Y)$，具体的，它是先验概率和条件概率的乘积，实际上，联合概率分布代表的是生成数据的机制，所以贝叶斯模型被称为**生成式模型**。使用朴素贝叶斯法分类时，对给定的输入 $x$，通过学习到的模型计算后验概率，将后验概率最大的类别作为 $x$ 的类输出。不过上式中的连乘操作很容易造成下溢，可以对其求对数来规避这个问题，求对数后的似然叫做**对数似然**（log-likelihood）：\n",
    "\n",
    "$$\n",
    "\\log \\prod_i P(X=x^{(i)}|Y=c_k) = \\sum_i \\log P(X=x^{(i)}|Y=c_k)\n",
    "$$\n",
    "\n",
    "为什么朴素贝叶斯法将实例分到后验概率最大的类中呢？因为这可以使得**期望风险**最小。（证明过程参见李航的《统计学习方法》4.1.2节）\n",
    "\n",
    "为了求先验概率 $P(Y=c_k)$ 和 条件概率 $P(X=x|Y=c_k)$，一般使用**极大似然估计**法。\n",
    "\n",
    "先验概率 $P(Y=c_k)$ 的极大似然估计是：\n",
    "\n",
    "$$\n",
    "P(Y=c_k) = \\frac{\\sum_{i=1}^{N}I(y_i=c_k)}{N}\n",
    "$$\n",
    "\n",
    "其中，$I(x)$ 称为**指示函数**（indicator function），当括号中的条件满足时函数值为 1，否则函数值为 0，相当于计数。条件概率 $P(X=x|Y=c_k)$ 的极大似然估计是：\n",
    "\n",
    "$$\n",
    "P(X=x|Y=c_k) = \\frac{\\sum_{i=1}^{N}I(x_i=x,y_i=c_k)}{\\sum_{i=1}^{N}I(y_i=c_k)}\n",
    "$$\n",
    "\n",
    "### 贝叶斯估计\n",
    "\n",
    "在上面的计算中，我们发现 $P(concussion|sneeze \\cap builder) = 0$，这是因为用极大似然法来估计条件概率时出现了概率值为 0 的情况，为了避免这种情况，一般推荐采用**贝叶斯估计**（Bayesian estimation），先验概率的贝叶斯估计为：\n",
    "\n",
    "$$\n",
    "P_{\\lambda}(Y=c_k) = \\frac{\\sum_{i=1}^{N}I(y_i=c_k) + \\lambda}{N+K\\lambda}\n",
    "$$\n",
    "\n",
    "其中，$K$ 表示类别的个数。同样的，条件概率的贝叶斯估计为：\n",
    "\n",
    "$$\n",
    "P_{\\lambda}(X=x|Y=c_k) = \\frac{\\sum_{i=1}^{N}I(x_i=x,y_i=c_k) + \\lambda}{\\sum_{i=1}^{N}I(y_i=c_k) + S\\lambda}\n",
    "$$\n",
    "\n",
    "当 $\\lambda = 0$ 时，就是极大似然估计，通常取 $\\lambda = 1$，这时称为 **拉普拉斯平滑**（Laplace smoothing）。\n",
    "\n",
    "### 连续属性的处理\n",
    "\n",
    "上面例子中的样本特征都是离散值，当特征是连续值时，我们可以用概率密度函数 $p(x|c)$ 替换上面的概率 $P(x|c)$。假设概率密度函数服从正态分布，即 $p(x|c) \\sim \\mathcal{N}(\\mu_c, \\delta^2_c)$，其中 $\\mu_c$ 和 $\\delta^2_c$ 分别是 c 类样本在某个属性上取值的均值和方差，则有：\n",
    "\n",
    "$$\n",
    "p(x|c) = \\frac{1}{\\sqrt{2\\pi}\\delta_c} \\exp \\lgroup -\\frac{(x-\\mu_c)^2}{2\\delta_c^2} \\rgroup\n",
    "$$"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
