news 2026/4/15 20:36:15

基于学习字典与加权稀疏表示的滚动轴承稀疏表示故障诊断【附代码】

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于学习字典与加权稀疏表示的滚动轴承稀疏表示故障诊断【附代码】

博主简介:擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导,毕业论文、期刊论文经验交流。

✅成品或者定制,扫描文章底部微信二维码。


(1) 基于优化共振稀疏分解的轴承微弱故障特征增强方法

滚动轴承在复杂工况条件下运行时,其振动信号中的故障特征往往十分微弱,容易被环境噪声、机械传动干扰和转速波动等因素所掩盖,给故障早期检测带来极大困难。共振稀疏信号分解是一种基于信号形态学特征的分离技术,能够将原始振动信号分解为高共振分量、低共振分量和残余分量三个部分,其中低共振分量包含了与轴承故障冲击相关的瞬态成分,而高共振分量则主要是周期性的转动频率成分。然而该方法的分解效果强烈依赖于品质因子等关键超参数的选择,不恰当的参数设置可能导致目标故障成分无法被有效分离。针对这一问题,本研究引入蜣螂优化算法对共振稀疏分解的超参数进行自动寻优。蜣螂优化算法是一种模拟蜣螂滚球、跳舞和觅食行为的新型群体智能算法,具有收敛速度快和全局搜索能力强的特点。以分解后低共振分量的峭度值作为优化目标,通过迭代搜索确定能够最大化故障冲击成分峭度的最优参数组合。在完成信号分解后,对低共振分量进行子带能量分析,利用谱峭度或包络谱能量分布准则筛选出包含主要冲击成分的频带并进行叠加重构。考虑到轴承故障信号本质上是周期性冲击与传递路径卷积的结果,进一步采用多点最优最小熵解卷积算法对重构信号进行处理,通过反卷积运算增强周期性冲击的尖锐程度并抑制传递函数的平滑效应。经过上述多阶段处理后,对增强信号进行包络解调和频谱分析,可以清晰地识别出与轴承内圈、外圈或滚动体故障特征频率相对应的谱峰,实现微弱故障的有效检测。

(2) 基于自适应分解与稀疏贝叶斯学习的复合故障分离诊断方法

在实际工业环境中,滚动轴承可能同时存在多个故障部位或多种故障类型的复合故障情况,不同故障产生的振动响应相互叠加耦合,使得各故障成分的特征频率混杂在一起难以分辨。传统的单一故障诊断方法在面对复合故障时往往力不从心,容易出现漏诊或误诊。本研究提出一种融合自适应模态分解与稀疏贝叶斯学习的阶段性故障分离策略,旨在将复合故障信号中的不同故障成分逐一分离并分别诊断。在信号预处理阶段,设计一种基于复合评价指标的自适应模态分解方法,该指标综合考虑分解分量的故障敏感度、信噪比和模态正交性等因素。通过可调品质因子的滤波器组对原始信号进行多尺度分解,自适应地选择能够最大化复合指标的分解模式,并利用互相关系数剔除冗余的模态分量。对筛选后的有效模态分量分别进行包络谱分析,采用包络谐波积谱方法估计各分量中可能存在的故障特征频率。包络谐波积谱通过计算包络谱在基频及其整数倍谐波处幅值的乘积来增强周期性成分的辨识度,能够在强噪声背景下更准确地估计故障特征频率。将估计得到的特征频率作为稀疏贝叶斯学习的先验知识,构建包含各故障频率成分的字典矩阵,利用贝叶斯推理框架求解信号在该字典上的稀疏表示系数。稀疏贝叶斯学习能够自动确定系数的稀疏度并给出各频率成分的后验概率分布,根据稀疏系数的幅值和置信区间可以判断对应故障成分是否存在以及其严重程度。

(3) 基于学习字典与加权稀疏表示的轴承故障分类识别方法

