这次,我们来学习一种经典的降维方法:
线性判别分析(Linear Discriminant Analysis, 以下简称LDA).
在前面博客中(点我)我们讲解了PCA降维算法。
PCA追求的是在降维之后能够最大化保持数据的内在信息,并通过衡量在投影方向上的数据方差的大小来衡量该方向的重要性。
PCA优缺点:
优点:1.最小误差 2.提取了主要信息
缺点:PCA将所有的样本(特征向量集合)作为一个整体对待,去寻找一个均方误差最小意义下的最优线性映射投影,而忽略了类别属性,而它所忽略的投影方向有可能刚好包含了重要的可分性信息。
LDA所追求的目标和PCA不同,不是希望保持数据最多的信息,而是希望数据在降维后能够很容易地被区分开来。
LDA一种有监督的线性降维方法,,也就是说它的数据集的每个样本是有类别输出的。这点和PCA不同。PCA是不考虑样本类别输出的无监督降维技术。
核心思想:往线性判别超平面的法向量上投影,使的区分度最大(高内聚,低耦合)。LDA是为了使得降维后的数据点尽可能地容易被区分!
用一句话概括,就是**“投影后类内方差最小,类间方差最大”**。
什么意思呢?
我们要将数据在低维度上进行投影,
投影后希望每一种类别数据的投影点尽可能的接近,
而不同类别的数据的类别中心之间的距离尽可能的大。
LDA算法计算步骤:
import numpy as np
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
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
if __name__ == '__main__':
iris = load_iris()
X = iris.data
Y = iris.target
data_1 = lda(X, Y, 2)
data_2 = LinearDiscriminantAnalysis(n_components=2).fit_transform(X, Y)
plt.figure(figsize=(8,4))
plt.subplot(121)
plt.title("LDA")
plt.scatter(data_1[:, 0], data_1[:, 1], c = Y)
plt.subplot(122)
plt.title("sklearn_LDA")
plt.scatter(data_2[:, 0], data_2[:, 1], c = Y)
plt.savefig("LDA.png",dpi=600)
plt.show()
run result:
这里,我们使用了自己编程实现的LDA和调用sklearn自带的LDA对iris数据进行LDA,效果图如上。
PCA和LDA的比较:
相同点:
1)两者均可以对数据进行降维。
2)两者在降维时均使用了矩阵特征分解的思想。
3)两者都假设数据符合高斯分布。
不同点:
1)LDA是有监督的降维方法,而PCA是无监督的降维方法
2)LDA降维最多降到类别数k-1的维数,而PCA没有这个限制。
3)LDA除了可以用于降维,还可以用于分类。
4)LDA选择分类性能最好的投影方向,而PCA选择样本点投影具有最大方差的方向。
LDA算法总结:
LDA算法既可以用来降维,又可以用来分类,但是目前来说,主要还是用于降维。在我们进行图像识别图像识别相关的数据分析时,LDA是一个有力的工具。
LDA算法的主要优点有:
1)在降维过程中可以使用类别的先验知识经验,而像PCA这样的无监督学习则无法使用类别先验知识。
2)LDA在样本分类信息依赖均值而不是方差的时候,比PCA之类的算法较优。
LDA算法的主要缺点有:
1)LDA不适合对非高斯分布样本进行降维,PCA也有这个问题。
2)LDA降维最多降到类别数k-1的维数,如果我们降维的维度大于k-1,则不能使用LDA。当然目前有一些LDA的进化版算法可以绕过这个问题。
3)LDA在样本分类信息依赖方差而不是均值的时候,降维效果不好。
4)LDA可能过度拟合数据。
注:里面的还有很多知识不是很了解,现在可是用代码实现,大致了解这LDA,后续进行更加深入的了解。
参考和引用:
https://www.cnblogs.com/pinard/p/6244265.html (线性判别分析LDA原理总结)
https://github.com/heucoder/dimensionality_reduction_alo_codes
https://blog.csdn.net/ChenVast/article/details/79227945
https://scikit-learn.org/stable/auto_examples/neighbors/plot_nca_dim_reduction.html#sphx-glr-auto-examples-neighbors-plot-nca-dim-reduction-py
https://www.cnblogs.com/jiahuaking/p/3938541.html
仅用来个人学习和分享,如有错误,请指正。
如若侵权,留言立删。
尊重他人知识产权,不做拿来主义者!
喜欢的可以关注我哦QAQ,
你的关注和喜欢就是我write博文的动力。