LDA, 即 Linear Discriminant Analysis, 中文翻译为, 线性判别分析. 比较有趣的一点是:LDA 既可以直接用作分类算法, 也可作为特征降维的方法. 给人感觉, 这是将特征工程和建模一并给做了呀.
LDA 作为分类器
可以通过熟知的SVM来比较, 为啥总提SVM呢, 我非常喜欢呀, 理论完美, 推导不易, 但一旦啃下来了, 那就是真的明白了, 再去其他相类似的算法, 都是一碟小菜.
svm 的思想是要找到 一条最优的 类别间的分割线(面) (w^Tx+b=0), 到类别两边的 "距离相等" 且尽可能的大, 即max margin, 且这个距离是:
(max margin = frac {2}{||w||})
而 LDA 是要找到一条线 (w^Tx + b = y), 让类别的点都向该直线 投影 (有点像PCA). 而分割线的是方向与该投影线垂直 通过 w 的一变化, 该投影线也在变化, 目标是找个一条适合的 投影线, 使得不同类别点投影下来, 有同类间隔很近, 不同类较远.
假设类别A的中心是 (mu_1, 标准差是: sigma_1), 类别B的中心是 (mu_2, 标准差是: sigma_2) 即要实现 高内聚,低耦合 的效果.
即: (max frac {(mu_1 - mu_2)^2}{sigma_1^2 + sigma_2 ^2})
LDA 分类器推导
知识准备
假设有大 K 个类别.
假设 $f_k(x) 为类别 G=k 的数据的条件概率密度函数, (pi_k) 为类别 G=k 的数据的先验概率.
真实中先验是不知道, 根据参数估计 可知抽样分布的样本去估计总体.
(pi_k = frac {N_k}{N} , sum limits _{k=1}^K pi_k = 1)
(N_k) 表示 k类 的样本数 占 总样本数 N 的比例, 记为 (pi_k)
数据共K个类别, 即所有 (pi_k) (比例)之和为1
一个类别下有很多数据, 分布函数是 f(x)
理想中, 我们是上帝, 已知先验概率, 那正常的逻辑是:
离散和连续是一样的哈, 离散用 (sum) 连续用 (int) (莱布尼兹 发明, 灵感就是 'sum' 都表示"累积求和")
因 知道 总体有 (A_1, A_2 ... A_K) 各类别, 及其对应出现的概率 (P(A_1), P(A_2)...P(A_k))
且 知道 每个类别下, 某类事件(样本)x 出现的概率: (P(x|A_1), P(x|A_2)...P(x|A_k))
则 现在随机来一个抽样, 恰好是该类事件的概率有多大?
分析:
最终该事件的发生概率, 其实是分散在, 总体中, 各类别下的该事件发生概率 的累加.(先类别发生的前提下 再发生的概率) 这样的逻辑关系 (条件概率)
即 **全概率 ** (= sum limits_{i=1}^K P(A_i)P(x|A_i) = sum limits _{i=1}^K pi_i f_i(x))
本篇最初假设: (pi_k) 为类别 k 出现的概率;
(f_i(x)) 表示类别 k 发生前提下的 概率密度分布函数;
共大 K 个类别;
现实中, 我们只是凡人, 只凭经验动态猜测先验概率, 现在的问题是:
已知该事件 x 发生了, x 是哪一个类别 的可能性最大?
即: (P(A_k|x) = frac {P(A_k)P(x|A_k)}{sum limits _{i=1}^K P(A_i)P(x|A_i)})
其实这个公式就是 大家熟知但又不熟悉的 贝叶斯公式
简单点, 解决类似 已知 (P(x|A_i)) 求解 (P(A_i|x)) 的问题
深刻点, 贝叶斯思想 (总体不可知, 参数不固定(变量), 动态来修正(概率分布)
即在本篇中, 样本 x 发生下, 属于类别 k 的概率表示为:
(P_r (G=k|X=x) = frac {pi_k f_k(x)}{sum limits _{i=1}^K pi_k f_i(x)})
LDA 模家型假设
多元正态分布假设
直到目前, 对于 (f_k(x)) 这个概率分布函数的具体形式尚未给出, 这里给出具体形式, 注意的是, x 可以是 一元, 也可以是多元(向量) , 为了更一般化, 假设 x 是多元 (向量), 分布呢, 就假定是 多元正态分布
(f_k(x) = frac {1}{2pi ^{frac {p}{2}} |Sigma_k|^{0.5}} e^{-frac {1}{2} (x- mu_k)^T sum_k^{-1} (x-mu_k)})
p 表示 x 向量的维度 (几(维) 元)
(Sigma_k) 是样本 X 矩阵的 协方差矩阵, 主对角线是 各特征的方差
(|Sigma|^{0.5}) 是对协方差矩阵求 行列式 再开根号 (得到一个实数)
(mu_k) 是样本 X 矩阵中, 属于 k 类的 那些 行, 然后分别对 每个特征 求均值, 最后组成的 均值向量
等方差假设
LDA 假设 不论有 多少个类别, 都认为他们的 协方差是一样的, 为啥要这样, 嗯... 可以回顾 数理统计中 关于 假设检验 - 方差分析 F 分布 这部分内容, 这里不暂时不展开了. 这样假设的好处,嗯... 理论上方便推导和计算吧大概.
(forall _k 满足 Sigma _k = Sigma)
注意这里的 (Sigma), 是先求: 对 属于某个类别 k 下的协方差阵 (X 是 n个样本(行), p维度 (列))
咱平时说的向量, 默认都是列向量
(sum limits _{i=1}^n (x_i - mu_k) (x_i - mu_k)^T) 注 xi 表示 一行, 即 p x1 维, 输出维度 (p x 1) ( 1xp) -> pxp 的 协方差, 方阵
再对每个类别 进行 求和起来, 相当于 二重的 for 循环
即: (Sigma = sum limits _{i=1}^K sum limits _{i=1}^n (x_i - mu_k) (x_i - mu_k)^T)
嗯, 概念类似, excel 表格(多行多列), 其中有一个字段是 "类别", 现进行 "筛选", 不同的类别, 晒出来的表格是不一样的, 当 "筛选所有值" 不就是 "整体了吗" . 没一个类值, 对应一个 pxp 的 协方差阵(方阵), 然做 K个类别, 即
(sum_1 + sum_2 +....sum_k = sum) 对应元素相加呀, 简单吧
latex, 注意, 求和符号 sum 和 协方差(大写西格玛) Sigma 感觉是一样的 (sum, 和, Sigma), 难怪之前会看糊涂, 果然, 符号使用跟 写代码是一样的, 一定要先声明 (标量,行/列向量, 矩阵, 函数...., 不然就不知道是啥了
对于:
(P_r (G=k|X=x) = frac {pi_k f_k(x)}{sum limits _{i=1}^K pi_k f_i(x)})
不论 x 是什么, 在先验概率下, x 的全概率 是不变的, 即 P(x) = (sum limits _{i=1}^K pi_k f_i(x)) 是个常数, 假设用 (frac {1}{c}) 来代替 则:
(P_r (G=k|X=x) = c pi_k f_k(x) =frac {c pi_k}{2pi ^{frac {p}{2}} |Sigma_k|^{0.5}} e^{-frac {1}{2} (x- mu_k)^T sum_k^{-1} (x-mu_k)})
在训练中, p 是固定的, (Sigma) 也是假设相等的, 因此这项 (frac {c}{2pi ^{frac {p}{2}} |Sigma_k|^{0.5}}) 也是固定的, 也 记为 常数 c (覆盖之前的哈), 则化简为:
(P_r (G=k|X=x) = c pi_k e^{-frac {1}{2} (x- mu_k)^T sum_k^{-1} (x-mu_k)})
再两边取对数, 乘法边加法
(P_r (G=k|X=x) = log c + log pi_k{-frac {1}{2} (x- mu_k)^T sum_k^{-1} (x-mu_k)})
判断 x 是属于哪一类, 带入上面公式即可, 如果有 K个类别, 那就算 K 次, 概率最大的类别, 即为最可能的类别.
log c 也是对 所有类别的影响一样, 可以忽略, 继续简化:
(=log pi_k - frac {1}{2} [x^T Sigma ^{-1} x - x^T Sigma^{-1}u_k - mu_k ^T Sigma ^{-1} x + mu_k ^T Sigma ^{-1} mu_k])
(x^T Sigma^{-1}u_k) 和 (mu_k ^T Sigma ^{-1} x) 二者的值是一样的, 形式上 相差了一个 "转置", 随便写哪个都可以
(=log pi_k - frac {1}{2} [x^T Sigma ^{-1} x -2 x^T Sigma^{-1}u_k + mu_k ^T Sigma ^{-1} mu_k])
(x^T Sigma ^{-1} x) 的值 与 x 属于哪类别 k 也是无关的
于是最终优化的目标函数为:
(f(x) = log pi_k + x^T Sigma^{-1} mu_k - frac {1}{2}mu_k ^T Sigma ^{-1} mu_k)
(pi_k) 是当前类别的 先验概率, (mu_k) 是类别为 k 的样本矩阵的 特征均值向量
LDA分类模型应用
根据:
(f(x) = log pi_k + x^T Sigma^{-1} mu_k - frac {1}{2}mu_k ^T Sigma ^{-1} mu_k)
输出一批样本 X:
Pk = [ ]
for k in 如果有大 K 个类别, 就要计算 K 次 f(x) 的值, 是个概率. k = 1, 2, 3 ...
for 每次计算, 都会从总样本矩阵 X 中, 筛选出 当前 属于 k 的 "k 样本矩阵" 进行计算.
输出一个 概率值 f(k).
Pk.append (fk))
Pk.sort( )
return Pk[-1] 最大概率 及对应类别
(补充) 协方差矩阵
样本 X 是nxp 的矩阵, 每行表示一个样本, 每列表示一个 特征 , 即我们所的一个样本(一个行)是 px1 的列向量 即: (如表示第6个样本, 第一行表示为:)
(x_6 = egin {pmatrix} X_{61} \ X_{62} \... \ X_{6p}end {pmatrix} = [X_{61}, X_{62}... X_{6p}]^T)
(X_{ij}) 表示第 i 个样本 的 第 j 个特征, 是一个实数值
(x_i 和 X_i) 的区别, (x_i) 表示 X 的 第 i 行, 共 n 行; (X_i) 表示的第 i 个特征变量 (字段), 共 p 维.
因此, 样本矩阵 X 可以写为:
(X = egin {pmatrix} X_i^T \ X_2^T \ ... \X_n^T end {pmatrix} = [X_1, X_2, ... Xp]^T) 尤其注意这里 样本和变量 不要混淆
即: 此处的样本矩阵 X (mxp), 表示 一个 p 维 随机向量 (x = [X_1, X_2, ...X_p]^T) 的一次 n 次抽样, (x_1, x_2... 表示某个样本(行))
且 (mu_i 是 X_i 的期望值, mu_i = E(X_i)) 即对对第 i 个特征 (列) 求均值, 所有的特征, 的均值就组成了
则样本 X 的 均值向量(中心)
(mu = [mu_i, mu_2, mu_3, ...mu_p] ^T)
而特征 i 与 特征 j 间的协方差为:
(Sigma _{ij} = E [(X_i-mu_i)(X_j-mu_j)^T]) 是一个 pxp 的方阵
从而 样本 X 的协方差矩阵为:
(Sigma = E[(X-E(X)(X-E(X)^T]) 也是 pxp 的方阵
小结 - LDA 作为分类器
理论核心其实, 就是 贝叶斯公式
这个过程可简单描述为:
已知 大类的先验分布, 及在各大类发生的前提下, B事件发生的条件概率.
则可 求出 B 事件发生的 全概率 (各条件概率之和)
BUT 已经B事件已经发生
求解 B 最可是属于哪一类(先验)
这妥妥的贝叶斯呀, 不过, 如果样本不均衡, 我感觉如果不加权重, 就要凉凉了.
从写代码实现来看, 对于样本 X 是已知的, 大类的先验概率, 就以 "分类字段" 进行 group by 再 count 就得到频率了, 用抽样分布参数估计总体, 即 频率 = 概率 这样每个大类的先验就ok了.
然后是事件的分布, 假设是服从多元的高斯分布, 也是可通过每个 类 的 抽样估计总体, 其实就是算一个 均值 和协方差, 这也搞定了
然后是 输入一个 新 X', 遍历每行,计算 之前推到出的判别函数, 共计算 K 次
(f(x) = log pi_k + x^T Sigma^{-1} mu_k - frac {1}{2}mu_k ^T Sigma ^{-1} mu_k)
则会输出 某样本 分别在 每个类别的 概率可能性, 是个 向量, list
返回最大即可 (其实这里是有 2层的 for 循环, 负责度是 O(n**2) 大概.
嗯, 下篇 就整一波, LDA 作为 降维 vs PCA 吧!