主成分分析-特征向量计算改进(1.1)

本文介绍了主成分分析(PCA)的一种改进方法,用于减少大矩阵协方差计算的时间,并展示了如何利用PCA进行人脸图像的逐步重建。

一)对PCA协方差的改进  

    这两天运行着人脸识别的相关程序发现,当数据量一大的时候,比如一个样本集合,随便的就有12*6750等等,在求这个矩阵的协方差与特征向量的时候,按照上一篇的介绍:

主成分分析-简单人脸识别(二)

使用到里面的Cell_all = PCA(img,k) 函数,会发现一般运行时间都会很久,其实正常在求取大矩阵的协方差特征值与特征向量的时候确实会很麻烦,但是从数学推导上可以发现存在着快速求解的方法。一个变换原理介绍如下:

主成分分析PCA(Principal Component Analysis)介绍

在其中的第二点上就是推导变换的过程,这个过程使得求取矩阵的特征向量变快了不少。

正常情况下我们说协方差ST  = E{(xi-u)*(xi-u)T}  = X'X'T   它是一个ST是(m*n*(m*n)阶的矩阵所以计算它的特征向量比较复杂但是左如下变换后:


可以看到要计算XTX的特征值和特征向量δivi,然后就可以计算出XXT 特征值和特征向量δiXvi,而XTXN*N阶的矩阵相比(m*n*m*n)阶矩阵来说小不少,计算起来比较容易

据此我们把以前的PCA程序改为如下:

function [img_new,V] = PCA(img,k)
%reshape函数:改变句矩阵的大小,矩阵的总元素个数不能变
% img = double(img);
% tic;
[m,n] = size(img);  %取大小
img_mean = mean(img); %求每列平均值
img_mean_all = repmat(img_mean,m,1);%复制m行平均值至整个矩阵
Z = img - img_mean_all;
T=Z*Z';  %协方差矩阵  
[V,D] = eigs(T,k);%计算T中最大的前k个特征值与特征向量
V=Z'*V;         %协方差矩阵的特征向量  
for i=1:k       %特征向量单位化  
    l=norm(V(:,i));  
    V(:,i)=V(:,i)/l;  
end  
img_new = Z*V;  %低维度下的各个脸的数据
% toc;

相比以前的变化可以看到,主要是对中间的改变了下,以前的程序是这样的:

function [img_new,V] = PCA(img,k)
%reshape函数:改变句矩阵的大小,矩阵的总元素个数不能变
%img = [1,2;2,1;3,3;3,6;6,3];
% k = 2;
% img = double(img);
tic;
[m,n] = size(img);  %取大小
img_mean = mean(img); %求每列平均值
img_mean_all = repmat(img_mean,m,1);%复制m行平均值至整个矩阵
Z = img - img_mean_all;
T = Z'*Z;%协方差矩阵    
[V,D] = eigs(T,k);%计算T中最大的前k个特征值与特征向量
img_new = Z*V;  %低维度下的各个脸的数据
toc;

可以看到区别主要在T=Z*Z'; T = Z'*Z;以及后面的一点内容,这就是上述原理的部分。为了比较两者性能到底差多少,这里分别使用改与未改的来观察,使用matlab计时器tictoc如下:

改之前:

>> [img_new,V] = PCA(ImgData,10);

时间已过 3.235867 秒。

改之后:

>> [img_new,V] = PCA(ImgData,10);

时间已过 0.012895 秒。

当后面的10变为50或者100,那么第一种方法求取的时间将会超过100多秒,等不住了。但是这个改变的前提是后面的k=10必须小于矩阵的行与列数,这就带来一个不足,比如如果来个样本集合为12*6750的时候,这个k最大只能是12了,也就是说最大只能降维到12,想在大一些就不可以了,但是第一种情况最大可以降维到6750维。也就是说改进的降维最大数为样本的数量(这里为12)。但是一般样本会很多,应该会超过你需要降维的维数。

    会想到这种快速改进的区别是看到一篇不同的博客,研究半天才知道

Matlab PCA+SVM人脸识别(一)


二)关于样本脸的重建

就这上面给的一篇博客中最后一点写到关于如何去重建的原始图像的程序,感觉有点明白且做了下,感觉挺有意思的。

运行人脸识别(二)中的程序

>>ImgData = imgdata();

导入人脸数据,出来ImgData12*6750的矩阵,运行改进的PCA程序,

>>[img_new,V] = PCA(ImgData,12);

这个时候最大只能降到12维了,不知道够不够,但是样本量就这么多,先这么着看看吧。得到降维后的矩阵与特征向量,假如这里来重建第一副图像,取

Img1 = img_new(1,:);

这里img1就变成了1*12的数列,假设就是[1 2 3 4 5 6 7 8 9 10 11 12];

想想这些数列是怎么来的?比如1就是原始样本矩阵乘以第一主成分特征向量所得,那么重构后就得包括是1*V1,同理重构后的数据也得包括2*V2,等等。

这样就可以把相应位置的数据累加起来就是原始样本在该位置的值。程序与显示如下:

[m,n] = size(ImgData);  %取大小
img_mean = mean(ImgData); %求每列平均值  1*6750
for i = 1:12
    img_mean = img_mean + img_new(1,i)*V(:,i)';
    B=reshape(img_mean,90,75);
    subplot(2,6,i);imshow(B,[]);
