一、基本SVM故障诊断例程
matlab
%% 基于SVM的故障诊断例程
% 作者:MATLAB助手
% 功能:使用SVM进行工业设备故障分类
clear; close all; clc;
%% 1. 生成模拟故障数据
% 假设我们监测设备的振动信号特征
rng(1); % 设置随机种子,确保结果可重现
% 正常状态数据(类别1)
normal_data = [
0.2 + 0.1*randn(50,1), 0.3 + 0.1*randn(50,1); % 特征1, 特征2
0.3 + 0.1*randn(50,1), 0.4 + 0.1*randn(50,1)
];
% 故障状态1:轻微故障(类别2)
fault1_data = [
0.6 + 0.2*randn(50,1), 0.7 + 0.2*randn(50,1);
0.7 + 0.2*randn(50,1), 0.8 + 0.2*randn(50,1)
];
% 故障状态2:严重故障(类别3)
fault2_data = [
1.2 + 0.3*randn(50,1), 1.3 + 0.3*randn(50,1);
1.1 + 0.3*randn(50,1), 1.4 + 0.3*randn(50,1)
];
% 合并数据
X = [normal_data; fault1_data; fault2_data];
Y = [ones(100,1); 2*ones(100,1); 3*ones(100,1)]; % 标签:1-正常, 2-轻微故障, 3-严重故障
%% 2. 数据可视化
figure;
gscatter(X(:,1), X(:,2), Y, 'rgb', 'os^');
xlabel('特征1: 振动幅度');
ylabel('特征2: 频率分量');
title('故障数据分布');
legend('正常', '轻微故障', '严重故障');
grid on;
%% 3. 数据预处理
% 数据标准化
X = zscore(X);
% 划分训练集和测试集 (70%训练, 30%测试)
cv = cvpartition(Y, 'HoldOut', 0.3);
XTrain = X(training(cv), :);
YTrain = Y(training(cv), :);
XTest = X(test(cv), :);
YTest = Y(test(cv), :);
%% 4. 训练SVM分类器
fprintf('开始训练SVM分类器...\n');
% 方法1: 一对一多类分类
SVMModel = fitcecoc(XTrain, YTrain, ...
'Learners', 'svm', ...
'ClassNames', [1; 2; 3], ...
'Coding', 'onevsone');
% 方法2: 也可以使用单个SVM进行二分类(如果需要)
% 这里以正常vs故障为例
binary_Y = YTrain > 1; % 1=正常, 2=故障
SVMModel_binary = fitcsvm(XTrain, binary_Y, ...
'KernelFunction', 'rbf', ...
'BoxConstraint', 1, ...
'Standardize', true);
%% 5. 模型预测
% 多类分类预测
YPred = predict(SVMModel, XTest);
% 二分类预测
YPred_binary = predict(SVMModel_binary, XTest);
%% 6. 性能评估
fprintf('\n=== 多类分类性能 ===\n');
accuracy = sum(YPred == YTest) / numel(YTest);
fprintf('测试集准确率: %.2f%%\n', accuracy * 100);
% 混淆矩阵
figure;
cm = confusionchart(YTest, YPred);
cm.Title = '多类分类混淆矩阵';
% 分类报告
fprintf('\n详细分类报告:\n');
for i = 1:3
true_pos = sum((YTest == i) & (YPred == i));
false_pos = sum((YTest ~= i) & (YPred == i));
false_neg = sum((YTest == i) & (YPred ~= i));
precision = true_pos / (true_pos + false_pos);
recall = true_pos / (true_pos + false_neg);
f1 = 2 * (precision * recall) / (precision + recall);
switch i
case 1
class_name = '正常';
case 2
class_name = '轻微故障';
case 3
class_name = '严重故障';
end
fprintf('%s - 精确率: %.3f, 召回率: %.3f, F1分数: %.3f\n', ...
class_name, precision, recall, f1);
end
%% 7. 决策边界可视化
figure;
h = 0.02; % 网格步长
[x1Grid, x2Grid] = meshgrid(min(X(:,1))-0.5:h:max(X(:,1))+0.5, ...
min(X(:,2))-0.5:h:max(X(:,2))+0.5);
xGrid = [x1Grid(:), x2Grid(:)];
% 预测整个网格
[~, scores] = predict(SVMModel, xGrid);
% 找到最大得分的类别
[~, maxScore] = max(scores, [], 2);
% 绘制决策区域
contourf(x1Grid, x2Grid, reshape(maxScore, size(x1Grid)), 'AlphaData', 0.3);
hold on;
% 绘制数据点
gscatter(X(:,1), X(:,2), Y, 'rgb', 'os^', 10);
xlabel('标准化特征1');
ylabel('标准化特征2');
title('SVM决策边界');
legend('区域1', '区域2', '区域3', '正常', '轻微故障', '严重故障');
grid on;
二、基于真实特征数据的SVM故障诊断例程
matlab
%% 基于特征提取的SVM故障诊断
% 模拟从振动信号中提取特征进行故障诊断
clear; close all; clc;
%% 1. 生成模拟振动信号并提取特征
num_samples = 300;
features = zeros(num_samples, 5); % 5个特征
labels = zeros(num_samples, 1);
for i = 1:num_samples
if i <= 100
% 正常状态信号
t = 0:0.001:1;
signal = 0.5*sin(2*pi*50*t) + 0.1*randn(size(t));
labels(i) = 1;
elseif i <= 200
% 轴承故障信号(冲击特征)
t = 0:0.001:1;
signal = 0.5*sin(2*pi*50*t) + 0.3*exp(-20*(mod(t,0.1)-0.05).^2).*sin(2*pi*1000*t) + 0.2*randn(size(t));
labels(i) = 2;
else
% 齿轮故障信号(调制特征)
t = 0:0.001:1;
signal = (0.5 + 0.3*sin(2*pi*20*t)).*sin(2*pi*50*t) + 0.3*randn(size(t));
labels(i) = 3;
end
% 提取时域特征
features(i, 1) = rms(signal); % RMS
features(i, 2) = std(signal); % 标准差
features(i, 3) = kurtosis(signal); % 峭度
features(i, 4) = skewness(signal); % 偏度
% 提取频域特征(简单的频谱幅度)
N = length(signal);
Y = fft(signal);
P2 = abs(Y/N);
P1 = P2(1:N/2+1);
P1(2:end-1) = 2*P1(2:end-1);
[~, max_idx] = max(P1(2:end)); % 找到最大幅值频率(忽略直流)
features(i, 5) = max_idx * (500/N); % 近似频率
end
%% 2. 特征可视化
figure;
subplot(2,3,1);
gscatter(features(:,1), features(:,2), labels, 'rgb', 'os^');
xlabel('RMS'); ylabel('标准差'); title('特征分布');
subplot(2,3,2);
gscatter(features(:,3), features(:,4), labels, 'rgb', 'os^');
xlabel('峭度'); ylabel('偏度'); title('特征分布');
subplot(2,3,3);
boxplot(features(:,5), labels);
xlabel('故障类型'); ylabel('主导频率'); title('频率特征');
% 特征相关性热图
subplot(2,3,4);
corr_matrix = corr(features);
imagesc(corr_matrix);
colorbar;
title('特征相关性矩阵');
xticks(1:5); yticks(1:5);
xticklabels({'RMS','Std','Kurtosis','Skewness','Freq'});
yticklabels({'RMS','Std','Kurtosis','Skewness','Freq'});
%% 3. 数据预处理和划分
% 标准化特征
features = zscore(features);
% 划分训练测试集
cv = cvpartition(labels, 'HoldOut', 0.3);
XTrain = features(training(cv), :);
YTrain = labels(training(cv), :);
XTest = features(test(cv), :);
YTest = labels(test(cv), :);
%% 4. 使用自动优化训练SVM
fprintf('使用贝叶斯优化寻找最佳SVM参数...\n');
% 定义优化变量
opts = struct('Optimizer', 'bayesopt', 'ShowPlots', false, ...
'CVPartition', cvpartition(YTrain, 'KFold', 5), ...
'AcquisitionFunctionName', 'expected-improvement-plus');
% 自动优化SVM参数
SVMModel_auto = fitcecoc(XTrain, YTrain, ...
'Learners', 'svm', ...
'OptimizeHyperparameters', {'BoxConstraint', 'KernelScale'}, ...
'HyperparameterOptimizationOptions', opts);
%% 5. 模型评估
YPred_auto = predict(SVMModel_auto, XTest);
accuracy_auto = sum(YPred_auto == YTest) / numel(YTest);
fprintf('\n优化后模型准确率: %.2f%%\n', accuracy_auto * 100);
% 混淆矩阵
figure;
confusionchart(YTest, YPred_auto);
title('优化SVM混淆矩阵');
%% 6. 特征重要性分析
% 使用排列重要性评估特征贡献
fprintf('\n分析特征重要性...\n');
base_accuracy = accuracy_auto;
feature_importance = zeros(1, size(XTest, 2));
for i = 1:size(XTest, 2)
% 打乱第i个特征
XTest_permuted = XTest;
XTest_permuted(:, i) = XTest_permuted(randperm(size(XTest_permuted, 1)), i);
YPred_perm = predict(SVMModel_auto, XTest_permuted);
perm_accuracy = sum(YPred_perm == YTest) / numel(YTest);
feature_importance(i) = base_accuracy - perm_accuracy;
end
% 显示特征重要性
figure;
bar(feature_importance);
xlabel('特征索引');
ylabel('准确率下降');
title('特征重要性(排列重要性)');
xticklabels({'RMS','Std','Kurtosis','Skewness','Freq'});
grid on;
参考代码 基于MATLAB的支持向量机(SVM)在故障诊断中的的应用例程 www.3dddown.com/csa/65944.html
三、关键
1. SVM在故障诊断中的优势
- 适用于小样本情况
- 能够处理高维特征
- 对于非线性问题有很好的处理能力(使用核技巧)
2. 参数调优
matlab
% 常用的核函数选择
% 'linear' - 线性核,适用于线性可分数据
% 'rbf' - 高斯核,最常用,适用于非线性问题
% 'poly' - 多项式核
% 关键参数
% BoxConstraint - 惩罚参数C,控制过拟合
% KernelScale - 核函数尺度参数(γ)
3. 应用
- 特征工程:从原始信号中提取有区分度的特征
- 数据标准化:SVM对特征尺度敏感,务必进行标准化
- 类别平衡:对于不平衡数据,使用加权SVM
- 交叉验证:使用k折交叉验证评估模型稳定性
这个例程提供了从基础到相对完整的SVM故障诊断实现,您可以根据具体的故障类型和数据特征进行调整和优化。