面向工业大数据场景下的轴承故障自动分类识别需求,本研究提出一种结合字典学习与加权稀疏表示的智能诊断方法。传统的稀疏表示分类方法采用固定的过完备字典对信号进行稀疏编码,但固定字典难以充分适应不同工况和不同设备采集的振动信号特征差异。为了提高字典对目标信号的表示能力,采用基于奇异值分解的字典学习算法从训练样本中自适应地学习最优字典原子。该算法通过交替优化稀疏编码和字典更新两个步骤,使学习得到的字典能够以最少的原子数量精确重构训练信号,从而捕捉信号中的本质特征结构。在分类识别阶段,针对传统稀疏表示分类中所有样本同等对待而忽视信号局部特征差异的问题,设计一种基于时域统计特征的样本加权策略。具体而言,计算测试样本与各类训练样本在峭度、偏度、波形因子等时域指标上的相似度,将相似度较高的训练样本在稀疏表示中赋予更大的权重。

import numpy as np from scipy.signal import hilbert, butter, filtfilt, find_peaks from scipy.fft import fft, ifft, fftfreq from sklearn.base import BaseEstimator, ClassifierMixin from sklearn.preprocessing import normalize class DBOOptimizer: def __init__(self, objective, dim, bounds, pop_size=30, max_iter=100): self.objective = objective self.dim = dim self.bounds = np.array(bounds) self.pop_size = pop_size self.max_iter = max_iter def optimize(self): lb, ub = self.bounds[:, 0], self.bounds[:, 1] population = lb + (ub - lb) * np.random.rand(self.pop_size, self.dim) fitness = np.array([self.objective(ind) for ind in population]) best_idx = np.argmax(fitness) best_solution = population[best_idx].copy() best_fitness = fitness[best_idx] for t in range(self.max_iter): sorted_idx = np.argsort(fitness)[::-1] n_ball_rolling = int(0.4 * self.pop_size) for i in sorted_idx[:n_ball_rolling]: alpha = 1 - t / self.max_iter k = 0.1 * np.random.randn(self.dim) b = 0.3 * np.random.randn(self.dim) population[i] = population[i] + alpha * k * (best_solution - population[i]) + b n_breeding = int(0.3 * self.pop_size) for i in sorted_idx[n_ball_rolling:n_ball_rolling + n_breeding]: local_best = population[sorted_idx[np.random.randint(0, n_ball_rolling)]] population[i] = population[i] + np.random.randn(self.dim) * (local_best - population[i]) for i in sorted_idx[n_ball_rolling + n_breeding:]: population[i] = lb + (ub - lb) * np.random.rand(self.dim) population = np.clip(population, lb, ub) fitness = np.array([self.objective(ind) for ind in population]) current_best_idx = np.argmax(fitness) if fitness[current_best_idx] > best_fitness: best_fitness = fitness[current_best_idx] best_solution = population[current_best_idx].copy() return best_solution, best_fitness class ResonanceSparseSeparator: def __init__(self, signal, fs): self.signal = signal self.fs = fs def tqwt_decompose(self, Q, r, J): N = len(self.signal) X = fft(self.signal) subbands = [] for j in range(J): alpha = 1 - 1 / (Q + 1) beta = 1 / r low_freq = self.fs / 2 * alpha**j * beta high_freq = self.fs / 2 * alpha**j freqs = fftfreq(N, 1/self.fs) mask = (np.abs(freqs) >= low_freq) & (np.abs(freqs) <= high_freq) subband_fft = X * mask subbands.append(np.real(ifft(subband_fft))) return np.array(subbands) def compute_kurtosis(self, signal): mean = np.mean(signal) std = np.std(signal) if std < 1e-10: return 0 return np.mean((signal - mean)**4) / std**4 def optimize_decomposition(self, Q_range=(1, 10), r_range=(2, 6), J_range=(3, 10)): def objective(params): Q, r, J = params J = int(J) try: subbands = self.tqwt_decompose(Q, r, J) low_resonance = np.sum(subbands[J//2:], axis=0) return self.compute_kurtosis(low_resonance) except: return 0 optimizer = DBOOptimizer(objective, dim=3, bounds=[Q_range, r_range, J_range]) best_params, best_kurtosis = optimizer.optimize() return best_params def extract_fault_component(self, Q, r, J): subbands = self.tqwt_decompose(Q, r, int(J)) kurtosis_values = [self.compute_kurtosis(sb) for sb in subbands] threshold = np.mean(kurtosis_values) + np.std(kurtosis_values) selected_idx = [i for i, k in enumerate(kurtosis_values) if k > threshold] if len(selected_idx) == 0: selected_idx = [np.argmax(kurtosis_values)] return np.sum(subbands[selected_idx], axis=0) class MOMEDADeconvolution: def __init__(self, filter_length=100, num_impulses=5): self.L = filter_length self.M = num_impulses def compute_momeda(self, signal, period): N = len(signal) target = np.zeros(N) impulse_positions = np.arange(0, N, int(period))[:self.M] target[impulse_positions] = 1 X = np.zeros((N - self.L + 1, self.L)) for i in range(N - self.L + 1): X[i] = signal[i:i + self.L] y = target[self.L - 1:] XtX = X.T @ X Xty = X.T @ y f = np.linalg.solve(XtX + 0.01 * np.eye(self.L), Xty) return np.convolve(signal, f, mode='same') class EnvelopeHarmonicProductSpectrum: def __init__(self, fs, max_harmonics=5): self.fs = fs self.max_harmonics = max_harmonics def compute_ehps(self, signal): analytic = hilbert(signal) envelope = np.abs(analytic) N = len(envelope) envelope_fft = np.abs(fft(envelope))[:N//2] freqs = fftfreq(N, 1/self.fs)[:N//2] hps = np.ones_like(envelope_fft) for h in range(1, self.max_harmonics + 1): decimated = envelope_fft[::h] hps[:len(decimated)] *= decimated return freqs, hps def estimate_fault_frequency(self, signal, freq_range=(50, 500)): freqs, hps = self.compute_ehps(signal) mask = (freqs >= freq_range[0]) & (freqs <= freq_range[1]) valid_freqs = freqs[mask] valid_hps = hps[mask] peaks, _ = find_peaks(valid_hps, height=np.mean(valid_hps)) if len(peaks) > 0: return valid_freqs[peaks[np.argmax(valid_hps[peaks])]] return valid_freqs[np.argmax(valid_hps)] class SparseBayesianLearning: def __init__(self, max_iter=500, tol=1e-6): self.max_iter = max_iter self.tol = tol def build_dictionary(self, N, frequencies, fs): t = np.arange(N) / fs D = [] for f in frequencies: D.append(np.cos(2 * np.pi * f * t)) D.append(np.sin(2 * np.pi * f * t)) return np.array(D).T def fit(self, y, D): N, M = D.shape alpha = np.ones(M) beta = 1.0 for _ in range(self.max_iter): Sigma = np.linalg.inv(np.diag(alpha) + beta * D.T @ D) mu = beta * Sigma @ D.T @ y gamma = 1 - alpha * np.diag(Sigma) alpha_new = gamma / (mu**2 + 1e-10) beta_new = (N - np.sum(gamma)) / np.sum((y - D @ mu)**2) if np.max(np.abs(alpha_new - alpha)) < self.tol: break alpha = alpha_new beta = beta_new return mu, Sigma class KSVDDictionary: def __init__(self, n_atoms=256, sparsity=10, max_iter=50): self.n_atoms = n_atoms self.sparsity = sparsity self.max_iter = max_iter self.dictionary = None def initialize_dictionary(self, signals): n_samples = signals.shape[0] indices = np.random.choice(n_samples, self.n_atoms, replace=False) self.dictionary = signals[indices].T self.dictionary = normalize(self.dictionary, axis=0) def omp_sparse_code(self, signal): residual = signal.copy() indices = [] coefficients = np.zeros(self.n_atoms) for _ in range(self.sparsity): correlations = np.abs(self.dictionary.T @ residual) correlations[indices] = 0 best_idx = np.argmax(correlations) indices.append(best_idx) D_selected = self.dictionary[:, indices] coef = np.linalg.lstsq(D_selected, signal, rcond=None)[0] residual = signal - D_selected @ coef coefficients[indices] = coef return coefficients def fit(self, signals): self.initialize_dictionary(signals) for _ in range(self.max_iter): codes = np.array([self.omp_sparse_code(s) for s in signals]) for j in range(self.n_atoms): indices = np.where(codes[:, j] != 0)[0] if len(indices) == 0: continue E = signals[indices].T - self.dictionary @ codes[indices].T + np.outer(self.dictionary[:, j], codes[indices, j]) U, S, Vt = np.linalg.svd(E, full_matrices=False) self.dictionary[:, j] = U[:, 0] codes[indices, j] = S[0] * Vt[0] return self.dictionary class WeightedSparseClassifier(BaseEstimator, ClassifierMixin): def __init__(self, sparsity=15): self.sparsity = sparsity self.dictionary_learner = KSVDDictionary() self.train_data = None self.train_labels = None def compute_sample_weights(self, test_sample): weights = [] test_kurtosis = np.mean((test_sample - np.mean(test_sample))**4) / (np.std(test_sample)**4 + 1e-10) test_skewness = np.mean((test_sample - np.mean(test_sample))**3) / (np.std(test_sample)**3 + 1e-10) for train_sample in self.train_data: train_kurtosis = np.mean((train_sample - np.mean(train_sample))**4) / (np.std(train_sample)**4 + 1e-10) train_skewness = np.mean((train_sample - np.mean(train_sample))**3) / (np.std(train_sample)**3 + 1e-10) dist = np.sqrt((test_kurtosis - train_kurtosis)**2 + (test_skewness - train_skewness)**2) weights.append(np.exp(-dist)) return np.array(weights) def fit(self, X, y): self.train_data = X self.train_labels = y self.classes_ = np.unique(y) self.dictionary_learner.fit(X) return self def predict(self, X): predictions = [] for test_sample in X: weights = self.compute_sample_weights(test_sample) residuals = [] for c in self.classes_: class_mask = self.train_labels == c class_samples = self.train_data[class_mask] class_weights = weights[class_mask] weighted_reconstruction = np.average(class_samples, axis=0, weights=class_weights) residual = np.linalg.norm(test_sample - weighted_reconstruction) residuals.append(residual) predictions.append(self.classes_[np.argmin(residuals)]) return np.array(predictions)

如有问题,可以直接沟通

👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/12 8:22:40

百考通:陪你走完毕业论文的最后一公里

又到毕业季&#xff0c;当别人已经在为答辩做准备&#xff0c;你还在对着空白文档发呆&#xff1f;面对“选题太老没新意、结构混乱逻辑差、格式不规范被打回”的难题&#xff0c;别慌——百考通&#xff08;https://www.baikaotongai.com&#xff09;的毕业论文全流程服务&…

作者头像 李华
网站建设 2026/4/13 15:54:53

使用VirtualLab Fusion属性浏览器获取更多光场信息

摘要 在研究任何结果时&#xff0c;快速方便地获取所有必要信息是关键。为此&#xff0c;VirtualLab Fusion 使用Property Browser直接向用户提供有关任何选定对象的物理和数值信息的完整摘要。 在哪里可以找到Property Browser&#xff1f; Property Browser位于主窗口右…

作者头像 李华
网站建设 2026/4/16 12:33:39

【科研绘图系列】R语言绘制图多组箱线图(boxplot)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍 加载R包 数据下载 导入数据 数据预处理 画图 总结 系统信息 参考 介绍 这篇代码展示了使用R语言进行真菌基因组比较分析的高级数据可视化流程,核心目标是探究机会性病原菌与腐生…

作者头像 李华
网站建设 2026/4/16 14:21:22

计算机毕业设计|基于ssm + vue超市管理系统(源码+数据库+文档)

超市管理 目录 基于ssm vue超市管理系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 基于ssm vue超市管理系统 一、前言 博主介绍&#xff1a;✌️大厂码农|毕设布道…

作者头像 李华
网站建设 2026/4/11 4:05:01

别急着删索引!MySQL的隐藏索引让你安全试错

本文首发于「数据库干货铺」公众号&#xff0c;转载请联系授权。在日常的数据库运维中&#xff0c;相信不少DBA都遇到过这样的困境&#xff1a;某个索引到底有没有用&#xff1f;删除会不会影响系统性能&#xff1f;留着又怕影响写入速度。MySQL8.0带来的隐藏索引功能&#xff…

作者头像 李华
网站建设 2026/4/16 14:32:49

基于springboot 网上超市系统(源码+数据库+文档)

网上超市 目录 基于springboot vue网上超市系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 基于springboot vue网上超市系统 一、前言 博主介绍&#xff1a;✌️大…

作者头像 李华