基于流形学习的无监督降维算法
1. 主程序:流形学习降维工具箱
%% 流形学习降维工具箱主程序
clear; close all; clc;
%% 参数设置
disp('=== 流形学习降维工具箱 ===');
% 数据集选项
dataset_type = 'swiss_roll'; % 'swiss_roll', 's_curve', 'helix', 'iris', 'mnist', 'custom'
n_samples = 1000; % 样本数量
noise_level = 0.1; % 噪声水平 (0-1)
% 算法参数
target_dim = 2; % 目标维度
k_neighbors = 10; % 近邻数
epsilon = 0.5; % 邻域半径(用于Isomap)
% 算法选择(可以运行多个算法进行对比)
algorithms = {'Isomap', 'LLE', 'Laplacian', 'HessianLLE', 'LTSA', 'MVU', 'DiffusionMaps'};
run_all = true; % 运行所有算法
selected_algorithms = {'Isomap', 'LLE', 'Laplacian', 'DiffusionMaps'}; % 如果run_all=false时选择
% 可视化选项
plot_original = true; % 绘制原始高维数据(如果可能)
plot_embeddings = true; % 绘制降维结果
plot_comparison = true; % 绘制算法对比
compute_quality = true; % 计算降维质量指标
save_results = true; % 保存结果
%% 生成或加载数据集
disp('=== 准备数据集 ===');
[X, labels, dataset_name, original_dim] = prepare_dataset(dataset_type, n_samples, noise_level);
disp(['数据集: ', dataset_name]);
disp(['样本数: ', num2str(size(X,1))]);
disp(['原始维度: ', num2str(original_dim)]);
disp(['目标维度: ', num2str(target_dim)]);
%% 可视化原始数据(如果维度<=3)
if plot_original && original_dim <= 3
figure('Position', [100, 100, 800, 600]);
plot_original_data(X, labels, original_dim, dataset_name);
end
%% 运行流形学习算法
disp('=== 运行流形学习算法 ===');
% 确定要运行的算法
if run_all
alg_to_run = algorithms;
else
alg_to_run = selected_algorithms;
end
% 存储结果
results = struct();
timings = zeros(length(alg_to_run), 1);
quality_scores = struct();
% 进度条
h = waitbar(0, '运行流形学习算法...');
for i = 1:length(alg_to_run)
algorithm = alg_to_run{i};
waitbar(i/length(alg_to_run), h, ['运行算法: ', algorithm]);
disp(['运行 ', algorithm, '...']);
% 记录开始时间
tic;
% 运行对应算法
switch algorithm
case 'Isomap'
Y = isomap_embedding(X, target_dim, k_neighbors, epsilon);
case 'LLE'
Y = lle_embedding(X, target_dim, k_neighbors);
case 'Laplacian'
Y = laplacian_eigenmaps_embedding(X, target_dim, k_neighbors);
case 'HessianLLE'
Y = hessian_lle_embedding(X, target_dim, k_neighbors);
case 'LTSA'
Y = ltsa_embedding(X, target_dim, k_neighbors);
case 'MVU'
Y = mvu_embedding(X, target_dim, k_neighbors);
case 'DiffusionMaps'
Y = diffusion_maps_embedding(X, target_dim, k_neighbors);
case 'tSNE'
Y = tsne_embedding(X, target_dim);
case 'UMAP'
Y = umap_embedding(X, target_dim, k_neighbors);
otherwise
warning(['未知算法: ', algorithm]);
continue;
end
% 记录时间
timings(i) = toc;
% 存储结果
results(i).algorithm = algorithm;
results(i).embedding = Y;
results(i).time = timings(i);
% 计算质量指标(如果启用)
if compute_quality
[trustworthiness, continuity, mrre] = compute_quality_metrics(X, Y, k_neighbors);
results(i).trustworthiness = trustworthiness;
results(i).continuity = continuity;
results(i).mrre = mrre;
end
disp([algorithm, ' 完成,耗时: ', num2str(timings(i), '%.2f'), ' 秒']);
end
close(h);
%% 可视化降维结果
if plot_embeddings
disp('=== 可视化降维结果 ===');
% 确定子图布局
n_algs = length(alg_to_run);
n_cols = min(3, n_algs);
n_rows = ceil(n_algs / n_cols);
figure('Position', [50, 50, 1400, 800]);
for i = 1:n_algs
subplot(n_rows, n_cols, i);
Y = results(i).embedding;
alg_name = results(i).algorithm;
% 绘制嵌入结果
if target_dim == 1
% 一维情况
scatter(Y, zeros(size(Y)), 30, labels, 'filled');
xlabel('嵌入维度 1');
ylim([-0.1, 0.1]);
elseif target_dim == 2
% 二维情况
scatter(Y(:,1), Y(:,2), 30, labels, 'filled');
xlabel('嵌入维度 1');
ylabel('嵌入维度 2');
elseif target_dim == 3
% 三维情况
scatter3(Y(:,1), Y(:,2), Y(:,3), 30, labels, 'filled');
xlabel('嵌入维度 1');
ylabel('嵌入维度 2');
zlabel('嵌入维度 3');
view(3);
end
title([alg_name, sprintf('\n时间: %.2fs', results(i).time)]);
% 添加质量指标(如果计算了)
if compute_quality
txt = sprintf('T=%.3f\nC=%.3f', ...
results(i).trustworthiness, results(i).continuity);
text(0.02, 0.98, txt, 'Units', 'normalized', ...
'VerticalAlignment', 'top', 'BackgroundColor', 'white');
end
axis equal tight;
grid on;
end
sgtitle([dataset_name, ' - 流形学习降维结果 (目标维度=', num2str(target_dim), ')'], ...
'FontSize', 14, 'FontWeight', 'bold');
end
%% 算法对比分析
if plot_comparison && length(alg_to_run) > 1
disp('=== 生成算法对比图 ===');
% 对比图1:性能指标雷达图
if compute_quality
figure('Position', [100, 100, 1000, 800]);
% 准备数据
alg_names = {results.algorithm};
n_algs = length(alg_names);
% 质量指标
trust_scores = [results.trustworthiness];
cont_scores = [results.continuity];
mrre_scores = [results.mrre];
time_scores = [results.time];
% 归一化(越高越好,除了时间和MRRE)
trust_norm = trust_scores / max(trust_scores);
cont_norm = cont_scores / max(cont_scores);
mrre_norm = 1 - (mrre_scores / max(mrre_scores)); % MRRE越低越好
time_norm = 1 - (time_scores / max(time_scores)); % 时间越短越好
% 创建雷达图
categories = {'可信度', '连续性', 'MRRE', '速度'};
data = [trust_norm; cont_norm; mrre_norm; time_norm];
subplot(2,2,1);
spider_plot(data, categories, alg_names);
title('算法性能雷达图(归一化)');
% 对比图2:质量指标柱状图
subplot(2,2,2);
bar_data = [trust_scores; cont_scores; mrre_scores]';
bar(bar_data);
xlabel('算法');
ylabel('分数');
title('降维质量指标对比');
legend('可信度', '连续性', 'MRRE', 'Location', 'best');
set(gca, 'XTickLabel', alg_names);
grid on;
% 对比图3:运行时间
subplot(2,2,3);
bar([results.time]);
xlabel('算法');
ylabel('时间 (秒)');
title('算法运行时间');
set(gca, 'XTickLabel', alg_names);
grid on;
% 对比图4:降维结果投影(前两个维度)
subplot(2,2,4);
hold on;
colors = lines(n_algs);
for i = 1:n_algs
Y = results(i).embedding;
if size(Y,2) >= 2
scatter(Y(:,1), Y(:,2), 20, colors(i,:), 'filled', ...
'DisplayName', alg_names{i});
end
end
hold off;
xlabel('嵌入维度 1');
ylabel('嵌入维度 2');
title('算法结果对比(前两维)');
legend('Location', 'best');
axis equal tight;
grid on;
sgtitle('流形学习算法对比分析', 'FontSize', 14, 'FontWeight', 'bold');
end
end
%% 高级分析:参数敏感性分析
disp('=== 参数敏感性分析 ===');
if strcmp(dataset_type, 'swiss_roll') || strcmp(dataset_type, 's_curve')
analyze_parameter_sensitivity(X, labels, target_dim, dataset_name);
end
%% 保存结果
if save_results
results_dir = 'Manifold_Learning_Results/';
if ~exist(results_dir, 'dir')
mkdir(results_dir);
end
% 保存所有结果
save([results_dir, 'manifold_learning_results.mat'], ...
'X', 'labels', 'results', 'target_dim', ...
'k_neighbors', 'dataset_name', 'original_dim');
% 保存降维后的数据
for i = 1:length(results)
alg_name = results(i).algorithm;
Y = results(i).embedding;
% 保存为文本文件
filename = [results_dir, 'embedding_', alg_name, '.txt'];
dlmwrite(filename, Y, 'delimiter', '\t', 'precision', '%.6f');
end
% 生成报告
generate_manifold_learning_report(results_dir, results, X, dataset_name);
disp(['结果已保存至: ', results_dir]);
end
disp('=== 流形学习降维完成 ===');
2. 数据集准备函数
function [X, labels, dataset_name, original_dim] = prepare_dataset(dataset_type, n_samples, noise_level)
% 准备数据集
% 输入:
% dataset_type - 数据集类型
% n_samples - 样本数量
% noise_level - 噪声水平
% 输出:
% X - 数据矩阵 (n_samples × original_dim)
% labels - 标签(用于着色)
% dataset_name - 数据集名称
% original_dim - 原始维度
switch dataset_type
case 'swiss_roll'
% Swiss Roll 数据集
[X, labels] = generate_swiss_roll(n_samples, noise_level);
dataset_name = 'Swiss Roll';
original_dim = 3;
case 's_curve'
% S-曲线数据集
[X, labels] = generate_s_curve(n_samples, noise_level);
dataset_name = 'S-Curve';
original_dim = 3;
case 'helix'
% 螺旋线数据集
[X, labels] = generate_helix(n_samples, noise_level);
dataset_name = 'Helix';
original_dim = 3;
case 'iris'
% Iris 数据集
load fisheriris;
X = meas;
labels = grp2idx(species);
dataset_name = 'Iris Dataset';
original_dim = size(X, 2);
case 'mnist'
% MNIST数据集(简化版)
[X, labels] = load_mnist_subset(n_samples);
dataset_name = 'MNIST Digits';
original_dim = size(X, 2);
case 'custom'
% 自定义数据集
% 从文件加载
data = load('custom_data.mat');
X = data.X;
labels = data.labels;
dataset_name = 'Custom Dataset';
original_dim = size(X, 2);
otherwise
error('未知的数据集类型');
end
% 确保X是双精度
X = double(X);
% 归一化(可选)
X = (X - mean(X)) ./ std(X);
% 如果没有标签,使用索引作为标签
if isempty(labels)
labels = 1:size(X,1);
end
end
function [X, t] = generate_swiss_roll(n_samples, noise_level)
% 生成Swiss Roll数据集
t = 3*pi/2 * (1 + 2*rand(n_samples, 1));
height = 21 * rand(n_samples, 1);
X = zeros(n_samples, 3);
X(:,1) = t .* cos(t);
X(:,2) = height;
X(:,3) = t .* sin(t);
% 添加噪声
if noise_level > 0
X = X + noise_level * randn(size(X));
end
% 标签(基于参数t)
t = t / max(t); % 归一化作为标签
end
function [X, t] = generate_s_curve(n_samples, noise_level)
% 生成S-曲线数据集
t = 3 * pi * (rand(n_samples, 1) - 0.5);
X = zeros(n_samples, 3);
X(:,1) = sin(t);
X(:,2) = 2 * rand(n_samples, 1);
X(:,3) = sign(t) .* (cos(t) - 1);
% 添加噪声
if noise_level > 0
X = X + noise_level * randn(size(X));
end
% 标签(基于参数t)
t = (t - min(t)) / (max(t) - min(t)); % 归一化作为标签
end
function [X, t] = generate_helix(n_samples, noise_level)
% 生成螺旋线数据集
t = linspace(0, 4*pi, n_samples)';
X = zeros(n_samples, 3);
X(:,1) = cos(t);
X(:,2) = sin(t);
X(:,3) = 0.1 * t;
% 添加噪声
if noise_level > 0
X = X + noise_level * randn(size(X));
end
% 标签(基于参数t)
t = t / max(t); % 归一化作为标签
end
function [X, labels] = load_mnist_subset(n_samples)
% 加载MNIST子集
% 注意:需要MNIST数据集文件
try
% 尝试加载MNIST数据集
load('mnist.mat'); % 假设有mnist.mat文件
if n_samples > size(images, 1)
n_samples = size(images, 1);
end
% 随机选择样本
idx = randperm(size(images, 1), n_samples);
X = double(images(idx, :));
labels = double(labels(idx));
catch
% 如果无法加载,使用随机数据模拟
warning('无法加载MNIST数据集,使用模拟数据');
X = randn(n_samples, 784);
labels = randi(10, n_samples, 1);
end
end
3. Isomap算法实现
function Y = isomap_embedding(X, target_dim, k_neighbors, epsilon)
% Isomap (等距映射) 算法
% 输入:
% X - 高维数据矩阵 (n×d)
% target_dim - 目标维度
% k_neighbors - 近邻数
% epsilon - 邻域半径
% 输出:
% Y - 低维嵌入 (n×target_dim)
[n, ~] = size(X);
% 步骤1:计算距离矩阵
disp(' Isomap: 计算距离矩阵...');
D = pdist2(X, X); % 欧氏距离矩阵
% 步骤2:构建邻域图
disp(' Isomap: 构建邻域图...');
if k_neighbors > 0
% k近邻方法
G = zeros(n);
for i = 1:n
[~, idx] = sort(D(i,:));
neighbors = idx(2:k_neighbors+1); % 排除自身
G(i, neighbors) = D(i, neighbors);
G(neighbors, i) = D(neighbors, i);
end
else
% epsilon邻域方法
G = D .* (D <= epsilon);
G = G + diag(inf(n,1)); % 对角线设为无穷大
end
% 步骤3:计算最短路径距离(Floyd-Warshall算法)
disp(' Isomap: 计算最短路径...');
DG = graph(G);
distances = distances(DG); % 计算所有点对之间的最短路径
% 处理无穷大距离(不连通的点)
inf_indices = isinf(distances);
if any(inf_indices(:))
warning('Isomap: 图不连通,用最大有限距离填充');
max_finite = max(distances(~inf_indices));
distances(inf_indices) = max_finite * 2;
end
% 步骤4:多维缩放(MDS)
disp(' Isomap: 执行多维缩放...');
Y = classical_mds(distances, target_dim);
end
function Y = classical_mds(D, target_dim)
% 经典多维缩放
% 输入:距离矩阵 D (n×n),目标维度 target_dim
% 输出:嵌入 Y (n×target_dim)
n = size(D, 1);
% 双中心化
J = eye(n) - ones(n)/n;
B = -0.5 * J * (D.^2) * J;
% 特征值分解
[V, Lambda] = eig(B);
lambda = diag(Lambda);
% 按特征值降序排序
[lambda_sorted, idx] = sort(lambda, 'descend');
V_sorted = V(:, idx);
% 选择前target_dim个正特征值
positive_idx = lambda_sorted > 1e-10;
lambda_pos = lambda_sorted(positive_idx);
V_pos = V_sorted(:, positive_idx);
if length(lambda_pos) < target_dim
warning('MDS: 正特征值数量不足,使用所有特征值');
target_dim = length(lambda_pos);
end
% 构造嵌入
Y = V_pos(:, 1:target_dim) * diag(sqrt(lambda_pos(1:target_dim)));
end
4. LLE算法实现
function Y = lle_embedding(X, target_dim, k_neighbors)
% LLE (局部线性嵌入) 算法
% 输入:
% X - 高维数据矩阵 (n×d)
% target_dim - 目标维度
% k_neighbors - 近邻数
% 输出:
% Y - 低维嵌入 (n×target_dim)
[n, d] = size(X);
% 步骤1:寻找每个点的k个最近邻
disp(' LLE: 寻找最近邻...');
[idx, dist] = knnsearch(X, X, 'K', k_neighbors+1);
idx = idx(:, 2:end); % 排除自身
% 步骤2:计算重构权重矩阵 W
disp(' LLE: 计算重构权重...');
W = zeros(n, n);
tol = 1e-3;
for i = 1:n
% 获取邻居
neighbors = idx(i, :);
% 计算局部协方差矩阵
Z = X(neighbors, :) - repmat(X(i, :), k_neighbors, 1);
C = Z * Z';
% 正则化(防止奇异性)
C = C + tol * trace(C) * eye(k_neighbors) / k_neighbors;
% 求解权重(约束:权重和为1)
w = C \ ones(k_neighbors, 1);
w = w / sum(w);
% 存储权重
W(i, neighbors) = w';
end
% 步骤3:计算低维嵌入
disp(' LLE: 计算低维嵌入...');
M = (eye(n) - W)' * (eye(n) - W);
% 特征值分解,排除最小的特征值(对应平移自由度)
[V, Lambda] = eig(M);
lambda = diag(Lambda);
% 按特征值升序排序
[lambda_sorted, idx_sort] = sort(lambda);
V_sorted = V(:, idx_sort);
% 选择第2到第target_dim+1小的特征值对应的特征向量
Y = V_sorted(:, 2:target_dim+1)';
% 确保嵌入是实数的
Y = real(Y)';
end
5. 拉普拉斯特征映射算法
function Y = laplacian_eigenmaps_embedding(X, target_dim, k_neighbors)
% 拉普拉斯特征映射算法
% 输入:
% X - 高维数据矩阵 (n×d)
% target_dim - 目标维度
% k_neighbors - 近邻数
% 输出:
% Y - 低维嵌入 (n×target_dim)
[n, ~] = size(X);
% 步骤1:构建邻接图
disp(' Laplacian: 构建邻接图...');
% 计算距离矩阵
D = pdist2(X, X);
% 构建k近邻图
W = zeros(n);
for i = 1:n
[~, idx] = sort(D(i,:));
neighbors = idx(2:k_neighbors+1);
% 热核权重(高斯核)
sigma = mean(D(i, neighbors));
weights = exp(-D(i, neighbors).^2 / (2*sigma^2));
W(i, neighbors) = weights;
W(neighbors, i) = weights;
end
% 步骤2:计算拉普拉斯矩阵
disp(' Laplacian: 计算拉普拉斯矩阵...');
D_mat = diag(sum(W, 2));
L = D_mat - W; % 未归一化拉普拉斯矩阵
% 步骤3:广义特征值问题
disp(' Laplacian: 求解特征值问题...');
% 求解 Lv = λDv 的最小特征值
[V, Lambda] = eig(L, D_mat);
lambda = diag(Lambda);
% 排除零特征值(对应常数特征向量)
[lambda_sorted, idx] = sort(lambda);
V_sorted = V(:, idx);
% 选择第2到第target_dim+1小的特征值对应的特征向量
Y = V_sorted(:, 2:target_dim+1);
% 归一化嵌入
Y = Y ./ sqrt(sum(Y.^2, 1));
end
6. 扩散映射算法
function Y = diffusion_maps_embedding(X, target_dim, k_neighbors)
% 扩散映射算法
% 输入:
% X - 高维数据矩阵 (n×d)
% target_dim - 目标维度
% k_neighbors - 近邻数
% 输出:
% Y - 低维嵌入 (n×target_dim)
[n, ~] = size(X);
% 步骤1:构建亲和矩阵
disp(' Diffusion Maps: 构建亲和矩阵...');
% 计算距离矩阵
D = pdist2(X, X);
% 计算核宽度(中位数启发式)
sigma = median(D(:)) / sqrt(2);
% 构建高斯核矩阵
K = exp(-D.^2 / (2*sigma^2));
% 步骤2:计算扩散矩阵
disp(' Diffusion Maps: 计算扩散矩阵...');
% 行归一化得到扩散矩阵
P = diag(1./sum(K, 2)) * K;
% 步骤3:计算扩散距离的特征映射
disp(' Diffusion Maps: 计算特征映射...');
% 对称化:P_sym = D^{1/2} P D^{-1/2}
D_sqrt = diag(sqrt(sum(K, 2)));
D_inv_sqrt = diag(1./sqrt(sum(K, 2)));
P_sym = D_sqrt * P * D_inv_sqrt;
% 特征值分解
[V, Lambda] = eig(P_sym);
lambda = diag(Lambda);
% 按特征值降序排序
[lambda_sorted, idx] = sort(lambda, 'descend');
V_sorted = V(:, idx);
% 选择前target_dim个特征向量(排除第一个特征值1)
Y_sym = V_sorted(:, 2:target_dim+1);
% 转换回原始空间
Y = D_inv_sqrt * Y_sym;
% 可选的:使用特征值进行加权
% for i = 1:target_dim
% Y(:, i) = Y(:, i) * lambda_sorted(i+1);
% end
end
7. 降维质量评估函数
function [trustworthiness, continuity, mrre] = compute_quality_metrics(X_high, X_low, k)
% 计算降维质量指标
% 输入:
% X_high - 高维数据 (n×d_high)
% X_low - 低维嵌入 (n×d_low)
% k - 近邻数
% 输出:
% trustworthiness - 可信度指标 [0,1],越高越好
% continuity - 连续性指标 [0,1],越高越好
% mrre - 平均相对秩误差,越低越好
n = size(X_high, 1);
if n < 2*k
k = floor(n/2);
end
% 计算距离矩阵
D_high = pdist2(X_high, X_high);
D_low = pdist2(X_low, X_low);
% 初始化
trustworthiness = 0;
continuity = 0;
mrre_sum = 0;
for i = 1:n
% 在高维空间中找到k个最近邻
[~, idx_high] = sort(D_high(i,:));
neighbors_high = idx_high(2:k+1); % 排除自身
% 在低维空间中找到k个最近邻
[~, idx_low] = sort(D_low(i,:));
neighbors_low = idx_low(2:k+1); % 排除自身
% 计算可信度
intruders = setdiff(neighbors_low, neighbors_high);
for j = 1:length(intruders)
r_high = find(idx_high == intruders(j)) - 1; % 在高维中的秩
trustworthiness = trustworthiness + (r_high - k);
end
% 计算连续性
missing = setdiff(neighbors_high, neighbors_low);
for j = 1:length(missing)
r_low = find(idx_low == missing(j)) - 1; % 在低维中的秩
continuity = continuity + (r_low - k);
end
% 计算相对秩误差
common_neighbors = intersect(neighbors_high, neighbors_low);
for j = 1:length(common_neighbors)
neighbor = common_neighbors(j);
r_high = find(idx_high == neighbor) - 1;
r_low = find(idx_low == neighbor) - 1;
mrre_sum = mrre_sum + abs(r_high - r_low) / max(r_high, r_low);
end
end
% 归一化
max_penalty = n * k * (2*n - 3*k - 1) / 2;
if max_penalty > 0
trustworthiness = 1 - (2 * trustworthiness) / max_penalty;
continuity = 1 - (2 * continuity) / max_penalty;
else
trustworthiness = 1;
continuity = 1;
end
% 平均相对秩误差
mrre = mrre_sum / (n * length(common_neighbors));
end
8. 参数敏感性分析函数
function analyze_parameter_sensitivity(X, labels, target_dim, dataset_name)
% 分析算法对参数的敏感性
% 参数范围
k_values = [5, 10, 15, 20, 30, 50];
algorithms = {'Isomap', 'LLE', 'Laplacian', 'DiffusionMaps'};
% 存储结果
results = struct();
figure('Position', [100, 100, 1200, 800]);
for alg_idx = 1:length(algorithms)
algorithm = algorithms{alg_idx};
trust_scores = zeros(length(k_values), 1);
cont_scores = zeros(length(k_values), 1);
time_scores = zeros(length(k_values), 1);
for k_idx = 1:length(k_values)
k = k_values(k_idx);
disp([' ', algorithm, ' with k=', num2str(k)]);
% 运行算法
tic;
switch algorithm
case 'Isomap'
Y = isomap_embedding(X, target_dim, k, 0.5);
case 'LLE'
Y = lle_embedding(X, target_dim, k);
case 'Laplacian'
Y = laplacian_eigenmaps_embedding(X, target_dim, k);
case 'DiffusionMaps'
Y = diffusion_maps_embedding(X, target_dim, k);
end
time_scores(k_idx) = toc;
% 计算质量指标
[trust, cont, ~] = compute_quality_metrics(X, Y, min(k, 20));
trust_scores(k_idx) = trust;
cont_scores(k_idx) = cont;
end
% 存储结果
results(alg_idx).algorithm = algorithm;
results(alg_idx).k_values = k_values;
results(alg_idx).trust_scores = trust_scores;
results(alg_idx).cont_scores = cont_scores;
results(alg_idx).time_scores = time_scores;
% 绘制子图
subplot(2, 2, alg_idx);
% 绘制双Y轴图
yyaxis left;
plot(k_values, trust_scores, 'b-o', 'LineWidth', 2, 'MarkerSize', 8);
hold on;
plot(k_values, cont_scores, 'r-s', 'LineWidth', 2, 'MarkerSize', 8);
ylabel('质量指标');
ylim([0, 1]);
yyaxis right;
plot(k_values, time_scores, 'g-^', 'LineWidth', 2, 'MarkerSize', 8);
ylabel('时间 (秒)');
xlabel('近邻数 k');
title([algorithm, ' - 参数敏感性']);
legend('可信度', '连续性', '运行时间', 'Location', 'best');
grid on;
hold off;
end
sgtitle([dataset_name, ' - 算法参数敏感性分析'], 'FontSize', 14, 'FontWeight', 'bold');
% 保存敏感性分析结果
if exist('Manifold_Learning_Results', 'dir')
save('Manifold_Learning_Results/parameter_sensitivity.mat', 'results');
end
end
9. 可视化辅助函数
function plot_original_data(X, labels, original_dim, dataset_name)
% 绘制原始数据
if original_dim == 1
% 一维数据
scatter(X, zeros(size(X)), 30, labels, 'filled');
xlabel('维度 1');
ylim([-0.1, 0.1]);
elseif original_dim == 2
% 二维数据
scatter(X(:,1), X(:,2), 30, labels, 'filled');
xlabel('维度 1');
ylabel('维度 2');
elseif original_dim == 3
% 三维数据
scatter3(X(:,1), X(:,2), X(:,3), 30, labels, 'filled');
xlabel('维度 1');
ylabel('维度 2');
zlabel('维度 3');
view(3);
else
% 高维数据:使用前三个主成分
[coeff, score] = pca(X);
if size(score, 2) >= 3
scatter3(score(:,1), score(:,2), score(:,3), 30, labels, 'filled');
xlabel('主成分 1');
ylabel('主成分 2');
zlabel('主成分 3');
view(3);
elseif size(score, 2) == 2
scatter(score(:,1), score(:,2), 30, labels, 'filled');
xlabel('主成分 1');
ylabel('主成分 2');
else
scatter(score(:,1), zeros(size(score,1)), 30, labels, 'filled');
xlabel('主成分 1');
ylim([-0.1, 0.1]);
end
end
title([dataset_name, ' 原始数据']);
axis equal tight;
grid on;
colorbar;
end
function spider_plot(data, categories, labels)
% 创建雷达图
n_categories = length(categories);
n_datasets = size(data, 2);
% 角度
theta = linspace(0, 2*pi, n_categories + 1);
theta = theta(1:end-1);
% 创建极坐标
ax = polaraxes;
hold on;
% 绘制每个数据集
colors = lines(n_datasets);
for i = 1:n_datasets
% 闭合数据
rho = [data(:,i); data(1,i)];
th = [theta, theta(1)];
polarplot(th, rho, 'Color', colors(i,:), 'LineWidth', 2, ...
'Marker', 'o', 'MarkerSize', 6, 'DisplayName', labels{i});
end
% 设置网格
ax.ThetaTick = rad2deg(theta);
ax.ThetaTickLabel = categories;
ax.RLim = [0, 1.1];
ax.RTick = 0:0.2:1;
ax.RTickLabel = arrayfun(@(x) sprintf('%.1f', x), 0:0.2:1, 'UniformOutput', false);
% 添加图例
legend('Location', 'best');
hold off;
end
10. 报告生成函数
function generate_manifold_learning_report(dir_path, results, X_original, dataset_name)
% 生成流形学习分析报告
report_file = [dir_path, 'manifold_learning_report.txt'];
fid = fopen(report_file, 'w');
fprintf(fid, '===============================================\n');
fprintf(fid, ' 流形学习降维分析报告\n');
fprintf(fid, '===============================================\n\n');
fprintf(fid, '数据集: %s\n', dataset_name);
fprintf(fid, '原始维度: %d\n', size(X_original, 2));
fprintf(fid, '样本数量: %d\n', size(X_original, 1));
fprintf(fid, '分析时间: %s\n\n', datestr(now));
% 算法性能汇总
fprintf(fid, '算法性能汇总:\n');
fprintf(fid, '%-15s %-10s %-12s %-12s %-10s\n', ...
'算法', '时间(s)', '可信度', '连续性', 'MRRE');
fprintf(fid, '%s\n', repmat('-', 65, 1));
for i = 1:length(results)
if isfield(results(i), 'trustworthiness')
fprintf(fid, '%-15s %-10.2f %-12.4f %-12.4f %-10.4f\n', ...
results(i).algorithm, results(i).time, ...
results(i).trustworthiness, results(i).continuity, ...
results(i).mrre);
else
fprintf(fid, '%-15s %-10.2f %-12s %-12s %-10s\n', ...
results(i).algorithm, results(i).time, 'N/A', 'N/A', 'N/A');
end
end
% 最佳算法
if isfield(results(1), 'trustworthiness')
[~, best_trust] = max([results.trustworthiness]);
[~, best_cont] = max([results.continuity]);
[~, fastest] = min([results.time]);
fprintf(fid, '\n最佳算法:\n');
fprintf(fid, ' 最佳可信度: %s (%.4f)\n', ...
results(best_trust).algorithm, results(best_trust).trustworthiness);
fprintf(fid, ' 最佳连续性: %s (%.4f)\n', ...
results(best_cont).algorithm, results(best_cont).continuity);
fprintf(fid, ' 最快算法: %s (%.2f s)\n', ...
results(fastest).algorithm, results(fastest).time);
end
% 参数设置
fprintf(fid, '\n参数设置:\n');
fprintf(fid, ' 目标维度: %d\n', size(results(1).embedding, 2));
if isfield(results(1), 'parameters')
params = fieldnames(results(1).parameters);
for j = 1:length(params)
fprintf(fid, ' %s: %s\n', params{j}, ...
num2str(results(1).parameters.(params{j})));
end
end
fclose(fid);
disp(['分析报告已保存: ', report_file]);
end
参考代码 基于流形学习的无监督降维算法 www.youwenfan.com/contentcnp/95944.html
使用说明:
1. 程序功能:
- 实现了多种流形学习算法:Isomap、LLE、拉普拉斯特征映射、扩散映射等
- 支持多种标准数据集:Swiss Roll、S曲线、螺旋线、Iris、MNIST等
- 提供完整的质量评估和可视化
- 包含参数敏感性分析
2. 算法特点:
Isomap:
- 保持测地线距离
- 适用于展开流形
- 对噪声敏感
LLE:
- 保持局部线性关系
- 计算效率高
- 对参数敏感
拉普拉斯特征映射:
- 基于图拉普拉斯
- 保持局部邻域关系
- 适用于聚类结构
扩散映射:
- 基于扩散过程
- 多尺度分析能力
- 对噪声鲁棒
3. 参数选择建议:
近邻数 k:
k = 5-20; % 一般范围
% 太小:欠拟合,太大:过拟合
目标维度:
target_dim = 2; % 可视化
target_dim = 3; % 3D可视化
target_dim = 10; % 特征提取
4. 运行步骤:
- 设置数据集类型和参数
- 选择要运行的算法
- 程序自动计算降维结果
- 查看可视化结果和性能指标
- 结果自动保存
5. 质量评估指标:
- 可信度:低维空间中保留的高维邻域关系的程度
- 连续性:高维空间中保留的低维邻域关系的程度
- MRRE:平均相对秩误差
6. 扩展功能:
- 可添加t-SNE和UMAP实现
- 可集成监督流形学习
- 可添加核方法扩展
- 可支持大规模数据(使用稀疏矩阵)

浙公网安备 33010602011771号