使用PCA算法进行故障诊断的MATLAB仿真

使用PCA算法进行故障诊断的MATLAB仿真,包含完整的PCA建模、统计量计算和故障检测功能:

matlab 复制代码
%% PCA故障诊断MATLAB仿真程序
% 作者:MATLAB助手
% 功能:使用PCA进行故障检测和诊断

clear all; close all; clc;
rng(42); % 设置随机种子,确保结果可重复

%% 1. 生成模拟数据
% 假设一个具有3个相关变量的工业过程
n_samples = 1000;  % 正常工况样本数
n_test = 500;      % 测试样本数
n_vars = 10;       % 过程变量数
fault_start = 300; % 测试数据中故障开始点

% 生成正常工况数据(训练数据)
X_normal = zeros(n_samples, n_vars);
t = (1:n_samples)' / 100;

% 基础信号
base1 = sin(2*pi*t/50);
base2 = cos(2*pi*t/30);
base3 = 0.5*sin(2*pi*t/20) + 0.3*cos(2*pi*t/15);

% 生成相关变量(模拟工业过程相关性)
X_normal(:,1) = base1 + 0.1*randn(n_samples,1);
X_normal(:,2) = 0.8*base1 + 0.3*base2 + 0.1*randn(n_samples,1);
X_normal(:,3) = 0.6*base2 + 0.4*base3 + 0.1*randn(n_samples,1);
X_normal(:,4) = 0.7*base1 - 0.5*base3 + 0.1*randn(n_samples,1);
X_normal(:,5) = 0.9*base2 + 0.2*base3 + 0.1*randn(n_samples,1);

% 添加一些独立变量
for i = 6:n_vars
    X_normal(:,i) = 0.5*randn(n_samples,1) + 0.2*sin(2*pi*t/(20+i));
end

% 添加少量噪声
X_normal = X_normal + 0.05*randn(size(X_normal));

% 生成测试数据(前部分正常,后部分故障)
X_test_normal = zeros(n_test, n_vars);
t_test = (1:n_test)' / 100;

% 正常部分
base1_test = sin(2*pi*t_test/50);
base2_test = cos(2*pi*t_test/30);
base3_test = 0.5*sin(2*pi*t_test/20) + 0.3*cos(2*pi*t_test/15);

X_test_normal(:,1) = base1_test + 0.1*randn(n_test,1);
X_test_normal(:,2) = 0.8*base1_test + 0.3*base2_test + 0.1*randn(n_test,1);
X_test_normal(:,3) = 0.6*base2_test + 0.4*base3_test + 0.1*randn(n_test,1);
X_test_normal(:,4) = 0.7*base1_test - 0.5*base3_test + 0.1*randn(n_test,1);
X_test_normal(:,5) = 0.9*base2_test + 0.2*base3_test + 0.1*randn(n_test,1);

for i = 6:n_vars
    X_test_normal(:,i) = 0.5*randn(n_test,1) + 0.2*sin(2*pi*t_test/(20+i));
end

X_test_normal = X_test_normal + 0.05*randn(size(X_test_normal));

% 引入故障(在变量2和变量5上添加偏移)
X_test_fault = X_test_normal;
fault_magnitude = 1.5; % 故障幅值

% 从fault_start开始添加故障
X_test_fault(fault_start:end, 2) = X_test_fault(fault_start:end, 2) + fault_magnitude;
X_test_fault(fault_start:end, 5) = X_test_fault(fault_start:end, 5) + 0.8*fault_magnitude;

% 测试数据(前半部分正常,后半部分故障)
X_test = X_test_fault;

%% 2. 数据预处理
% 数据标准化(均值中心化+方差归一化)
[mu, sigma] = deal(mean(X_normal), std(X_normal));
X_normal_scaled = (X_normal - mu) ./ sigma;
X_test_scaled = (X_test - mu) ./ sigma;

%% 3. PCA模型建立
[coeff, score, latent, ~, explained] = pca(X_normal_scaled);

% 确定主成分个数(累积贡献率>85%)
cumulative_explained = cumsum(explained);
n_components = find(cumulative_explained >= 85, 1);
fprintf('选择前%d个主成分,累积贡献率: %.2f%%\n', ...
    n_components, cumulative_explained(n_components));

% 划分主成分空间和残差空间
P = coeff(:, 1:n_components);      % 负载矩阵(主成分方向)
T = X_normal_scaled * P;           % 得分矩阵

% 残差矩阵
X_reconstructed = T * P';
E = X_normal_scaled - X_reconstructed;

