简介:这是一份面向数据分析和机器学习场景的MATLAB实现包,聚焦随机子空间与稳定性选择(SSI)策略,用于在高维特征空间中评估特征重要性并绘制SSI稳定图,帮助研究者发现不同随机子集中频繁出现、稳定性高的特征,从而减少过拟合并提升模型泛化能力。包内共四个文件,全部为m脚本,整体仅四KB,涵盖主执行程序、数据预处理、滤波降采样、协方差计算及稳定性评估等环节,适合具备MATLAB基础并开展特征工程或预测建模的读者复用。运行主脚本可自动完成数据读取、随机子空间生成、模型训练、特征稳定性评分与稳定图输出,无需手工干预,可作为随机子空间分析的落地工具链。目前已有四百零八人浏览学习,这类小体积工具包在特征选择和高维数据分析场景中具有实用价值,也可作为教学示例。
1. SSI 随机子空间稳定图是什么:环境激励下那些藏起来的模态
结构健康监测里最麻烦的不是采集数据,而是从数据里筛出可信的模态。现场环境激励的响应信号里,谱峰经常被噪声淹没,峰值法只能看到两三阶明显共振;阻尼大的、靠得近的模态直接消失。SSI,全称 Stochastic Subspace Identification,中文叫随机子空间识别,直接对响应做状态空间建模,把频率、阻尼比、振型一次性估计出来。而“稳定图”就是这套方法的关键产出:把模型阶次从低到高扫一遍,每个极点在图上留下一个点,真实模态会像柱子一样立在同一个频率位置上,虚假模态则乱跑。
跑通一套 SSI 稳定图流程后,一段 60 秒的加速度记录就能自动给你 6 到 8 阶模态参数,不需要人工去数频谱峰,更不用反复试滤波带。相比频域方法,SSI 是纯时域方法,不依赖频率分辨率,对密集模态和重阻尼模态的分辨能力明显更强。这篇按我自己搭这套流程的顺序来讲:原理、可复现代码、参数调整、常见坑和验证技巧。新手能照着跑通仿真数据,熟手可以直接拿去对照自己的实测数据,看边界条件在哪、参数该往哪个方向动。
2. SSI 原理与稳定图逻辑:为什么必须扫阶次、判据怎么定
2.1 状态空间模型与可观测矩阵:SSI 为什么不测输入也能识别
环境激励下我们拿不到输入力,只能从响应数据本身挖掘模态信息。SSI 的出发点是一个离散状态空间模型:
x_{k+1} = A x_k + w_k
y_k = C x_k + v_k
这里的 w_k 是过程噪声,含义是没法测量的环境激励;v_k 是传感器噪声。A 是系统矩阵,C 是输出矩阵,模态参数全部藏在 A 的特征值里。问题的难点在于我们既不知道 x_k,也不知道 A 和 C,只能从观测序列 y_k 反推。SSI 的思路是先构造一个“可观测矩阵” O_i = [C^T, (CA)^T, (CA^2)^T, ..., (CA^{i-1})^T]^T,然后再从 O 中恢复 A 和 C。为什么要搞出 O?因为 O 可以直接从输出数据的协方差结构里估计出来,不需要输入。
输出 y_k 的协方差矩阵 R_j = E[y_{k+j} y_k^T] 是理论可观性和可辨识性的载体。把不同延时的 R_j 按块排成一个矩阵,这个矩阵的列空间恰好等于可观测矩阵的列空间。于是问题被拆成两半:先用响应数据把 O_i 算出来,再从 O_i 的结构里把系统矩阵 A 回归出来。这个过程不依赖任何输入测量,这就是 SSI 适合环境激励的根本原因。对比 ERA 和 ITD 这类方法,ERA 需要脉冲响应,ITD 对噪声更敏感;SSI 直接把手上的随机响应当成白噪声激励下的输出,跟现场实测数据的形态最匹配。
“随机子空间”这个叫法,来源于算法里最关键的一步:对协方差矩阵或投影矩阵做 SVD 截断,把观测空间投影到由系统主导子空间张成的低维子空间上。这个子空间本身是从随机响应里估计出来的,所以叫随机子空间。理解这一点对后面调参很重要,因为所有稳定图相关的“玄学”问题,本质上都是这个子空间截断截得准不准的问题。
2.2 从 Toeplitz 矩阵到系统矩阵:SSI 的两条路线(SSI-COV 与 SSI-DATA)
常见的 SSI 实现分两条路线。第一条是协方差驱动 SSI-COV:先算协方差序列 R_1, R_2, ...,再排成块 Toeplitz 矩阵 T,对 T 做 SVD 得到 O_i。第二条是数据驱动 SSI-DATA:直接对原始响应数据的块 Hankel 矩阵做 LQ 分解,把投影矩阵 SVD 后得到 O_i。两条路线数学上等价,数值表现差别不小。
| 路线 | 核心矩阵 | 数值稳定性 | 计算量 | 适合场景 |
|---|---|---|---|---|
| SSI-COV | 块 Toeplitz | 中 | 小 | 长记录、通道数少 |
| SSI-DATA | 块 Hankel + 投影 | 高 | 较大 | 通道多、模态密集 |
我一般会先用 SSI-COV 做快速摸底,确认频率范围后再切到 SSI-DATA 做精细识别。原因很简单:SSI-COV 矩阵尺寸小,试参数快,几分钟能扫完几十种阶次组合;SSI-DATA 数值稳定性好,但计算量大,适合已经把参数摸清楚之后跑最终结果。很多网上下载的 SSI 工具包默认实现是其中之一,你看代码里如果先构造了 Toeplitz 矩阵再 SVD,就是 SSI-COV;如果出现 LQ 分解或 QR 分解再投影,就是 SSI-DATA。
要注意一个容易翻车的细节:SVD 截断阶次 n 是模型阶次,而不是模态数。一个物理模态对应一对复共轭极点,所以模型阶次至少是物理模态数的两倍。如果真实系统有 3 阶模态,n 至少要取 6;实际工程里为了容纳噪声,n 会取到 30、50 甚至更高,靠稳定图来筛掉多余极点。这也是稳定图存在的意义:阶次不是算出来的,是扫出来的。
2.3 稳定图扫描逻辑与三组判据:频率、阻尼、MAC
稳定图的具体做法是把模型阶次 n 从低到高逐步增加,每算一个阶次就把 A 的所有特征值换算成频率和阻尼比,按阶次画在纵轴上。真实模态对应的极点在相邻阶次之间位置几乎不动,连成一条竖直的稳定轴;噪声极点则随机漂移,甚至出现负阻尼,一眼就能看出来。
判断两个相邻阶次的极点是不是同一个物理模态,工程上常用三组判据:频率相对偏差、阻尼比绝对偏差、振型 MAC 值。频率偏差通常要求小于 1%,阻尼偏差按绝对差算,一般小于 0.03 到 0.05,MAC 值要求大于 0.9。只有三者同时满足,才把这个点标记为稳定点。
这三个判据的敏感性完全不同。频率最稳,几乎不会误判;阻尼最飘,因为阻尼比的估计方差天然大;MAC 对传感器布点很敏感,通道少或测点靠近节点时容易失效。所以调参时我习惯先把 MAC 阈值放松到 0.8,等稳定图主轴出来了再收紧。另外还要提前剔除阻尼为负或超过 20% 的极点,这些基本可以断定是过拟合出来的数学极点,留在图里只会把稳定轴的对比度拉低。
3. 用 MATLAB 从零搭一套 SSI 稳定图:仿真数据验证与核心函数
3.1 生成三自由度仿真响应:白噪声激励与传感器连接
搭稳定图之前先要有可信的数据。我用一个最简单的三自由度质量弹簧阻尼系统做仿真,白噪声激励,三个通道全部输出加速度。这样做的好处是物理模态数量已知,后面任何一根稳定轴对不上真实频率,都能立刻判断是算法的问题还是参数的问题。
% gen_data.m —— 生成3自由度仿真响应,供SSI稳定图验证 clear; clc; rng(1); fs = 100; % 采样率 100Hz T = 60; % 时长 60 秒 N = fs * T; % 总点数 t = (0:N-1)' / fs; % 三自由度质量-弹簧-阻尼系统 m = [1 1 1]; k = [300 300 300]; c = [0.3 0.3 0.3]; M = diag(m); K = zeros(3); C = zeros(3); for i = 1:3 K(i,i) = K(i,i) + k(i); C(i,i) = C(i,i) + c(i); if i > 1 K(i-1,i) = K(i-1,i) - k(i); K(i,i-1) = K(i,i-1) - k(i); C(i-1,i) = C(i-1,i) - c(i); C(i,i-1) = C(i,i-1) - c(i); end end % 状态空间模型,输出加速度 A = [zeros(3) eye(3); -M\K -M\C]; B = [zeros(3); M\eye(3)]; Css = [-M\K -M\C]; Dss = M\eye(3); u = randn(N,3); % 三处独立白噪声激励 y = lsim(ss(A,B,Css,Dss), u, t); y = y + 0.05 * std(y) .* randn(size(y)); % 5%测量噪声 save sim_data.mat y fs这段代码的关键是激励和输出都在同一套状态空间里,激励是每个自由度上的独立白噪声,符合 SSI 的假设前提。刚度取 300 N/m,质量取 1 kg,三阶固有频率大致落在 1.5Hz 到 7Hz 区间,肉眼能从时程里看出明显的振动包络。阻尼取值很小,阻尼比约在 0.5% 到 1.5% 之间,这样稳定图上真实极点非常锐利,适合用来验证算法是否写对。
如果你拿到的是实测数据,只需把 y 替换成 l 行 N 列的加速度矩阵,fs 改成实际采样率,其余流程完全一样。需要提醒的是实测数据里一定要先去掉均值、去掉趋势项,不然那些直流分量和低频漂移会被识别成频率接近 0Hz 的虚假极点,把稳定图的下半部分搅成一团。
3.2 SSI-COV 核心函数:协方差、Toeplitz 与 SVD 截断
下面这个函数是我常用的 SSI-COV 实现,输入是响应矩阵、采样频率、模型阶次 n 和 Toeplitz 块行数 i,输出是正频率极点、阻尼比和对应振型分量。这个函数直接支持后续稳定图循环,不需要重复计算协方差。
% ssi_cov.m —— 协方差驱动随机子空间识别 function [freqs, damps, modes] = ssi_cov(y, fs, n, i) % y : l×N 响应矩阵,每行一个通道 % fs : 采样率(Hz) % n : 模型阶次,通常取偶数 % i : Toeplitz 块行数,每块尺寸为 l×l % 输出 : 正频率极点的频率(Hz)、阻尼比、l×n_ok 振型矩阵 [l, N] = size(y); if N <= 2*i error('数据太短,无法构造 Toeplitz 矩阵'); end % 1) 协方差序列 R_1 到 R_{2i} R = zeros(l, l, 2*i); for k = 1:2*i Rk = zeros(l); for t = 1:N-k Rk = Rk + y(:, t+k) * y(:, t)'; end R(:,:,k) = Rk / (N - k); end % 2) 构造块 Toeplitz 矩阵 T = zeros(i*l, i*l); for r = 1:i for c = 1:i T((r-1)*l+1:r*l, (c-1)*l+1:c*l) = R(:,:, r + i - c); end end % 3) SVD 截断得到可观测矩阵 [U, S, ~] = svd(T); U = U(:, 1:n); S = sqrt(S(1:n, 1:n)); O = U * S; % 4) 从可观测矩阵提取 C 和 A C = O(1:l, :); A = pinv(O(1:l*(i-1), :)) * O(l+1:l*i, :); % 5) 特征值并转换到连续域 [V, D] = eig(A); s = log(diag(D)) * fs; % 离散特征值转换到连续极点 wn = abs(s); freq_raw = wn / (2*pi); damp_raw = -real(s) ./ wn; mode_raw = C * V; % 6) 保留虚部为正、频率>0、阻尼在0~20%的极点 ok = (imag(s) > 0) & (freq_raw > 0) & (damp_raw > 0) & (damp_raw < 0.2); freqs = freq_raw(ok); damps = damp_raw(ok); modes = mode_raw(:, ok); endSVD 截断是整段代码的核心,n 是截断后保留的列数。需要特别注意的是 n 一定不能超过 i*l,否则 SVD 后根本没有那么多有效奇异值。一个物理模态对应两个共轭极点,所以 n 取偶数最自然。步骤 4 里用最小二乘从可观测矩阵的位移不变性估计 A,这样求出来的 A 是一个 n 维系统矩阵,特征值和原始连续系统有相同的模态信息。
这里的 i 就是稳定图质量最敏感的参数,i 取 20 到 40 是常见起点。i 太小,Toeplitz 矩阵包含的协方差信息不够,低频模态估计偏;i 太大,协方差序列尾部噪声累积,稳定图会变得非常乱。后面第 4 章会单独讲这块的调整经验。
3.3 稳定图主循环与绘制:阶次遍历与极点配对
有了 ssi_cov 函数,稳定图本身就是一个循环加一个配对函数。配对逻辑是:对当前阶次的每个极点,在上一阶次的所有极点里找频率最接近的一个,然后判断频率偏差、阻尼偏差和 MAC 值是否同时达标。
% stab_diagram.m —— 遍历阶次生成稳定图 clear; clc; load sim_data.mat; % y, fs y = y'; % 转置为 l×N orders = 2:2:40; % 阶次扫描范围 i_blk = 30; % Toeplitz 块行数 prev = []; % 上一次的极点集合 figure; hold on; for n = orders [f, d, phi] = ssi_cov(y, fs, n, i_blk); if isempty(f), continue; end % 第一阶次没有上一阶,只画黑点 if isempty(prev) plot(f, n*ones(size(f)), 'k.', 'MarkerSize', 4); else [flag] = stability_match(prev.f, prev.d, prev.phi, f, d, phi); plot(f, n*ones(size(f)), 'k.', 'MarkerSize', 4); plot(f(flag), n*ones(nnz(flag)), 'g.', 'MarkerSize', 8); end prev = struct('f', f, 'd', d, 'phi', phi); end xlabel('频率 (Hz)'); ylabel('模型阶次'); title('SSI 稳定图(黑点:极点,绿点:稳定点)'); grid on;% stability_match.m —— 相邻阶次极点配对与稳定判断 function [is_stable] = stability_match(f1, d1, phi1, f2, d2, phi2) is_stable = false(size(f2)); for k = 1:numel(f2) [~, j] = min(abs(f2(k) - f1)); % 频率最近配对 df = abs(f2(k) - f1(j)) / f1(j); dd = abs(d2(k) - d1(j)); mac = abs(phi1(:,j)' * phi2(:,k)) / (norm(phi1(:,j)) * norm(phi2(:,k))); is_stable(k) = (df < 0.01) && (dd < 0.03) && (mac > 0.9); end end这段逻辑里频率配对用的是“最近邻”,简单直接,但对模态间距小于 1% 的密集模态会串线。处理密集模态时要把配对范围限制在 ±1Hz 以内,同时优先用 MAC 配对而不是频率配对,这个我会在第 4 章展开。画图时黑点是所有极点,绿点是满足三项判据的稳定点,肉眼扫一眼就能看到三个竖直的绿色主轴。
运行这段代码,正常情况会在约 1.5Hz、4Hz、7Hz 三个位置各出现一条绿色主轴。如果你看到主轴分散或者根本没有绿点,先检查仿真数据是否正常,再检查 i_blk 是否和阶次范围匹配。这个从零搭出来的流程虽然简陋,但胜在每一步都能拆开看,调参时比用一个来路不明的 SSI.rar 里的黑匣子函数要踏实得多。
4. 稳定图参数怎么设:阶次范围、块行数、判据阈值与自动取点
4.1 块行数与阶次范围:两个参数决定一张图的质量
稳定图画得乱,八成问题不在算法,而在 i_blk、orders 这两个结构参数没配对好。i_blk 决定了 Toeplitz 矩阵的行数,也就是可观测矩阵能表达的最大阶次。理论上 i_blk*l 必须大于最大模型阶次,实际工程中我会要求至少大出一倍,否则 SVD 截断会把有效信息一起截掉。
| 参数 | 我常用的起点 | 调整方向 |
|---|---|---|
| 块行数 i_blk | 30 | 数据长噪声大时加到 40~50;数据短时减到 20 |
| 起始阶次 | 2 | 固定不变 |
| 阶次步长 | 2 | 密集模态用 1,常规用 2 即可 |
| 最大阶次 | 40 | 通道多、结构复杂时可到 60 |
| 频率容差 | 0.01 | 模态密集时放宽到 0.02 |
| 阻尼容差 | 0.03 | 现场噪声大时放宽到 0.05 |
| MAC 阈值 | 0.90 | 通道少于 3 个时降到 0.80 |
阶次扫描上限也不是越大越好。阶次太高后,SVD 截断保留的奇异值全是噪声,A 矩阵会出现大量负阻尼极点,稳定图下半部分被墨点盖满。我一般按预计模态数的 10 倍左右设定最大阶次,比如预计结构有 4 到 5 阶有效模态,orders 取到 40 就够。如果扫到 60 还不停出现新的“稳定轴”,通常不是结构模态多,而是你的数据里有强周期干扰,比如设备工频或风机转频。
一个很容易被忽略的点是阶次步长。步长取 2 时,每个物理模态的共轭对是同时加入的,稳定配对比较干净;步长取 1 时,极点对会交替出现,稳定性判断容易跳变。所以我建议永远用偶数步长,除非你在做需要极高频率分辨率的特殊分析。
4.2 三种判据阈值的取值:先松后紧的调参顺序
稳定判据里频率最可靠,阻尼最不可靠,MAC 受测点布设影响大。我第一次跑一个新数据集时,会用一组“宽松起步”参数:频率容差 0.02、阻尼容差 0.05、MAC 阈值 0.8。这个配置下稳定图会偏浓,但至少不会把真实模态漏掉。确认主轴位置之后,再把阻尼容差收紧到 0.02 到 0.03,MAC 阈值提到 0.9,让图面干净一些,方便后续自动取点。
阻尼容差是稳定图里最需要小心的参数。阻尼比本质上是特征值实部与虚部的比值,实部由衰减速率决定,对噪声特别敏感。同一个物理模态在相邻阶次算出来的阻尼比,差 0.01 是常态,差 0.05 也不稀奇。所以阻尼容差第一次直接取 0.01 的话,真实模态也标不成稳定点,稳定图会“光秃秃”的,看不见稳定轴。
如果发现某根稳定轴非常清晰,但阻尼值在相邻阶次上反复横跳,我建议先别急着调阈值,而是检查数据里是否有一段非平稳干扰。我踩过这个坑:数据里有一段短暂的敲击,稳定图上阻尼全部异常,频率却完全正常。后来把那 2 秒数据切掉,阻尼就恢复稳定了。
4.3 自动选点:把散点收敛成一簇可信模态
稳定图人工判读能看出主轴,但交付报告时需要给出具体频率、阻尼和振型。我的做法是先把所有绿点按横坐标频率做核密度估计,然后用峰值定位找出候选模态频率,再对每个候选频率附近的绿点取均值和标准差。
% auto_pick.m —— 从稳定点自动提取模态参数 % 假设已经收集了绿点频率 f_stable、阻尼 d_stable、振型 phi_stable [f_pks, locs] = findpeaks(ksdensity(f_stable, 0:0.01:max(f_stable))); cand_f = locs(f_pks > 0.02 * max(f_pks)); % 高度阈值 modes_out = table(); for k = 1:numel(cand_f) sel = abs(f_stable - cand_f(k)) < 0.1; % 频率邻域 if nnz(sel) < 5, continue; end % 稳定点数太少,剔除 modes_out.Freq(k) = mean(f_stable(sel)); modes_out.Damp(k) = mean(d_stable(sel)); modes_out.DampStd(k) = std(d_stable(sel)); modes_out.Phi(:,k) = mean(phi_stable(:,sel), 2); end核密度带宽是自动取点里唯一需要微调的参数。带宽太小,同一个模态会出现多个峰;带宽太大,两个靠得近的模态会被并成一个。我一般用 0.05 到 0.1 倍主频间距做带宽,10Hz 以内的结构取 0.05Hz 基本够用。选出来的簇还要检查两个附加条件:簇内点数占比超过该阶次极点总数的 50%,簇内阻尼均值在 0 到 10% 之间。满足这两个条件,这簇点才值得进入最终模态表。
自动取点不是全自动的,主轴判断一定要人工扫一眼稳定图。遇到过一种特殊情况:某根“稳定轴”竖直贯穿所有阶次,频率、阻尼、MAC 全稳定,但它在频响函数上没有任何对应峰。后来查明那是传感器通道之间的电气串扰,两个通道的噪声完全相干,SSI 会把它当成一个高置信度的虚拟模态。自动聚类看不出来,只有跟频响函数对照时才会露馅。
5. SSI 稳定图常见问题排查:5 个高频翻车现象与对应解法
5.1 现象一:整个图面全是墨点,稳定主轴被淹没
现象:绿点很少,黑色极点密密麻麻,稳定图看起来像撒了一把胡椒面,完全看不出竖直的稳定轴。出现这种图,先检查判据阈值是不是放得太宽,比如阻尼容差到 0.1 以上、MAC 阈值低于 0.7,几乎所有相邻阶次的极点都会被标成稳定点。
原因通常是两个:一是判据阈值放太松,二是 i_blk 取得太大,导致协方差矩阵尾部噪声被 SVD 当成了系统信息。解决方法是先把阻尼容差收紧到 0.02,MAC 阈值提到 0.9,如果图面还乱,就把 i_blk 从 40 降到 25,重新观察主轴是否出现。这个排查顺序一般两轮就能定位问题。
5.2 现象二:稳定主轴中途断裂,低阶有高阶无
现象:低阶次范围里主轴很清晰,扫到某个阶次之后整条轴消失,再往高阶又出现,像是被人拦腰切断。先怀疑数据长度不够。SSI 需要足够长的数据来估计协方差,尤其是低频模态,数据总长至少要覆盖最低模态周期的 20 倍。如果最低阶是 1Hz,数据 30 秒勉强够,10 秒就会出问题。
另一个常见原因是激励能量集中在窄带里。如果现场主要激励是某个固定频率的旋转设备,其他频段能量太低,那些频段虽然物理上存在模态,但响应里几乎没有贡献,SSI 自然识别不出来。解决方法是先做频带白化,把响应分成多个子带分别做 SSI,再把各子带的稳定图合并。我一般在处理旋转机械数据时都用这个方法,单跑一条宽带稳定图几乎必翻车。
5.3 现象三:SSI 频率与峰值法对不上,稳定轴不在谱峰上
现象:稳定图主轴清晰,频率值和频响函数谱峰差了 5% 到 10%。如果阻尼比本来就小,这问题通常不是算法错误,而是两种方法的物理参考点不同。频响函数的幅值峰出现在有阻尼固有频率附近,峰的位置会随阻尼向右偏;SSI 提取的是无阻尼固有频率,本来就该落在谱峰斜坡上而不是峰尖上。
另一个可能性是离散化转换写错了。从离散特征值换算连续极点的公式是 s = log(lambda) * fs。有人图省事直接用角度换算频率 f = angle(lambda) * fs / (2*pi),这只在采样率极高、每周期采样点几十个时近似成立,普通数据下误差很容易到 5%。如果你在代码里看到这种写法,先改回对数换算再看结果。
5.4 现象四:SVD 奇异值看不到明显截断平台
现象:对 Toeplitz 矩阵做 SVD 后,奇异值从第一个开始平滑下降,没有明显阶梯,找不到该在哪一刀截断。这通常意味着输出通道之间相关性过强,比如三个传感器贴在同一块刚性板上,算出来的三路信号几乎一样,SVD 的前几个奇异值全部接近,截断阶次怎么选都不对。
解决方法是先对响应做通道预减。最简单的做法是计算各通道相关系数矩阵,把相关系数超过 0.95 的通道合并或去掉,只保留其中一路。另一个更稳健的做法是对响应做 PCA,只保留累计贡献率超过 95% 的主成分,再进入 SSI。这样处理之后奇异值的阶梯通常会变得很明显,稳定图也干净得多。
5.5 现象五:负阻尼极点成堆,稳定图下方全是“发散的轴”
现象:识别出来的极点多达一半是负阻尼,也就是特征值实部为正,系统反而是发散的。物理系统不可能持续发散,负阻尼基本都是过拟合或数据非平稳造成的。最常见的原因是数据里包含瞬态段,比如敲击激励、开关机冲击、车辆经过的局部冲击。
解决思路是数据段清洗优先于算法调参。把数据按时间窗切段,逐段计算均方根值,把均方根超过整段中位数 3 倍以上的短段剔除。剔除后如果负阻尼还是没有减少,再检查阶次上限是不是太高,把 orders 最大值降 20% 通常能滤掉一批虚极点。负阻尼点要不要画在稳定图上?我习惯画出来但标记为灰色,这样能直观看到过拟合的起点在哪个阶次,对判断合理阶次上限很有用。
6. 稳定图结果怎么验证:叠加频响函数做最后一道检查
6.1 双轴叠加法:把稳定点画在 PSD 上
稳定图给出的是候选模态,最后一道检查永远是把它跟频域的谱峰对照。我的做法是把自动取点得到的稳定极点按绿色散点画在功率谱密度图上方,频率轴完全对齐。真实模态的频率值会落在谱峰附近,虚假模态会悬在谱谷里。这个验证对数据质量不敏感,一眼就能看出哪些极点是算法自己的“幻觉”。
% validate.m —— 稳定点与PSD双轴叠加 figure; [pmm, f] = pwelch(mean(y,1), hann(8192), 4096, 8192, fs); yyaxis left; semilogy(f, pmm, 'b-'); ylabel('PSD'); yyaxis right; plot(modes_out.Freq, 1:height(modes_out), 'g.', 'MarkerSize', 14); ylabel('模态序号'); xlabel('频率 (Hz)'); grid on;6.2 分段重复性检验:同一数据切两半,结果必须在容差内
更严格的做法是把 60 秒数据切成两段 30 秒,分别跑完整 SSI 流程,然后对比两组结果的频率和 MAC。频率偏差小于 1%、MAC 大于 0.9 的模态才进入最终交付表。这个方法能有效识别噪声模态:真实模态在任何数据段里都存在,噪声模态则依赖特定段里的随机成分,两次结果很难一致。
6.3 交付前最后一步:看一眼阻尼的标准差
我现在拿到一组稳定图,第一件事不是看频率,而是把自动选点出来的每个模态阻尼标准差摊开看。如果某个“模态”的阻尼比在相邻阶次里来回横跳,标准差超过均值的一半,我会直接怀疑它是噪声模态。这个习惯来自一次把噪声模态当真实模态交付的教训,从那以后每次输出模态表之前都会查这一项。希望帮到你。
本文还有配套的精品资源,点击获取