基于KLPP与PCA的数据降维方法
概述
本文将介绍两种重要的数据降维技术:主成分分析(PCA)和核局部保持投影(KLPP),并提供完整的MATLAB实现代码。这两种方法在机器学习、模式识别和计算机视觉领域有广泛应用。
核心原理
PCA (主成分分析)
- 目标:寻找数据最大方差方向,保留全局结构
- 数学原理:
- 计算协方差矩阵:\(C = \frac{1}{n} \sum_{i=1}^{n} (x_i - \mu)(x_i - \mu)^T\)
- 特征值分解:\(C = V\Lambda V^T\)
- 选择前k个最大特征值对应的特征向量作为投影矩阵
KLPP (核局部保持投影)
- 目标:保持数据局部结构,处理非线性数据
- 数学原理:
- 使用核函数将数据映射到高维空间:\(\phi: x \rightarrow \phi(x)\)
- 构建邻接图并计算权重矩阵W
- 求解广义特征值问题:\(XLX^T a = \lambda XDX^T a\)
- 选择前k个最小非零特征值对应的特征向量
MATLAB
%% PCA与KLPP降维算法实现
clear; clc; close all;
%% 加载数据
% 使用MATLAB内置鸢尾花数据集
load fisheriris;
X = meas; % 150x4数据矩阵
labels = species; % 类别标签
% 数据标准化
X = zscore(X);
fprintf('数据集信息:\n');
fprintf('样本数: %d, 特征数: %d\n', size(X,1), size(X,2));
fprintf('类别: %s, %s, %s\n\n', unique(labels));
%% PCA降维实现
function [Y, V] = my_pca(X, k)
% 输入:
% X - m x n 数据矩阵 (m样本数, n特征数)
% k - 目标维度
% 输出:
% Y - 降维后的数据 (m x k)
% V - 投影矩阵 (n x k)
% 计算均值
mu = mean(X, 1);
% 中心化数据
X_centered = X - mu;
% 计算协方差矩阵
cov_matrix = cov(X_centered);
% 特征值分解
[V, D] = eig(cov_matrix);
% 特征值排序(降序)
[~, idx] = sort(diag(D), 'descend');
V = V(:, idx);
% 选择前k个主成分
V = V(:, 1:k);
% 数据投影
Y = X_centered * V;
end
%% KLPP降维实现
function [Y, A] = my_klpp(X, k, kernel_type, sigma, neighbor_num)
% 输入:
% X - m x n 数据矩阵
% k - 目标维度
% kernel_type - 核函数类型 ('gaussian', 'linear', 'poly')
% sigma - 高斯核参数
% neighbor_num - 近邻数
% 输出:
% Y - 降维后的数据 (m x k)
% A - 投影矩阵
[m, n] = size(X);
% 1. 计算核矩阵
K = compute_kernel_matrix(X, kernel_type, sigma);
% 2. 构建邻接图
W = build_adjacency_matrix(X, neighbor_num);
% 3. 计算度矩阵D和拉普拉斯矩阵L
D = diag(sum(W, 2));
L = D - W;
% 4. 求解广义特征值问题 K*L*K'*a = λ*K*D*K'*a
A = K * L * K';
B = K * D * K';
% 处理奇异矩阵问题
B = B + 1e-6 * eye(size(B));
% 求解广义特征值问题
[eig_vecs, eig_vals] = eig(A, B);
% 特征值排序(升序)
eig_vals = diag(eig_vals);
[~, idx] = sort(eig_vals, 'ascend');
eig_vecs = eig_vecs(:, idx);
% 选择前k个特征向量(忽略零特征值)
A = eig_vecs(:, 2:k+1); % 跳过第一个特征向量
% 5. 数据投影
Y = K * A;
end
%% 核矩阵计算函数
function K = compute_kernel_matrix(X, kernel_type, sigma)
m = size(X, 1);
K = zeros(m, m);
switch kernel_type
case 'gaussian'
for i = 1:m
for j = 1:m
K(i,j) = exp(-norm(X(i,:)-X(j,:))^2/(2*sigma^2));
end
end
case 'linear'
K = X * X';
case 'poly'
% 使用二次多项式核
K = (X * X' + 1).^2;
otherwise
error('未知的核函数类型');
end
end
%% 邻接矩阵构建函数
function W = build_adjacency_matrix(X, neighbor_num)
m = size(X, 1);
W = zeros(m, m);
% 计算距离矩阵
dist_matrix = pdist2(X, X);
% 构建邻接图(无向图)
for i = 1:m
% 找到最近的k个邻居
[~, idx] = sort(dist_matrix(i,:), 'ascend');
neighbors = idx(2:neighbor_num+1); % 排除自身
% 设置权重(热核权重)
for j = neighbors
dist = dist_matrix(i,j);
W(i,j) = exp(-dist^2 / (2 * mean(dist_matrix(:))^2));
W(j,i) = W(i,j); % 对称权重
end
end
end
%% 参数设置
k = 2; % 目标维度
kernel_type = 'gaussian';
sigma = 1.5; % 高斯核参数
neighbor_num = 7; % 邻接图近邻数
%% 执行降维
% PCA降维
[Y_pca, V_pca] = my_pca(X, k);
% KLPP降维
[Y_klpp, A_klpp] = my_klpp(X, k, kernel_type, sigma, neighbor_num);
fprintf('降维完成:\n');
fprintf('PCA投影矩阵大小: %dx%d\n', size(V_pca));
fprintf('KLPP投影矩阵大小: %dx%d\n\n', size(A_klpp));
%% 结果可视化
figure('Position', [100, 100, 1200, 500]);
% 原始数据可视化
subplot(1, 3, 1);
gscatter(X(:,1), X(:,2), labels, 'rgb', 'os^', [], 'off');
title('原始数据 (前两个特征)');
xlabel('花萼长度');
ylabel('花萼宽度');
grid on;
% PCA降维结果
subplot(1, 3, 2);
gscatter(Y_pca(:,1), Y_pca(:,2), labels, 'rgb', 'os^', [], 'off');
title('PCA降维结果 (k=2)');
xlabel('主成分1');
ylabel('主成分2');
grid on;
% KLPP降维结果
subplot(1, 3, 3);
gscatter(Y_klpp(:,1), Y_klpp(:,2), labels, 'rgb', 'os^', [], 'off');
title(['KLPP降维结果 (\sigma=', num2str(sigma), ', k=', num2str(neighbor_num), ')']);
xlabel('KLPP分量1');
ylabel('KLPP分量2');
grid on;
%% 性能评估 - 降维后数据分类精度
% 使用kNN分类器评估降维效果
rng(42); % 设置随机种子
% 创建kNN分类器
knn_model = fitcknn(X, labels, 'NumNeighbors', 5);
cv_model = crossval(knn_model, 'KFold', 5);
acc_orig = 1 - kfoldLoss(cv_model);
% PCA降维数据
knn_model_pca = fitcknn(Y_pca, labels, 'NumNeighbors', 5);
cv_model_pca = crossval(knn_model_pca, 'KFold', 5);
acc_pca = 1 - kfoldLoss(cv_model_pca);
% KLPP降维数据
knn_model_klpp = fitcknn(Y_klpp, labels, 'NumNeighbors', 5);
cv_model_klpp = crossval(knn_model_klpp, 'KFold', 5);
acc_klpp = 1 - kfoldLoss(cv_model_klpp);
fprintf('分类性能评估 (5折交叉验证):\n');
fprintf('原始数据分类精度: %.4f\n', acc_orig);
fprintf('PCA降维后分类精度: %.4f\n', acc_pca);
fprintf('KLPP降维后分类精度: %.4f\n\n', acc_klpp);
%% 参数敏感性分析
% 分析不同参数对KLPP性能的影响
sigma_values = 0.5:0.5:3;
neighbor_values = 3:2:15;
acc_matrix = zeros(length(sigma_values), length(neighbor_values));
fprintf('KLPP参数敏感性分析...\n');
for i = 1:length(sigma_values)
for j = 1:length(neighbor_values)
[Y_temp, ~] = my_klpp(X, k, 'gaussian', sigma_values(i), neighbor_values(j));
knn_model = fitcknn(Y_temp, labels, 'NumNeighbors', 5);
cv_model = crossval(knn_model, 'KFold', 5);
acc_matrix(i,j) = 1 - kfoldLoss(cv_model);
end
end
% 可视化参数敏感性
figure('Name', 'KLPP参数敏感性分析');
imagesc(neighbor_values, sigma_values, acc_matrix);
colorbar;
xlabel('近邻数');
ylabel('高斯核参数 \sigma');
title('KLPP降维后分类精度');
set(gca, 'YDir', 'normal');
% 标记最佳参数
[max_acc, max_idx] = max(acc_matrix(:));
[row, col] = ind2sub(size(acc_matrix), max_idx);
hold on;
plot(neighbor_values(col), sigma_values(row), 'ro', 'MarkerSize', 10, 'LineWidth', 2);
text(neighbor_values(col)+0.5, sigma_values(row), ...
sprintf('最佳: \\sigma=%.1f, k=%d\n精度: %.4f', ...
sigma_values(row), neighbor_values(col), max_acc), ...
'VerticalAlignment', 'bottom');
代码说明
1. 核心函数实现
-
PCA函数 (
my_pca)- 数据标准化
- 计算协方差矩阵
- 特征值分解
- 选择主成分
- 数据投影
-
KLPP函数 (
my_klpp)- 核矩阵计算
- 邻接图构建
- 图拉普拉斯矩阵计算
- 广义特征值求解
- 数据投影
2. 辅助函数
compute_kernel_matrix:支持高斯核、线性核、多项式核build_adjacency_matrix:基于k近邻构建邻接图,使用热核权重
3. 实验分析
-
可视化:
- 原始数据分布
- PCA降维结果
- KLPP降维结果
-
性能评估:
- 使用kNN分类器评估降维后数据质量
- 5折交叉验证计算分类精度
-
参数敏感性分析:
- 分析不同核参数和近邻数对KLPP性能的影响
- 可视化参数组合与分类精度的关系
算法比较
| 特性 | PCA | KLPP |
|---|---|---|
| 结构保持 | 全局结构 | 局部结构 |
| 数据假设 | 线性 | 非线性 |
| 计算复杂度 | 低 | 中高 |
| 参数敏感度 | 低 | 中高 |
| 适用场景 | 高斯分布数据 | 流形结构数据 |
| 主要优势 | 计算简单,去相关 | 保持局部结构,处理非线性 |
参考代码 此算法是 基于KLPP与PCA的数据的降维的方法 www.youwenfan.com/contentcnl/81760.html,可用于图像处理和故障诊断等需要降维的应用中。
结果分析
-
可视化分析:
- PCA倾向于最大化全局方差,可能忽略局部结构
- KLPP能更好地保持数据的局部邻域关系
- 在鸢尾花数据集上,KLPP通常能实现更好的类别分离
-
性能评估:
- KLPP降维后数据通常获得更高分类精度
- PCA在计算效率上优于KLPP
- 对于线性可分数据,PCA可能足够有效
-
参数敏感性:
- KLPP性能受核参数σ和近邻数k影响显著
- 高斯核参数σ过小导致过拟合,过大导致欠拟合
- 近邻数k需要平衡局部与全局信息

浙公网安备 33010602011771号