end

运行后的结果为:


照片显示从一次两次一直到12次的重建过程,效果是越来越好吧。



### 数据加载与预处理 首先,加载PaviaU高光谱影像(PaviaU.mat)与其地物类别标注(PaviaU_gt.mat)。接着,对每个有标注的像素点提取光谱特征,并建立特征 - 标签样本集。之后,使用标准化(StandardScaler)处理特征数据,使不同波段的数值分布一致。最后,进行主成分分析(PCA),将原始高维特征降至10 - 100维以减少计算复杂度和冗余。 ```python import numpy as np from scipy.io import loadmat from sklearn.preprocessing import StandardScaler from sklearn.decomposition import PCA # 数据加载 def load_paviau_data(): data = loadmat('PaviaU.mat') labels = loadmat('PaviaU_gt.mat') X = data['paviaU'] # 高光谱影像数据 y = labels['paviaU_gt'] # 地物类别标注 return X, y # 提取光谱特征建立样本集 def extract_features(X, y): h, w, b = X.shape X_flat = X.reshape(-1, b) y_flat = y.flatten() # 去除标签为0的样本(通常表示未标注区域) valid_indices = y_flat != 0 X_valid = X_flat[valid_indices] y_valid = y_flat[valid_indices] return X_valid, y_valid # 标准化处理特征数据 def standardize_features(X): scaler = StandardScaler() X_scaled = scaler.fit_transform(X) return X_scaled # PCA主成分分析降维至指定维度 def pca_dim_reduction(X, n_components=10): pca = PCA(n_components=n_components) X_pca = pca.fit_transform(X) return X_pca X, y = load_paviau_data() X_features, y_labels = extract_features(X, y) X_scaled = standardize_features(X_features) X_reduced = pca_dim_reduction(X_scaled, n_components=50) ``` ### 数据集划分 使用`sklearn.model_selection`中的`train_test_split`函数将数据集划分为训练集和测试集。 ```python from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X_reduced, y_labels, test_size=0.2, random_state=42) ``` ### 多模型分类与参数自动调优 选择多种分类模型,如支持向量机(SVM)、随机森林(Random Forest)等,并使用`GridSearchCV`进行参数自动调优。 ```python from sklearn.svm import SVC from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import GridSearchCV # 支持向量机 param_grid_svm = { 'C': [0.1, 1, 10], 'kernel': ['linear', 'rbf'] } svm = SVC() grid_search_svm = GridSearchCV(svm, param_grid_svm, cv=3) grid_search_svm.fit(X_train, y_train) best_svm = grid_search_svm.best_estimator_ # 随机森林 param_grid_rf = { 'n_estimators': [50, 100, 200], 'max_depth': [None, 10, 20] } rf = RandomForestClassifier() grid_search_rf = GridSearchCV(rf, param_grid_rf, cv=3) grid_search_rf.fit(X_train, y_train) best_rf = grid_search_rf.best_estimator_ ``` ### 评估指标计算与可视化分析 计算分类模型的评估指标,如准确率、精确率、召回率、F1值等,并使用`matplotlib`进行可视化分析。 ```python from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score import matplotlib.pyplot as plt import seaborn as sns from sklearn.metrics import confusion_matrix # 预测 y_pred_svm = best_svm.predict(X_test) y_pred_rf = best_rf.predict(X_test) # 计算评估指标 accuracy_svm = accuracy_score(y_test, y_pred_svm) precision_svm = precision_score(y_test, y_pred_svm, average='weighted') recall_svm = recall_score(y_test, y_pred_svm, average='weighted') f1_svm = f1_score(y_test, y_pred_svm, average='weighted') accuracy_rf = accuracy_score(y_test, y_pred_rf) precision_rf = precision_score(y_test, y_pred_rf, average='weighted') recall_rf = recall_score(y_test, y_pred_rf, average='weighted') f1_rf = f1_score(y_test, y_pred_rf, average='weighted') print(f"SVM - Accuracy: {accuracy_svm}, Precision: {precision_svm}, Recall: {recall_svm}, F1: {f1_svm}") print(f"RF - Accuracy: {accuracy_rf}, Precision: {precision_rf}, Recall: {recall_rf}, F1: {f1_rf}") # 绘制混淆矩阵 cm_svm = confusion_matrix(y_test, y_pred_svm) cm_rf = confusion_matrix(y_test, y_pred_rf) plt.figure(figsize=(12, 6)) plt.subplot(1, 2, 1) sns.heatmap(cm_svm, annot=True, fmt='d', cmap='Blues') plt.title('SVM Confusion Matrix') plt.subplot(1, 2, 2) sns.heatmap(cm_rf, annot=True, fmt='d', cmap='Blues') plt.title('Random Forest Confusion Matrix') plt.show() ``` ### 结果分析与总结 根据评估指标和可视化结果,分析不同模型的性能表现。比较各个模型的准确率、精确率、召回率和F1值,判断哪个模型在PaviaU高光谱影像分类任务中表现更好。同时,观察混淆矩阵,分析模型在哪些类别上容易出现误分类,为后续的模型改进提供依据。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值