一、数据准备与预处理
数据加载
Indian Pines数据集包含145×145像素的高光谱图像(200个波段)和对应的地面真值标签(16类)。
% 加载数据(需提前下载Indian_pines_corrected.mat和Indian_pines_gt.mat) data = load('Indian_pines_corrected.mat'); % 三维矩阵 (145x145x200) labels = load('Indian_pines_gt.mat'); % 标签矩阵 (145x145)数据清洗
移除无效标签(标签为0的像素),并将三维数据转换为二维样本矩阵:
% 将三维数据展平为二维矩阵 (样本数×波段数) [rows, cols, bands] = size(data); data_reshaped = reshape(data, rows*cols, bands); % 提取有效标签并转换为分类类型 valid_indices = labels > 0; labels_clean = labels(valid_indices); labels_clean(labels_clean == 0) = []; % 移除标签为0的样本 data_clean = data_reshaped(valid_indices, :);数据标准化
对光谱特征进行Z-score标准化:
mu = mean(data_clean, 1); sigma = std(data_clean, 0, 1); data_normalized = (data_clean - mu) ./ sigma;
二、PCA降维实现
协方差矩阵与特征分解
[coeff, score, latent] = pca(data_normalized); % coeff为主成分系数,score为投影数据 explained = 100 * cumsum(latent) / sum(latent); % 累计解释方差比例选择主成分数量
保留90%以上方差的主成分(通常选择40-60维):
n_components = find(explained >= 90, 1); % 找到满足条件的第一个索引 data_pca = score(:, 1:n_components); % 降维后的数据可视化主成分贡献率
figure; plot(1:n_components, explained(1:n_components), '-o'); xlabel('主成分数量'); ylabel('累计解释方差 (%)'); title('PCA方差贡献率'); grid on;
三、分类模型训练与评估
数据集划分
% 划分训练集和测试集(70%训练,30%测试) cv = cvpartition(labels_clean, 'HoldOut', 0.3); train_data = data_pca(cv.training,:); train_labels = labels_clean(cv.training); test_data = data_pca(cv.test,:); test_labels = labels_clean(cv.test);分类器选择与训练
支持向量机(SVM)
model = fitcecoc(train_data, train_labels, 'Learners', 'svm', 'Coding', 'onevsall');随机森林(Random Forest)
model = fitrensemble(train_data, train_labels, 'Method', 'Bag', 'NumLearningCycles', 100);
性能评估
% 预测 predicted_labels = predict(model, test_data); % 计算准确率 accuracy = sum(predicted_labels == test_labels) / numel(test_labels); fprintf('分类准确率: %.2f%% ', accuracy*100); % 混淆矩阵 cm = confusionmat(test_labels, predicted_labels); figure; confusionchart(cm); title('混淆矩阵');
四、完整MATLAB代码示例
%% 数据加载与预处理
data = load('Indian_pines_corrected.mat'); % 三维高光谱数据
labels = load('Indian_pines_gt.mat'); % 标签矩阵
% 数据清洗
[rows, cols, bands] = size(data);
data_reshaped = reshape(data, rows*cols, bands);
valid_indices = labels > 0;
data_clean = data_reshaped(valid_indices, :);
labels_clean = labels(valid_indices);
% 数据标准化
mu = mean(data_clean, 1);
sigma = std(data_clean, 0, 1);
data_normalized = (data_clean - mu) ./ sigma;
%% PCA降维
[coeff, score, latent] = pca(data_normalized);
explained = 100 * cumsum(latent) / sum(latent);
n_components = find(explained >= 90, 1);
data_pca = score(:, 1:n_components);
%% 分类模型训练
cv = cvpartition(labels_clean, 'HoldOut', 0.3);
train_data = data_pca(cv.training,:);
train_labels = labels_clean(cv.training);
test_data = data_pca(cv.test,:);
test_labels = labels_clean(cv.test);
% 使用SVM分类器
model = fitcecoc(train_data, train_labels, 'Learners', 'svm', 'Coding', 'onevsall');
%% 性能评估
predicted_labels = predict(model, test_data);
accuracy = sum(predicted_labels == test_labels) / numel(test_labels);
fprintf('分类准确率: %.2f%%
', accuracy*100);
% 可视化混淆矩阵
cm = confusionmat(test_labels, predicted_labels);
figure;
confusionchart(cm);
title('混淆矩阵');
五、结果优化策略
主成分数量调优
通过网格搜索选择最优主成分数量(如20-100维):
accuracy_list = zeros(1, 50); for k = 1:50 data_pca = score(:, 1:k); model = fitcecoc(data_pca, labels_clean); predicted_labels = predict(model, data_pca); accuracy_list(k) = sum(predicted_labels == labels_clean)/numel(labels_clean); end [~, best_k] = max(accuracy_list);分类器参数优化
使用交叉验证调整SVM参数(如惩罚因子C和核函数):
% 定义参数网格 tuneTable = optimizableVariable('C', [0.1, 100], 'Transform', 'log'); tuneTable = [tuneTable; optimizableVariable('KernelFunction', { 'linear', 'rbf'})]; % 贝叶斯优化 results = bayesopt(@(params) svm_evaluate(params, train_data, train_labels), tuneTable); best_params = results.XAtMinObjective;特征选择增强
结合ANOVA或互信息筛选重要波段:
% 使用ANOVA选择前50个显著波段 [~, idx] = mrmr_classif(data_clean, labels_clean, 50); data_selected = data_clean(:, idx);
参考代码 PCA_进行indian_pines数据集合分类 www.youwenfan.com/contentald/59763.html
六、可视化分析
主成分投影可视化
% 选择前3个主成分进行3D可视化 figure; scatter3(data_pca(:,1), data_pca(:,2), data_pca(:,3), 10, labels_clean, 'filled'); colormap(jet(16)); colorbar; title('前3个主成分投影');分类结果空间分布
% 生成分类图(需将降维结果映射回图像空间) [m, n] = size(data(:,:,1)); classification_map = reshape(predicted_labels, m, n); figure; imagesc(classification_map); colormap(jet(16)); colorbar; title('分类结果空间分布');
七、关键问题与解决方案
类别不平衡
问题:某些类别样本过少(如"Stone Steel Towers"仅93个样本)
方案:使用
fitcecoc的Prior参数调整类别权重model = fitcecoc(train_data, train_labels, 'Prior', 'uniform');
高维小样本
- 问题:降维后特征仍可能超过样本数
- 方案:使用核PCA(
fitckernelpca)或结合LDA进行监督降维
计算效率
- 问题:200维原始数据计算协方差矩阵耗时
- 方案:使用增量PCA(
incrementalPCA)分块处理
八、扩展应用
多传感器融合
将PCA降维后的光谱特征与纹理特征(GLCM)拼接,提升分类精度:
% 计算灰度共生矩阵(GLCM) glcm = graycomatrix(im2uint8(rgbImg), 'NumLevels', 16); stats = graycoprops(glcm, { 'Contrast', 'Correlation'}); texture_features = [stats.Contrast, stats.Correlation];迁移学习
使用预训练的CNN模型提取空间特征,结合PCA光谱特征进行联合分类
九、总结
通过MATLAB实现PCA对Indian Pines数据集的分类,核心步骤包括:
- 数据标准化与PCA降维(保留90%方差)
- 使用SVM或随机森林进行多类分类
- 通过混淆矩阵和准确率评估性能
优化方向:
- 结合核方法(如Kernel PCA)处理非线性可分数据
- 引入深度学习模型(如CNN)提升复杂场景下的分类精度