数据降维---LLE(Locally Linear Embedding)---局部线性嵌入(2)

来源:互联网 发布:尚观java就业班视频 编辑:程序博客网 时间:2024/05/29 02:10

没有办法,只能分成两个部分来写了,不然的话显示不出来, 啧啧

(3) 将样本点映射到低维空间

① 映射条件
作为LLE算法的最后一步,当将将本映射到地位空间的时候,映射条件需要满足:

公式(11)

在公式中,yi是xi对应的输出向量,且需要满足两个条件,也就是所谓的约束条件:
映射后的输出结果的重心应当在坐标原点上(MDS算法用过的哟)

这个是不是为了防止误差过大啊

② 映射条件的化简
矩阵论原理,啧啧,反正我以前不知道
对于矩阵A=[a1,a2, … ,an]始终有下列一组式子存在:

公式(12)

一个矩阵的迹(trace)等于特征值之和,另外呢,线性代数中的Tr表示对角线元素之和

假定Ii表示N*N单位矩阵的第i列,Y表示整个输出矩阵Y=[y1,y2, … ,yn],Wi表示稀疏矩阵W(由wij组成的稀疏矩阵,非邻接点都是0,所以是稀疏矩阵)的列向量。化简结果如下所示:

公式(13)

③ 利用Lagrange拉格朗日乘子再一次求最值
还记得那两个莫名其妙的约束条件了么,啧啧,采用Lagrange乘子建立拉格朗日式子,公式如下:

公式(14)

我们可以明显看到,这个就是特征值和特征向量之间的关系α,想要求解Y的值,就要求解M的特征值,进而求解对应的特征向量即可。

④ 输出整理
要让损失函数值达到最下,则选择Y作为M的最小d个非零特征值所对应的特征向量。在处理过程中,将M的特征值从小到大排列,第一个特征值几乎接近于0通常不选择第一个特征值,从而通常选择第2~d+1间的特征值所对应的特征向量作为输出向量。其中M=(1-W)(1-W)T在公式(13)明显提到过。

代码实现:

# 估计也没有人看我的代码,就丢在这吧,毕设要改进的,啧啧,第一版,无敌,网上的都是matlab的代码,所以自己写也算费了点时间# LLE函数 欲降维数据 邻接点个数 降维目标数def LLE(data, k, dimension):    # 初始化    # 距离矩阵    distanceMat=[]    # 距离排序后结果矩阵    neighborArray=[]    # 一步一步来,所以可能会有很多print输出    # sampleNumber表示数据数量    [sampleNumber,featureNumber]=data.shape    print "该组数据条目共有%d条, 数据维度(特征值)有%d个" %(sampleNumber,featureNumber)    print "1. 找到样本的k个邻近点 这里先使用L2范式求距离 创建一个结果矩阵 sampleNumber*sampleNumber大小的矩阵"    # 当为array的时候,默认d*f就是对应元素的乘积,multiply也是对应元素的乘积,dot(d,f)会转化为矩阵的乘积    # 当为mat的时候,默认d*f就是矩阵的乘积,multiply转化为对应元素的乘积,dot(d,f)为矩阵的乘积    # np.dot(data,data.transpose()) sampleNumber*sampleNumber矩阵    # np.tile(pow(lung_cleanedData, 2).sum(axis=1),(192,1)) tile创建重复数组    distanceMat=np.tile(pow(data, 2).sum(axis=1),(192,1))\        +np.tile(pow(data, 2).sum(axis=1),(192,1)).transpose()\        -2*np.dot(data,data.transpose())    # 在获得距离后,对192*192矩阵进行排序,从第2项开始找到k个邻接点(第1项为自己)    neighborArray=np.argsort(distanceMat)[:,1:k+1]    print "2. 解决权重构,也就是重修构造权值"    # 初始化    # 绝对误差限 基因特征值特别多,运行不到,后期注释掉    tol=0    # 权值初始化    W=np.zeros([sampleNumber,k])    # 稀疏矩阵初始化    WSparseMat=np.zeros([sampleNumber,sampleNumber])    # 确定绝对误差限 基因特征值特别多,运行不到,后期注释掉    if k>featureNumber:        tol=1e-3    else:        tol=0    # 遍历所有结点,针对所有结点都重新修正权值    for i in range(sampleNumber):        # 公式内部都有具体推导        # 2.1 公式5里的X-Ni 这是一个featureNumber*k矩阵 其实可以整体进行transpose转置的        X_N=np.tile(data[i],(k,1)).transpose()-data[neighborArray[i]].transpose()        # 2.2 公式5里的S 这是一个k*k矩阵 利用X_N就能运算出来 记得矩阵运算用np.dot()        S=np.dot(X_N.transpose(),X_N)        # 2.3 k>featureNumber的处理,防止他不是奇异矩阵 我觉得不用了,毕竟基因的特征值特别多,不会出现这种问题        # S=S+np.eye(k)*tol*trace(S)        # 2.4 公式9计算w矩阵 但是计算的仅仅是W中的一列 我们公式中用的均为列向量 np.linalg.inv():矩阵求逆        W[i,:]=(np.dot(np.linalg.inv(S),np.ones([k,1]))/(np.dot(np.linalg.inv(S),np.ones([k,1])).sum(axis=0))).transpose()        # 2.5 构造稀疏矩阵        WSparseMat[i][neighborArray[i]]=W[i]    print "3. 将样本点映射到低维空间"    # 初始化,单位矩阵    unitMat=np.eye(sampleNumber)    # 结果数组M    M=[]    # 3.1 公式13中M的计算公式为(I-W)'(I-W) W作为sampleNumber*sampleNumber的稀疏矩阵    M=np.dot((unitMat-WSparseMat).transpose(),(unitMat-WSparseMat))    # 3.2 求解M的特征值进而求出特征向量 np.linalg.eig()求解特征向量和特征值,贼棒    eigenvalue,eigenvector=np.linalg.eig(M)    # 3.3 按照输出整理,需要对特征值进行排序,并获取对应的特征县了刚刚,然后作为输出结果,输出结果大小应该为sampleNumber*k    sortEigenvalue=np.argsort(eigenvalue)[1:dimension+1]    sortEigenvector=eigenvector[sortEigenvalue]    Y=sortEigenvector.transpose()    return Y
原创粉丝点击