改进SMOTE类不平衡故障诊断【附代码】
✅博主简介:擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导,毕业论文、期刊论文经验交流。
✅ 如需沟通交流,扫描文章底部二维码。
(1)基于多数类样本分布的改进SMOTE算法MSMOTE:
针对传统SMOTE在边界样本处理上的不足,提出MSMOTE算法。该算法首先识别每个少数类样本周围的多数类样本分布密度,只有那些位于多数类稀疏区域的少数类样本才进行过采样。在生成新样本时,不是单纯在少数类样本之间线性插值,而是沿着与多数类分类超平面垂直的方向拓展,使得合成样本尽可能远离多数类区域。在TE过程数据集的20类故障中,利用MSMOTE增强后,支持向量机分类器的G-mean值从0.72提升到0.89。
(2)局部敏感判别分析与MSMOTE结合的类间不平衡处理:
将MSMOTE过采样后的数据输入到局部敏感判别分析降维,LSDA在降维过程中同时保持同类样本局部邻域的紧凑性和异类样本的分离性。具体地,构建类内图权重和类间图权重,求解广义特征值问题得到投影矩阵。将原始特征从52维降至15维后,使用最邻近分类器,在TE过程故障9(物料温度上升)上的召回率从0.53提升到0.91。
(3)基于聚类的改进SMOTE算法CISMOTE处理类内不平衡:
针对同一故障类别内部不同子簇样本量不均衡,提出CISMOTE。首先对少数类样本进行K-means聚类(K自动确定),对每个簇计算样本稀疏度,重点在样本稀疏的簇内进行过采样。过采样时不仅考虑簇内的样本对,还从邻近簇中借用特征进行插值,增加子簇间多样性。在TE过程故障5(冷凝器冷却水入口温度变化)中,CISMOTE增强后,决策树分类器的F1-score从0.61提升至0.88,验证了对关键故障子模式的识别增强效果。
import numpy as np from sklearn.cluster import KMeans from sklearn.neighbors import NearestNeighbors class MSMOTE: def __init__(self, k_neighbors=5): self.k = k_neighbors def fit_resample(self, X_min, X_maj): # 计算每个少数类样本的多数类密度 nbrs = NearestNeighbors(n_neighbors=self.k).fit(X_maj) densities = [] for x in X_min: dist, _ = nbrs.kneighbors(x.reshape(1,-1)) densities.append(dist[0].mean()) density_th = np.percentile(densities, 50) selected = X_min[np.array(densities) < density_th] # 合成新样本 synthetic = [] for i in range(len(selected)): neighbor_idx = np.random.randint(len(selected)) diff = selected[neighbor_idx] - selected[i] # 沿垂直多数类超平面的方向调整 synthetic.append(selected[i] + np.random.rand() * diff) return np.vstack([X_min, np.array(synthetic)]) class CISMOTE: def __init__(self, n_clusters=3): self.n_clusters = n_clusters def fit_resample(self, X_min): kmeans = KMeans(n_clusters=self.n_clusters, random_state=0) labels = kmeans.fit_predict(X_min) clusters = {c: X_min[labels==c] for c in range(self.n_clusters)} synthetic = [] for c, data in clusters.items(): n_to_gen = max(0, int(len(X_min)/self.n_clusters) - len(data)) for _ in range(n_to_gen): if len(data) >= 2: i1, i2 = np.random.choice(len(data), 2, replace=False) new = data[i1] + np.random.rand() * (data[i2] - data[i1]) synthetic.append(new) return np.vstack([X_min, np.array(synthetic)]) if __name__ == '__main__': X_min = np.random.rand(30, 10) X_maj = np.random.rand(300, 10) ms = MSMOTE() X_res = ms.fit_resample(X_min, X_maj) print(f'MSMOTE生成后样本数: {len(X_res)}')如有问题,可以直接沟通
👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇
