用scikit-learn进行LDA降维——以前没有注意,原来LDA降维竟然这么好用!对无监督的任务使用PCA进行降维,对有监督的则应用LDA。
PCA和LDA区别:PCA选择的是投影后数据方差最大的方向。由于它是无监督的,因此PCA假设方差越大,信息量越多,用主成分来表示原始数据可以去除冗余的维度,达到降维。而LDA选择的是投影后类内方差小、类间方差大的方向。其用到了类别标签信息,为了找到数据中具有判别性的维度,使得原始数据在这些方向上投影后,不同类别尽可能区分开。
举一个简单的例子,在语音识别中,我们想从一段音频中提取出人的语音信号,这时可以使用PCA先进行降维,过滤掉一些固定频率(方差较小)的背景噪声。但如果我们的需求是从这段音频中区分出声音属于哪个人,那么我们应该使用LDA对数据进行降维,使每个人的语音信号具有区分性。
用scikit-learn进行LDA降维
在线性判别分析LDA原理总结中,我们对LDA降维的原理做了总结,这里我们就对scikit-learn中LDA的降维使用做一个总结。
1. 对scikit-learn中LDA类概述
在scikit-learn中, LDA类是sklearn.discriminant_analysis.LinearDiscriminantAnalysis。那既可以用于分类又可以用于降维。当然,应用场景最多的还是降维。和PCA类似,LDA降维基本也不用调参,只需要指定降维到的维数即可。
2. LinearDiscriminantAnalysis类概述
我们这里对LinearDiscriminantAnalysis类的参数做一个基本的总结。
1)solver : 即求LDA超平面特征矩阵使用的方法。可以选择的方法有奇异值分解"svd",最小二乘"lsqr"和特征分解"eigen"。一般来说特征数非常多的时候推荐使用svd,而特征数不多的时候推荐使用eigen。主要注意的是,如果使用svd,则不能指定正则化参数shrinkage进行正则化。默认值是svd
2)shrinkage:正则化参数,可以增强LDA分类的泛化能力。如果仅仅只是为了降维,则一般可以忽略这个参数。默认是None,即不进行正则化。可以选择"auto",让算法自己决定是否正则化。当然我们也可以选择不同的[0,1]之间的值进行交叉验证调参。注意shrinkage只在solver为最小二乘"lsqr"和特征分解"eigen"时有效。
3)priors :类别权重,可以在做分类模型时指定不同类别的权重,进而影响分类模型建立。降维时一般不需要关注这个参数。
4)n_components:即我们进行LDA降维时降到的维数。在降维时需要输入这个参数。注意只能为[1,类别数-1)范围之间的整数。如果我们不是用于降维,则这个值可以用默认的None。
从上面的描述可以看出,如果我们只是为了降维,则只需要输入n_components,注意这个值必须小于“类别数-1”。PCA没有这个限制。
3. LinearDiscriminantAnalysis降维实例
在LDA的原理篇我们讲到,PCA和LDA都可以用于降维。两者没有绝对的优劣之分,使用两者的原则实际取决于数据的分布。由于LDA可以利用类别信息,因此某些时候比完全无监督的PCA会更好。下面我们举一个LDA降维可能更优的例子。
完整代码参加我的github: https://github.com/ljpzzz/machinelearning/blob/master/classic-machine-learning/lda.ipynb
我们首先生成三类三维特征的数据,代码如下:
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D %matplotlib inline from sklearn.datasets.samples_generator import make_classification X, y = make_classification(n_samples=1000, n_features=3, n_redundant=0, n_classes=3, n_informative=2, n_clusters_per_class=1,class_sep =0.5, random_state =10) fig = plt.figure() ax = Axes3D(fig, rect=[0, 0, 1, 1], elev=30, azim=20) ax.scatter(X[:, 0], X[:, 1], X[:, 2],marker='o',c=y)
我们看看最初的三维数据的分布情况:
首先我们看看使用PCA降维到二维的情况,注意PCA无法使用类别信息来降维,代码如下:
from sklearn.decomposition import PCA pca = PCA(n_components=2) pca.fit(X) print pca.explained_variance_ratio_ print pca.explained_variance_ X_new = pca.transform(X) plt.scatter(X_new[:, 0], X_new[:, 1],marker='o',c=y) plt.show()
在输出中,PCA找到的两个主成分方差比和方差如下:
[ 0.43377069 0.3716351 ] [ 1.20962365 1.03635081]
输出的降维效果图如下:
由于PCA没有利用类别信息,我们可以看到降维后,样本特征和类别的信息关联几乎完全丢失。
现在我们再看看使用LDA的效果,代码如下:
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis lda = LinearDiscriminantAnalysis(n_components=2) lda.fit(X,y) X_new = lda.transform(X) plt.scatter(X_new[:, 0], X_new[:, 1],marker='o',c=y) plt.show()
输出的效果图如下:
可以看出降维后样本特征和类别信息之间的关系得以保留。
一般来说,如果我们的数据是有类别标签的,那么优先选择LDA去尝试降维;当然也可以使用PCA做很小幅度的降维去消去噪声,然后再使用LDA降维。如果没有类别标签,那么肯定PCA是最先考虑的一个选择了。
(欢迎转载,转载请注明出处。欢迎沟通交流: liujianping-ok@163.com)
(二)sklearn降维——PCA和LDA
HawardScut 2018-07-27 16:42:55 2925 收藏 7
分类专栏: sklearn学习
版权
sklearn学习
专栏收录该内容
8 篇文章0 订阅
订阅专栏
线性判别分析(LDA)尝试识别占类之间差异最大的属性。特别地,与PCA相比,LDA是使用已知类标签的监督方法。
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.decomposition import PCA
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
iris = datasets.load_iris()
X = iris.data
y = iris.target
target_names = iris.target_names
X.shape,y.shape,target_names
1
((150, 4), (150,), array(['setosa', 'versicolor', 'virginica'], dtype='<U10'))
1
Iris数据集代表3种鸢尾花(Setosa,Versicolour和Virginica),具有4种属性:萼片长度,萼片宽度,花瓣长度和花瓣宽度。
PCA把4种属性降维2种
pca = PCA(n_components=2)
X_r = pca.fit(X).transform(X)
1
2
X_r.shape
1
(150, 2)
1
LDA把4种属性降维2种,LDA是使用已知类标签的监督方法
lda = LinearDiscriminantAnalysis(n_components=2)
X_r2 = lda.fit(X, y).transform(X)
1
2
X_r2.shape
1
(150, 2)
1
# Percentage of variance explained for each components
#explained_variance_ 指每个选定的组件所解释的差异量,
#等于n_components的协方差矩阵的最大特征值(保留特征值最大的组分)
#PCA解释方差比,如果没有设置n_components,则会存储所有组件,解释方差之和为1.0。
print('explained variance ratio (first two components): %s'
% str(pca.explained_variance_ratio_))
explained variance ratio (first two components): [0.92461621 0.05301557]
1
#绘图X_r[y == i, 0]代表第0个组分作为x轴,y == i代表标签为y的数据。
#一共3个类别,所有有3次不同颜色的绘图
plt.figure()
colors = ['navy', 'turquoise', 'darkorange']
lw = 2
for color, i, target_name in zip(colors, [0, 1, 2], target_names):
plt.scatter(X_r[y == i, 0], X_r[y == i, 1], color=color, alpha=.8, lw=lw,
label=target_name)
plt.legend(loc='best', shadow=False, scatterpoints=1)
plt.title('PCA of IRIS dataset')
Text(0.5,1,'PCA of IRIS dataset')
1
plt.figure()
for color, i, target_name in zip(colors, [0, 1, 2], target_names):
plt.scatter(X_r2[y == i, 0], X_r2[y == i, 1], alpha=.8, color=color,
label=target_name)
plt.legend(loc='best', shadow=False, scatterpoints=1)
plt.title('LDA of IRIS dataset')
plt.show()
分析:两种成分基本可以把3个类别区分,甚至一种成分(x轴的数据就可以,因为0.92461621代表大量的信息)
————————————————
版权声明:本文为CSDN博主「HawardScut」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hao5335156/article/details/81240168