这次,我们来学习一种经典的降维方法:
线性判别分析(Linear Discriminant Analysis, 以下简称LDA)
.
在前面博客中(点我)我们讲解了PCA降维算法。
PCA追求的是在降维之后能够最大化保持数据的内在信息,并通过衡量在投影方向上的数据方差的大小来衡量该方向的重要性。
PCA优缺点:
优点:1.最小误差 2.提取了主要信息
缺点:PCA将所有的样本(特征向量集合)作为一个整体对待,去寻找一个均方误差最小意义下的最优线性映射投影,而忽略了类别属性,而它所忽略的投影方向有可能刚好包含了重要的可分性信息。
LDA所追求的目标和PCA不同,
不是希望保持数据最多的信息,而是希望数据在降维后能够很容易地被区分开来。
LDA一种
有监督的
线性降维方法,,也就是说它的数据集的每个样本是有类别输出的。这点和PCA不同。PCA是不考虑样本类别输出的无监督降维技术。
核心思想
:
往线性判别超平面的法向量上投影
,使的区分度最大(高内聚,低耦合)。LDA是为了使得降维后的数据点尽可能地容易被区分!
用一句话概括,就是**“投影后类内方差最小,类间方差最大”**。
什么意思呢?
我们要将数据在低维度上进行投影,
投影后希望每一种类别数据的投影点尽可能的接近,
而不同类别的数据的类别中心之间的距离尽可能的大。
LDA算法计算步骤:
- 对d维数据进行标准化处理(d为特征数量)
- 对每一类别,计算d维的均值向量
- 构造类间的散步矩阵和类内的散步矩阵
- 计算矩阵的特征值和对应的特征向量
- 选取前k个特征值对应的特征向量 ,构造一个d x k维的转换矩阵W,特征向量以列的形式排列
- 使用转换矩阵W将样本映射到新的特征子空间上
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博文的动力。