ML-降维:PCA、SVD、LDA、MDS、LLE、LE算法总结
1.PCA主成分分析
PCA是不考虑样本类别输出的无监督降维技术,实现的是高维数据映射到低维的降维。
PCA原理这个介绍的不错:https://www.cnblogs.com/pinard/p/6239403.html
线性代数矩阵性质背景:特征值表示的是矩阵在特征值对应的特征向量方向上的伸缩大小;线性代数的本质这个课有不错介绍:https://www.bilibili.com/video/av6731067
步骤:
1)组成数据矩阵
def get_date():m_vec = np.array([0, 0, 0])cov_vec = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])# 20个3维,且每个维度以m_vec为均值,以cov_vec为方差的多元正态分布随机数c1 = np.random.multivariate_normal(m_vec, cov_vec, 20).Tm_vec2 = np.array([1, 1, 1])cov_vec2 = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])# 20个3维,且每个维度以m_vec2为均值,以cov_vec2为方差的多元正态分布随机数c2 = np.random.multivariate_normal(m_vec2, cov_vec2, 20).T# 合并构造一个3 x 40 的数据集data = np.concatenate((c1, c2), axis=1)return dataX = get_date()
2) 计算特征均值
mean_X = np.mean(X, axis=1).reshape(X.shape[0], 1)
3) 去中心化的新数据矩阵
dmean_X = X - mean_X
4)计算协方差矩阵
m = dmean_X.shape[1]
C = np.dot(dmean_X, dmean_X.T) / m
5)C的分解
计算C的特征值,特征向量,(大到小排列,特征值-向量一一对应)
eig_val_sc, eig_vec_sc = np.linalg.eig(C)
6)取得投影矩阵
选择取C分解的前k(k<n)个特征向量,按行排列组成基向量:
k=2
# 从大到小特征值的k个索引
argsort_eigv = np.argsort(eig_val_sc)[-k:][::-1]
# 从大到小特征值的k个索引对应的特征向量,构造新矩阵
W = eig_vec_sc[argsort_eigv]
7)实现数据降维,n维到k维
# 构造的新矩阵对原数据X降维
new_X = np.dot(W, X)
然后用Yk.m替代Xn.m,作为降维数据集使用
import numpy as np
import pandas as pd
import matplotlib.pyplot as pltdef get_date():m_vec = np.array([0, 0, 0])cov_vec = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])# 20个3维,且每个维度以m_vec为均值,以cov_vec为方差的多元正态分布随机数c1 = np.random.multivariate_normal(m_vec, cov_vec, 20).Tm_vec2 = np.array([1, 1, 1])cov_vec2 = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])# 20个3维,且每个维度以m_vec2为均值,以cov_vec2为方差的多元正态分布随机数c2 = np.random.multivariate_normal(m_vec2, cov_vec2, 20).T# 合并构造一个3 x 40 的数据集data = np.concatenate((c1, c2), axis=1)return dataX = get_date()k = 2# ====基于线性代数实现PCA降维======
mean_X = np.mean(X, axis=1).reshape(X.shape[0], 1)
dmean_X = X - mean_X
m = dmean_X.shape[1]
C = np.dot(dmean_X, dmean_X.T) / m# 矩阵分解 奇异值,特征向量
eig_val_sc, eig_vec_sc = np.linalg.eig(C)# 从大到小特征值的k个索引
argsort_eigv = np.argsort(eig_val_sc)[-k:][::-1]
# 从大到小特征值的k个索引对应的特征向量,构造新矩阵
W = eig_vec_sc[argsort_eigv]
# 构造的新矩阵对原数据X降维
new_X = np.dot(W, X)
# 显示降维后的数据
plt.scatter(new_X.T[:, 0], new_X.T[:, 1], c='y')plt.show()
可以看到降维到2的数据,还是有明显的区分的。
sklearn-PCA
decomposition.PCA(n_components=None, copy=True, whiten=False)
from sklearn.decomposition import PCA
pca = PCA(n_components=3)
pca.fit(X)
print pca.explained_variance_ratio_
print pca.explained_variance_X_new = pca.transform(X)#实现对X的降维
n_components: PCA算法中所要保留的主成分个数n,也即保留下来的特征个数n
copy:表示是否在运行算法时,将原始训练数据复制一份。
若为True,则运行PCA算法后,原始训练数据的值不会有任何改变,因为是在原始数据的副本上进行运算;若为False,则运行PCA算法后,原始训练数据的值会改,因为是在原始数据上进行降维计算。
whiten: bool,缺省时默认为False,True使得每个特征具有相同的方差。
explained_variance_ratio_:计算了每个特征方差贡献率,所有总和为1
explained_variance_:方差值
可以看到,sklearn的效果和前面编程实现的一样。
梯度上升PCA
前面是基于矩阵分解,这个是用梯度下降:
https://www.jianshu.com/p/1e9cab07d54d
2.SVD
原理参考:https://www.cnblogs.com/pinard/p/6251584.html
这里不加证明的写出如下总结:
对于任意矩阵Amxn,其奇异值是的特征值的平方根;
的特征向量是:v1,v2,v3,则A的特征向量是:
若特征值<0,m<n时直接不取,m>n时需要根据已求出的特征向量计算正交,得出多个正交向量要正交化。
2.1SVD降维:
通常,按大小排列的奇异值,减少特别的快,在很多情况下,前10%甚至1%的奇异值的和就占了全部的奇异值之和的99%以上的比例。也就是说,我们也可以用最大的k个的奇异值和对应的左右奇异向量来近似描述矩阵。也就是说:,可以实现降维。(线性代数中,特征向量意味着方向,对应的特征值意味着矩阵在特征向量上的拉伸程度,取大的k个特征值对应的特征向量,可以近似的描述这个拉伸过程,极大程度上保存原有数据形状)
sklearn实现:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn.datasets import load_iris# ======创建数据集========
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['label'] = iris.target
df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']
labels = df.iloc[:, -1].values
data = df.iloc[:, :-1].values
samples, features = df.shape
print(samples, features)# =======这里SVD========
U, s, V = np.linalg.svd(data)# =====取前3维数据显示===========
newdata = U[:, :3]
fig = plt.figure()
ax = Axes3D(fig)# =======每个类型的形状和颜色=====
marks = ['o', '*', '+']
colors = ['r', 'b', 'g']
for i in range(samples):ax.scatter(newdata[i, 0], newdata[i, 1], newdata[i, 2], c=colors[int(labels[i])], marker=marks[int(labels[i])])plt.show()
3 LDA
LDA是一种监督学习的降维技术,也就是说它的数据集的每个样本是有类别输出的。这点和PCA不同。核心思想是投影后类内方差最小,类间方差最大,如下右图(2维到1维),显然比左图更符合这个思想,LDA就是希望降维后的数据,能最大化的满足这个。
原理介绍:https://www.cnblogs.com/pinard/p/6244265.html
考虑二类别情况:
定义均值向量:
协方差:
希望同类更近,异类更远,意味着希望如下关系尽可能大:
定义类内散度矩阵:
类间散度矩阵:
目标变成了:
对上目标进行求解,其实是转为对某矩阵的分解,我的另一个文章的最后一张图有介绍:https://blog.csdn.net/jiang425776024/article/details/87607301 ,最后会得出结论,问题的求解等价于关系,只要对其矩阵分解得到,就找到了w的解(最大维度<2)。
多分类的情况也是一样的,最后的关键也是对矩阵分解求w。
3.1LDA算法流程
有数据集:
,
希望降维到d<k;
1) 计算类内散度矩阵Sw::
2)计算类间散度矩阵Sb,u为所有样本均值向量:
3) 计算矩阵
4)矩阵分解,得到最大的d个特征值及对应的d个特征向量,得到投影矩阵W
5) 对样本集中的每一个样本特征xi转化为新的样本
6) 得到输出新样本集:
numpy实现,加强对原理的理解:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_irisiris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['label'] = iris.target
df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']
data = np.array(df.iloc[:100, [0, 1, 2, -1]])
X = data[:, :-1]
Y = data[:, -1]# 类别数
class_labels = np.unique(Y)
n_class = class_labels.shape[0]# 类均值向量
mean_vec = []
for c in range(n_class):mean_vec.append(np.mean(X[Y == class_labels[c]], axis=0))# 类内散度矩阵Sw
SW = np.zeros((3, 3))
for cl, mv in zip(class_labels, mean_vec):sc_matrix_class = np.zeros((3, 3))for row in X[Y == cl]: # 所有X中类别=cl的样本row, mv = row.reshape(3, 1), mv.reshape(3, 1)sc_matrix_class += (row - mv).dot((row - mv).T)SW += sc_matrix_class# Sb
all_mean_vec = np.mean(X, axis=0)
n_features = X.shape[1]
SB = np.zeros((n_features, n_features))
for i, mea_v in enumerate(mean_vec):n = X[Y == class_labels[i]].shape[0]mea_v = mea_v.reshape(n_features, 1)all_mean_vec = all_mean_vec.reshape(n_features, 1)SB += n * (mea_v - all_mean_vec).dot((mea_v - all_mean_vec).T)# Sw^-1 Sb矩阵分解
e_val, e_vec = np.linalg.eig(np.linalg.inv(SW).dot(SB))dindex = np.argsort(e_val)[-2:][::-1]
W = e_vec[dindex]
new_X = np.dot(W, X.T)
plt.scatter(new_X.T[:, 0], new_X.T[:, 1])
plt.show()
sklearn 实现3维到2维:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn.datasets.samples_generator import make_classificationX, 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)from sklearn.discriminant_analysis import LinearDiscriminantAnalysislda = 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()
4 MDS 流形学习(Manifold Learning)
流形学习(Manifold Learning)的一类,多维缩放MDS要求原始空间中的样本之间的距离在低维空间中保持,思想是构造距离矩阵,然后矩阵分解,和前面的降维流程基本上是一致的,只是矩阵分解时的构造不一样,没有特别之处。
具体细节参考《机器学习》周志华 P228。或者博客:https://blog.csdn.net/AI_BigData_wh/article/details/78242052
MDS流程:
sklearn API:https://scikit-learn.org/stable/modules/generated/sklearn.manifold.MDS.html
from sklearn.datasets import load_digits
from sklearn.manifold import MDS
X, _ = load_digits(return_X_y=True)
X.shapeembedding = MDS(n_components=2)
X_transformed = embedding.fit_transform(X[:100])
X_transformed.shape
4.1 Isomap 等度量映射
Isomap:通过“改造一种原本适用于欧氏空间的算法”,达到了“将流形映射到一个欧氏空间”的目的。
流形Manifold:“嵌入在高维空间中的低维流形”,最直观的例子通常都会是嵌入在三维空间中的二维或者一维流形。比如说一块布,可以把它看成一个二维平面,这是一个二维的欧氏空间,现在我们(在三维)中把它扭一扭,它就变成了一个流形(当然,不扭的时候,它也是一个流形,欧氏空间是流形的一种特殊情况)。
MDS 是针对欧氏空间设计的,对于距离的计算也是使用欧氏距离来完成的。如果数据分布在流形上欧氏距离不适用。
Isomap通过把数据点连接起来构成一个邻接 Graph 来离散地近似原来的流形,而测地距离也相应地通过 Graph 上的最短路径来近似,通过这样的距离计算,把 MDS 中原始空间中距离的计算从欧氏距离换为了流形上的测地距离。
如下图:两点间的距离不再是欧氏距离!!
算法流程: 核心就是把MDS的距离计算改为了最短路径(Dijikstra、Floyd)等算法的计算。
sklearn API:https://scikit-learn.org/stable/modules/generated/sklearn.manifold.Isomap.html#sklearn.manifold.Isomap
from sklearn.datasets import load_digits
from sklearn.manifold import Isomap
X, _ = load_digits(return_X_y=True)
X.shapeembedding = Isomap(n_components=2)
X_transformed = embedding.fit_transform(X[:100])
X_transformed.shape
Isomap等距映射算法有一个问题就是他要找所有样本全局的最优解,当数据量很大,样本维度很高时,计算非常的耗时,鉴于这个问题,出现了只关注局部的LLE
5 LLE 局部线性嵌入
局部线性嵌入(Locally Linear Embedding,以下简称LLE),也是流形学习算法,LLE关注于降维时保持样本局部的线性关系,由于LLE在降维时保持了样本的局部关系,它广泛的用于图像图像识别,高维数据可视化等领域。
参考:https://www.cnblogs.com/pinard/p/6266408.html
LLE首先假设数据在较小的局部是线性的,也就是说,某一个数据可以由它邻域中的几个样本来线性表示,如原来的线性关系:
降维后的线性关系:
也就是说降维前后(局部)线性权重不变。
sklearn API:https://scikit-learn.org/stable/modules/generated/sklearn.manifold.locally_linear_embedding.html#sklearn.manifold.locally_linear_embedding
官方例子:https://scikit-learn.org/stable/auto_examples/manifold/plot_swissroll.html#sphx-glr-auto-examples-manifold-plot-swissroll-py
6 LE 拉普拉斯特征映射
其思路和LLE很相似,也是基于图的降维算法,希望相互关联的点降维后的空间尽可能靠近,通过构建邻接矩阵,最后推导,矩阵分解等步骤,实现降维。
sklearn API:https://scikit-learn.org/stable/modules/generated/sklearn.manifold.SpectralEmbedding.html#sklearn.manifold.SpectralEmbedding
from sklearn import manifold, datasets
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3Dfig = plt.figure()
ax = Axes3D(fig)X, color = datasets.samples_generator.make_swiss_roll(n_samples=1500)se = manifold.SpectralEmbedding(n_components=2, n_neighbors=10)
Y = se.fit_transform(X)
# 原3维
# ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=color)
# 降维 2d
plt.scatter(Y[:, 0], Y[:, 1], c=color)
plt.show()
ML-降维:PCA、SVD、LDA、MDS、LLE、LE算法总结相关推荐
- 四大机器学习降维算法:PCA、LDA、LLE、Laplacian Eigenmaps
四大机器学习降维算法:PCA.LDA.LLE.Laplacian Eigenmaps 引言 机器学习领域中所谓的降维就是指采用某种映射方法,将原高维空间中的数据点映射到低维度的空间中.降维的本质是学习 ...
- 四大降维算法的比较和一些理解(PCA、LDA、LLE、LEP)
PCA Principle components analysis 主成分分析法:https://blog.csdn.net/weixin_43909872/article/details/85321 ...
- 降维(PCA和LDA)
1. 主成分分析(PCA) 1.1 主成分分析介绍 PCA是最常用的无监督线性降维方法,它的目标是通过某种线性投影,将高维的数据映射到低维的空间中,并期望在所投影的维度上数据的方差最大,以此使用较少的 ...
- 机器学习-白板推导-系列(五)笔记:降维(PCA/SVD/PCoA/PPCA)
文章目录 0 笔记说明 1 背景 1.1 样本均值 1.2 样本协方差矩阵 2 主成分分析PCA 2.1 最大投影方差 2.2 最小重构距离 2.3 总结 3 SVD分解HX 4 主坐标分析PCoA ...
- PCA、LDA、MDS、LLE、TSNE等降维算法的Python实现
整理 | 夕颜 出品 | AI科技大本营(ID:rgznai100) [导读]网上关于各种降维算法的资料参差不齐,但大部分不提供源代码.近日,有人在 GitHub 上整理了一些经典降维算法的 Demo ...
- 大数据(线性/非线性)降维方法(PCA,LDA,MDS,ISOMAP,LLE)
文章目录 数据块划分 特征分布 特征提取 PCA LDA MDS Isomap LLE 数据块划分 对于给定的数据集Magic(19020个样本,10个属性),我们首先将其划分为RSP数据块,然后再分 ...
- 线性降维:PCA、LDA、MDS
1. KNN 为什么要在介绍降维之前学习KNN呢?因为以KNN为代表的一类算法,由于其为非参数化模型,无法通过一组固定的参数和固定的模型进行表征.此外,KNN还是惰性学习算法的典型例子.惰性是指它仅仅 ...
- ML之DR:基于鸢尾花(Iris)数据集利用多种降维算法(PCA/TSVD/LDA/TSNE)实现数据降维并进行二维和三维动态可视化应用案例
ML之DR:基于鸢尾花(Iris)数据集利用多种降维算法(PCA/TSVD/LDA/TSNE)实现数据降维并进行二维和三维动态可视化应用案例 目录 基于鸢尾花(Iris)数据集利用多种降维算法(PCA ...
- 降维方法小结和理解:PCA、LDA、MDS、ISOMAP、SNE、T-SNE、AutoEncoder
PCA:Principle component analysis 主成分分析 百度百科:它是一个线性变换.这个变换把数据变换到一个新的坐标系统中,使得任何数据投影的第一大方差在第一个坐标(称为第一主成 ...
- 机器学习之降维方法(LDA、PCA)小结
1 线性判别分析(LDA) 1.1 LDA简介 LDA是一种监督学习的降维技术,也就是说它的数据集的每个样本是有类别输出的.一句话来概括LDA的核心思想,[投影后类内方差最小,类间方差最大].我们将数 ...
最新文章
- 命令行客户端MySQL基本命令的使用(登录、登出、数据库操作的SQL语句、表结构的SQL语句、表数据操作的SQL语句)
- js sdk 一键分享 微信_微信jssdk实现分享到微信
- 使PropertyGrid控件的属性值可以显示多行的方法
- java 静态方法上的泛型
- 【Linux 内核 内存管理】虚拟地址空间布局架构 ② ( 用户虚拟地址空间组成 | 内存描述符 mm_struct 结构体源码 )
- 浏览器是如何展示网页的
- 刚开始学Web前端,用什么软件好?
- 如何将现有的项目添加到远程的git库里面!
- html5jqueryl轮播图,基于JQuery的实现图片轮播效果(焦点图)
- 如何让Sublime Text2支持GBK编码
- 获取子元素上面父元素中最大的z-index(z-index在chrome的兼容问题)
- 扣丁三国 - 技术支持
- google人体浏览器+android,google人体浏览器
- rpgmv存档修改html_使用HTML5存档网站内容更改
- 从发声机理到听觉感知认识声音的本质
- 网站SEO优化的关键词密度怎么布局才算合理
- “IN-Chain全球区块链峰会”落幕 30余位大咖都说了什么
- 代码健壮性的几点思考
- 支付业务与技术架构学习总结(9)——银行核心系统之清算体系
- 基于S52单片机的温度测量与报警装置
热门文章
- Flink学习-DataStream-HDFSConnector(StreamingFileSink)
- 怎么看计算机配件型号,如何看硬件参数
- RC4原理以及Python实现
- 3NF的无损连接和保持函数依赖的分解、BCNF的无损连接的分解
- Python_静态方法
- java--for循环执行的顺序
- 嵌入式笔试面试问题总结
- java实现多元线性回归
- Ambari-2.7.5.0 + HDP-3.1.5.0网盘地址
- supersqli(SQL注入流程及常用SQL语句)