%% 4. 计算控制限
% 4.1 T²统计量(Hotelling's T²)控制限
alpha = 0.99;  % 置信水平
[n, m] = size(X_normal_scaled);
a = n_components;

% T²统计量计算函数
T2_train = diag(T * inv(diag(latent(1:a))) * T');
T2_limit = a * (n-1) * (n+1) * finv(alpha, a, n-a) / (n * (n-a));

% 4.2 SPE(平方预测误差)或Q统计量控制限
SPE_train = sum(E.^2, 2);
theta = zeros(3,1);
for i = 1:3
    theta(i) = sum(latent(a+1:end).^i);
end

h0 = 1 - 2*theta(1)*theta(3) / (3*theta(2)^2);
z_alpha = norminv(alpha);
SPE_limit = theta(1) * (z_alpha*sqrt(2*theta(2)*h0^2)/theta(1) + 1 + ...
    theta(2)*h0*(h0-1)/theta(1)^2)^(1/h0);

%% 5. 测试数据的故障检测
% 5.1 测试数据投影
T_test = X_test_scaled * P;
X_test_reconstructed = T_test * P';
E_test = X_test_scaled - X_test_reconstructed;

% 5.2 计算测试数据的统计量
T2_test = diag(T_test * inv(diag(latent(1:a))) * T_test');
SPE_test = sum(E_test.^2, 2);

% 5.3 故障检测
T2_violation = T2_test > T2_limit;
SPE_violation = SPE_test > SPE_limit;
fault_detected = T2_violation | SPE_violation;

% 检测性能指标
true_fault = false(n_test, 1);
true_fault(fault_start:end) = true;

TP = sum(fault_detected(true_fault));      % 真阳性
FP = sum(fault_detected(~true_fault));     % 假阳性
FN = sum(~fault_detected(true_fault));     % 假阴性
TN = sum(~fault_detected(~true_fault));    % 真阴性

accuracy = (TP+TN) / n_test;
precision = TP / (TP+FP);
recall = TP / (TP+FN);
F1_score = 2 * (precision*recall) / (precision+recall);

fprintf('\n故障检测性能指标:\n');
fprintf('准确率: %.2f%%\n', accuracy*100);
fprintf('精确率: %.2f%%\n', precision*100);
fprintf('召回率: %.2f%%\n', recall*100);
fprintf('F1分数: %.2f%%\n', F1_score*100);

%% 6. 故障诊断(贡献图方法)
fault_samples = find(fault_detected);
if ~isempty(fault_samples)
    % 选择一个故障样本进行诊断
    sample_idx = fault_samples(1);
    
    % 计算各变量对SPE的贡献
    SPE_contributions = E_test(sample_idx, :).^2;
    
    % 计算各变量对T²的贡献
    T2_contributions = zeros(1, m);
    Lambda_inv = inv(diag(latent(1:a)));
    for j = 1:m
        c_j = P(j, :)' * Lambda_inv * P(j, :);
        T2_contributions(j) = X_test_scaled(sample_idx, j)^2 * c_j;
    end
    
    % 总贡献
    total_contributions = SPE_contributions + T2_contributions;
end

%% 7. 可视化结果
% 7.1 主成分解释率
figure('Position', [100, 100, 1200, 800]);

subplot(3, 3, 1);
bar(explained(1:10));
xlabel('主成分');
ylabel('解释方差 (%)');
title('主成分解释方差');
grid on;

subplot(3, 3, 2);
plot(cumulative_explained(1:10), 'o-', 'LineWidth', 2);
hold on;
plot([1, 10], [85, 85], 'r--', 'LineWidth', 1.5);
plot([n_components, n_components], [0, 100], 'g--', 'LineWidth', 1.5);
xlabel('主成分个数');
ylabel('累积解释方差 (%)');
title('累积解释方差');
legend('累积贡献率', '85%阈值', ['选择: ' num2str(n_components)], 'Location', 'best');
grid on;

% 7.2 得分图(前两个主成分)
subplot(3, 3, 3);
scatter(T(1:200,1), T(1:200,2), 20, 'b', 'filled', 'DisplayName', '训练数据');
hold on;
scatter(T_test(1:fault_start-1,1), T_test(1:fault_start-1,2), 20, 'g', 'filled', 'DisplayName', '测试正常');
scatter(T_test(fault_start:end,1), T_test(fault_start:end,2), 20, 'r', 'filled', 'DisplayName', '测试故障');
xlabel('PC1');
ylabel('PC2');
title('得分图 (PC1 vs PC2)');
legend('Location', 'best');
grid on;

% 7.3 T²统计量监控图
subplot(3, 3, [4, 5]);
plot(T2_test, 'b-', 'LineWidth', 1.5);
hold on;
plot([1, n_test], [T2_limit, T2_limit], 'r--', 'LineWidth', 2);
plot([fault_start, fault_start], [0, max(T2_test)], 'k--', 'LineWidth', 1.5);
xlabel('样本序号');
ylabel('T²统计量');
title(['T²统计量监控 (控制限: ' num2str(T2_limit, '%.2f') ')']);
legend('T²统计量', ['控制限 (' num2str(alpha*100) '%)'], '故障起始点', 'Location', 'best');
grid on;

% 7.4 SPE统计量监控图
subplot(3, 3, [6, 7]);
plot(SPE_test, 'b-', 'LineWidth', 1.5);
hold on;
plot([1, n_test], [SPE_limit, SPE_limit], 'r--', 'LineWidth', 2);
plot([fault_start, fault_start], [0, max(SPE_test)], 'k--', 'LineWidth', 1.5);
xlabel('样本序号');
ylabel('SPE统计量');
title(['SPE统计量监控 (控制限: ' num2str(SPE_limit, '%.2f') ')']);
legend('SPE统计量', ['控制限 (' num2str(alpha*100) '%)'], '故障起始点', 'Location', 'best');
grid on;

% 7.5 故障检测结果
subplot(3, 3, 8);
stairs(true_fault, 'b-', 'LineWidth', 2);
hold on;
stairs(fault_detected, 'r-', 'LineWidth', 1.5);
plot([fault_start, fault_start], [0, 1], 'k--', 'LineWidth', 1.5);
xlabel('样本序号');
ylabel('故障状态');
title('故障检测结果');
legend('真实故障', '检测故障', '故障起始点', 'Location', 'best');
grid on;
ylim([-0.1, 1.1]);

% 7.6 贡献图(故障诊断)
subplot(3, 3, 9);
if ~isempty(fault_samples)
    bar(total_contributions);
    xlabel('变量序号');
    ylabel('贡献度');
    title(['故障样本#' num2str(sample_idx) '的贡献图']);
    grid on;
    
    % 标记故障变量
    hold on;
    bar([2, 5], total_contributions([2, 5]), 'r');
    legend('正常变量', '故障变量', 'Location', 'best');
else
    text(0.5, 0.5, '未检测到故障', 'HorizontalAlignment', 'center');
    axis off;
end

%% 8. 保存结果
save('PCA_fault_diagnosis_results.mat', ...
    'X_normal', 'X_test', 'fault_start', ...
    'coeff', 'latent', 'explained', 'n_components', ...
    'T2_test', 'SPE_test', 'T2_limit', 'SPE_limit', ...
    'fault_detected', 'accuracy', 'precision', 'recall', 'F1_score');

fprintf('\n仿真完成!结果已保存到 PCA_fault_diagnosis_results.mat\n');

程序功能说明:

1. 数据生成模块

  • 生成正常工况训练数据(1000个样本,10个变量)
  • 生成测试数据(前200个正常,后300个含故障)
  • 故障模拟:在变量2和5上添加偏移故障

2. PCA建模模块

  • 数据标准化预处理
  • 计算主成分和解释方差
  • 自动确定主成分个数(累积贡献率>85%)

3. 故障检测模块

  • 计算T²和SPE统计量
  • 计算基于F分布和正态分布的控制限
  • 实现实时故障检测逻辑

4. 故障诊断模块

  • 使用贡献图方法识别故障变量
  • 计算各变量对统计量的贡献度

5. 性能评估模块

  • 计算准确率、精确率、召回率、F1分数
  • 可视化检测结果

6. 可视化模块

  • 主成分分析结果
  • 统计量监控图
  • 故障检测结果对比
  • 贡献图分析

参考代码 使用PCA算法的故障诊断MATLAB仿真程序 www.3dddown.com/csa/96615.html

使用说明:

  1. 直接运行:在MATLAB中运行整个程序即可看到完整的仿真结果

  2. 自定义参数

    • 修改 n_vars 调整变量数
    • 修改 fault_magnitude 调整故障幅值
    • 修改 alpha 调整置信水平
    • 修改 fault_start 调整故障开始位置
  3. 扩展功能

    • 可替换为自己的实际工业数据
    • 可添加不同类型的故障(漂移、振荡等)
    • 可结合其他方法(如KPCA、DPCA等)

输出结果:

  • 9个子图的综合可视化界面
  • 控制台输出的性能指标
  • 保存到MAT文件的完整结果数据
相关推荐
额呃呃2 小时前
二分查找细节理解
数据结构·算法
无尽的罚坐人生2 小时前
hot 100 283. 移动零
数据结构·算法·双指针
永远都不秃头的程序员(互关)2 小时前
C++动态数组实战:从手写到vector优化
c++·算法
水力魔方3 小时前
武理排水管网模拟分析系统应用专题5:模型克隆与并行计算
数据库·c++·算法·swmm
谈笑也风生4 小时前
经典算法题型之排序算法(三)
java·算法·排序算法
大佬,救命!!!5 小时前
对算子shape相关的属性值自动化处理
python·算法·自动化·学习笔记·算子·用例脚本·算子形状
高山上有一只小老虎5 小时前
小红的推荐系统
java·算法
冰西瓜6005 小时前
贪心(一)——从动态规划到贪心 算法设计与分析 国科大
算法·贪心算法·动态规划
javachen__5 小时前
341-十道经典程序设计题目
数据结构·c++·算法