- 为什么要降维:
1、避免维数灾难,高维情况下容易产生过拟合
2、特征之间如果存在明显的相关性(也叫共线性),此时就需要降维
3、降维可以提取数据中的有效信息,去除噪音数据
4、降维可以降低数据的复杂性,减少模型的训练时间
5、可以方便对数据进行可视化处理,因为维数很高的话,无法可视化
在machine learning领域,PCA和LDA都可以看成是数据降维的一种方式。
1.PCA介绍
- 目的:
将原有的d维数据集转换成K维的数据,看k<d;
新生成的K维数据尽可能多的包含原来d维数据的信息
直观看:投影后的投影值尽可能分散。(方差)
- PCA处理过程:
1.将原始数据按列组成d行n列矩阵X
2.将X的每一样本去中心化,即减去这一行的均值
3.求出协方差矩阵
4.求出协方差矩阵的特征值及对应的特征向量
5.将特征向量按对应特征值大小从上到下按行排列成矩阵,取前m行组成矩阵P
6.Y=PX即为降维到m维后的数据
- PCA推导过程:blog.csdn.net/qq_38330846…
2.LDA介绍
- 目的:
降维数据满足两个特征来减少重叠:不同类别数据降维后相互间的差异大,同一类别数据降维后相互间的差异小(最大化类间距离和最小化类內距离)
- LDA降维流程:
1.计算每个类别的均值ui,全局样本均值u
2.计算类內散度矩阵Sw,全局散度矩阵St,类间散度矩阵Sb
3.对矩阵Sw-1Sb做特征值分解
4.去最大的d‘个特征值所对应的特征向量
5.计算投影矩阵
- LDA推导过程:blog.csdn.net/u012535605/…
3.PCA和LDA代码
- pca代码
import numpy as np
from scipy.spatial.distance import pdist,squareform
def pca(X, threshold):
#将X中心化
X_mean = np.mean(X, axis = 0)
X_cen = X - X_mean
#构造散度矩阵并且求解特征值与特征向量
X_sca = np.dot(X_cen.T, X_cen)
X_eigenval, X_eigenvect = np.linalg.eig(X_sca)
#按照阈值排序
indexs = X_eigenval.argsort()[::-1]
indexs = indexs[:threshold]
X_eigenvect_TopK = X_eigenvect[:,indexs]
#将X投影到特征向量上
X_proj = np.dot(X_cen, X_eigenvect_TopK)
#计算重构数据 X * X_proj* X_proj.T
X_restore = np.dot(X_proj, X_eigenvect_TopK.T) + X_mean
return X_proj, X_restore
#kernel_pca
def KPCA(X, gamma, k):
#计算L2距离
dist_arr = sqdist(X, metric='sqeuclidean')
dist_mat = squareform(sq_dists)
#计算径向基散度矩阵,并将其归一化
K_diag = np.exp(-gamma * dist_mat)
N = X.shape[0]
one_N = np.ones((N, N))/N
K = K-one_N.dot(K)-K.dot(one_N)+one_N.dot(K).dot(one_N)
#计算特征值与特征向量
K_eigenval, K_eigevector = np.linalg.eigh(K)
K_eigevector_proj = np.column_stack((K_eigevector[:, -i]for i in range(1, 1+k)))
K_eigenval_proj = [K_eigenval[-i] for i in range(1, k+1)]
return K_eigevector_proj, K_eigenval_proj
#计算新来的样本的投影
#模型构建完毕后,至于观测样本有关。
def proj_new(X_new, X, gamma, K_eigevector_proj, K_eigenval_proj):
k = np.exp(-gamma*np.sum((X-X_new)**2, 1))
return k.dot(K_eigevector_proj/K_eigenval_proj)
- LDA代码
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
多种降维参考代码:github.com/heucoder/di…
4.PCA与LDA的比较
- 相似点:
从PCA和LDA的计算过程来看,最后其实都是在求某一个矩阵的特征值,投影矩阵即为该特征值对应的特征向量。
- 差异:
1.PCA为非监督降维,LDA为有监督降维
2.PCA希望投影后的数据方差尽可能的大,方差越大,则降维后包含的信息越多;LDA则希望投影后相同类别的组内方差小,而组间方差大。LDA能合理运用标签信息,使得投影后的维度具有判别性,不同类别数据尽可能的分开。
3.有标签就尽可能的利用标签的数据(LDA),而对于纯粹的非监督任务,则还是得用PCA进行数据降维。