使用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
使用说明:
-
直接运行:在MATLAB中运行整个程序即可看到完整的仿真结果
-
自定义参数:
- 修改
n_vars调整变量数 - 修改
fault_magnitude调整故障幅值 - 修改
alpha调整置信水平 - 修改
fault_start调整故障开始位置
- 修改
-
扩展功能:
- 可替换为自己的实际工业数据
- 可添加不同类型的故障(漂移、振荡等)
- 可结合其他方法(如KPCA、DPCA等)
输出结果:
- 9个子图的综合可视化界面
- 控制台输出的性能指标
- 保存到MAT文件的完整结果数据