主成分分析PCA降维--python,matlab实现高光谱数据降维

在机器学习领域中,我们对原始数据进行特征提取,有时会得到比较高维的特征向量。在这些向量所处的高维空间中,包含很多的冗余和噪声。我们希望通过降维的万式米寻找数据内部的特性,从而提升特征表达能力,降低训练复杂度。主成分分析(PrincipalComponents Analysis,PCA)作为降维中最经典的方法,至今已有100多年的历史,它属于一种线性、非监督、全局的降维算法。

PCA旨在找到数据中的主成分,并利用这些主成分表征原始数据,从而达到降维的目的。举一个简单的例子,在三维空间中有一系列数据点,这些点分布在一个过原点的平面上。如果我们用自然坐标系x,y,z三个轴来表示数据,就需要使用三个维度。而实际上,这些点只出现在一个二维平面上,如果我们通过坐标系旋转变换使得数据所在平面与xy平面重合,那么我们就可以通过x’y’两个维度表达原始数据,并且没有任何损失,这样就完成了数据的降维。而x’y’两个轴所包含的信息就是我们要找的信息。


在这里插入图片描述
第一个图是二维空间中经过中心化的一组数据,我们很容易看出主成分所在的轴(以下称为主轴)的大致方向,即第二个图中黄线所处的轴。因为在黄线所处的轴上,数据分布得更为分散,这也意味着数据在这个方向上方差更大。在信号处理领域,我们认为信号具有较大方差,噪声具有较小方差,信号与噪声之比称为信噪比。信噪比越大意味着数据的质量越好,反之,信噪比越小意味着数据的质量越差。由此我们不难引出 PCA 的目标,即最大化投影方差,也就是让数据在主轴上投影的方差最大。

python实现高光谱数据降维

import matplotlib.pyplot as plt
import numpy as np
import gdal
from sklearn.decomposition import PCA
       
filename = "xxx.tif" #自己的文件路径
data = list()
img = gdal.Open(filename)
width = img.RasterXSize
height = img.RasterYSize
print(height, width)
bands = img.RasterCount
x, y, m = 0, 0, 1
# img_data = img.ReadAsArray(x,y,int(width/m),int(height/m)).astype(np.float)
img_data = img.ReadAsArray(x,y,12,12).astype(np.float)
for i in range(bands):
    data.append(img_data[i,:,:].flatten())
data = np.mat(data).T
print("高分图像维数:",np.shape(data))

k = 4
pca = PCA()
pca.fit(data)
component = pca.components_
pdf = pca.explained_variance_ratio_
cdf = [sum(pdf[:i+1]) for i in range(len(pdf))]
plt.figure(figsize=(10, 6), dpi=100)
plt.plot(np.arange(len(pdf)),cdf)
plt.xlim((0,20))
plt.show()

matlab实现高光谱数据降维

clear;clc;
load('xxx.mat');
data = imggt
[m,n,p]=size(data);%(610,340,103)
t=m*n;%207400
data=reshape(data,t,p);%(207400,103),(样本数,波段数)
data=isinf(data);
[inf_r inf_c]=find(data==1);
data(inf_r,:)=[];
[pc,score,latent,tsquare]=pca(data);%pc为主成分系数,score为主成分的结果,latent为方差
feature_after_PCA=score(:,1:3);
RES=reshape(feature_after_PCA,m,n,3);
% imwrite(RES(:,:,1),'1.jpg');
% imwrite(RES(:,:,2),'2.jpg');
% imwrite(RES(:,:,3),'3.jpg');
imwrite(RES,'PU_pca_3.jpg')
%cumsum(latent)./sum(latent)
%ans =0.5832,0.9442,0.9886,0.9916,0.9937

这里是用mat格式的matlab可读数据,如果只有tif,想转mat可参照下面的代码。

import scipy.io as sio
import skimage.io
imgpath = r'XXX.tif'
imggt = skimage.io.imread(imgpath)
sio.savemat(r"XXX.mat", {
    
    'imggt': imggt})

猜你喜欢

转载自blog.csdn.net/weixin_45807161/article/details/123800174