线性判别分析(Linear Discriminant Analysis,LDA)
是一种可作为特征抽取的技术
Linear Discriminant Analysis
LDA 对您的数据做了一些简化的假设:
- 您的数据是高斯的,每个变量在绘制时的形状都像钟形曲线。
- 每个属性具有相同的方差,每个变量的值在平均值附近平均变化相同的量。
通过这些假设,LDA 模型会根据您的数据为每个类别估算均值和方差。在具有两个类的单变量(单个输入变量)情况下很容易想到这一点。
使用 LDA 进行预测
LDA 通过估计一组新输入属于每个类的概率来进行预测。获得最高概率的类是输出类并进行预测。
该模型使用贝叶斯定理来估计概率。简要地说,贝叶斯定理可用于使用每个类的概率和数据属于每个类的概率来估计给定 input(x) 的输出类ouptu class (k) 的概率.
如何为 LDA 准备数据
本节列出了在准备用于 LDA 的数据时可能考虑的一些建议。
- 分类问题。这可能不言而喻,但 LDA 旨在解决输出变量是分类的分类问题。LDA 支持二分类和多分类。
- 高斯分布。该模型的标准实现假设输入变量的高斯分布。考虑检查每个属性的单变量分布并使用变换使它们看起来更像高斯(例如指数分布的对数和根,以及偏斜分布的 Box-Cox)。
- 删除异常值。考虑从数据中删除异常值。这些可能会扭曲用于在 LDA 中分离类的基本统计数据,例如均值和标准差。
相同的方差。LDA假设每个输入变量具有相同的方差。在使用 LDA 之前标准化数据几乎总是一个好主意,这样它的平均值为 0,标准差为 1。
LDA 的扩展
线性判别分析是一种简单有效的分类方法。由于它简单且易于理解,因此该方法有许多扩展和变体。一些流行的扩展包括:
二次判别分析(QDA):每个类都使用自己的方差估计(或当有多个输入变量时的协方差)。
- 灵活判别分析 (FDA):使用输入的非线性组合,例如样条。
- 正则化判别分析(RDA):将正则化引入方差(实际上是协方差)的估计中,缓和不同变量对 LDA 的影响。
最初的发展被称为线性判别分析或费舍尔判别分析。多类版本被称为多判别分析。这些现在都简称为线性判别分析。
LDA 是一种可作为特征抽取的技术,其目标是向最大化类间差异,最小化类内差异的方向投影,以利于分类等任务即将不同类的样本有效的分开。LDA 可以提高数据分析过程中的计算效率,对于未能正则化的模型,可以降低维度灾难带来的过拟合。
LDA
方法步骤:
1、 对d维数据集进行标准化处理(d为特征数量)
2、 对每一类别,计算d维的均值向量
3、 构造类间的散布矩阵以及类内的散布矩阵
4、 计算矩阵的特征值所对应的特征向量,
5、 选取前k个特征值对应的特征向量,构造一个d x k维的转换矩阵W,特征向量以列的形式排列
6、 使用转换矩阵W将样本映射到新的特征子空间上
import numpy as np
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
'''
author: heucoder
email: 812860165@qq.com
date: 2019.6.13
'''
def lda(data, target, n_dim):
'''
:param data: (n_samples, n_features)
:param target: data class
:param n_dim: target dimension
:return: (n_samples, n_dims)
'''
clusters = np.unique(target)
if n_dim > len(clusters)-1:
print("K is too much")
print("please input again")
exit(0)
#within_class scatter matrix
# 类内离散度矩阵
Sw = np.zeros((data.shape[1],data.shape[1]))
for i in clusters:
datai = data[target == i]
datai = datai-datai.mean(0)
Swi = np.mat(datai).T*np.mat(datai)
Sw += Swi
#between_class scatter matrix
# 类间散射矩阵
SB = np.zeros((data.shape[1],data.shape[1]))
u = data.mean(0) #所有样本的平均值
for i in clusters:
Ni = data[target == i].shape[0]
ui = data[target == i].mean(0) #某个类别的平均值
SBi = Ni*np.mat(ui - u).T*np.mat(ui - u)
SB += SBi
S = np.linalg.inv(Sw)*SB
eigVals,eigVects = np.linalg.eig(S) #求特征值,特征向量
eigValInd = np.argsort(eigVals)
eigValInd = eigValInd[:(-n_dim-1):-1]
w = eigVects[:,eigValInd]
data_ndim = np.dot(data, w)
return data_ndim
https://github.com/heucoder/dimensionality_reduction_alo_codes/tree/master/codes/LDA