基于九轴传感器 + K-means 聚类的振动异常检测实战教程

(嵌入式 / 工业监测场景:设备振动、电机故障、结构松动、碰撞异常实时检测)

一、前言(你能学到什么)

这篇文章不讲虚的,直接带你做一个工业级轻量异常检测系统

  • LSM6DS3TR-C(6 轴)+ 磁力计 = 九轴传感器 采集振动数据
  • K-means 无监督聚类算法 做异常侦测
  • 全程不需要标签、不需要深度学习、单片机可跑
  • 原理 + 代码 + 工程思路 一次性讲透

适合:设备监测、预测性维护、物联网边缘计算、嵌入式 AI 入门。


二、系统整体原理(一句话讲清楚)

核心逻辑

  1. 正常设备振动 = 稳定、规律、特征集中
  2. 异常振动 = 剧烈、突变、偏离正常模式
  3. K-means 任务 :学习正常振动的 "特征分布",把偏离分布的数据判定为异常

为什么用 K-means?

  • 无监督:只需要正常数据,不需要异常样本
  • 超轻量:可跑在 STM32 / ESP32 上
  • 可解释性强:靠距离判断异常
  • 工业界最常用的传统异常检测算法

三、硬件与数据基础

1. 九轴传感器组成

你用的 LSM6DS3TR-C 是:

  • 加速度计 ACC(X/Y/Z)→ 振动核心数据
  • 陀螺仪 GYRO(X/Y/Z)→ 角速度 / 抖动
  • 外加磁力计 MAG(X/Y/Z)→ 9 轴

振动检测主要依赖:加速度计(ACC)

2. 振动数据是什么?

设备运行时,三轴加速度会周期性小幅波动:

  • 正常:波动小、稳定
  • 异常:波动大、突变、冲击、噪声

原始数据是时序信号 ,不能直接喂 K-means,必须提取特征


四、核心原理:为什么 K-means 能检测异常?

1. K-means 是什么

K-means 是无监督聚类算法,自动把相似数据分成 K 组。

2. 异常检测原理(关键)

  • 大量正常振动数据训练 K-means
  • 算法会把正常数据聚成几个紧凑的簇
  • 新数据进来后:
    • 计算到最近簇中心的距离
    • 距离 > 阈值 = 异常

一句话:K-means 异常检测 = 距离异常检测


五、完整工程流程(一步都不跳)

流程总览

  1. 传感器采集原始加速度数据
  2. 滑动窗口截取一段振动
  3. 提取振动特征(RMS、方差、均值等)
  4. 用正常特征训练 K-means 模型
  5. 实时推理:计算距离 → 判断异常

六、特征工程(最重要!不能直接用原始数据)

原始三轴加速度是时序波形,必须转成固定长度特征向量

最适合振动的特征(工业标准)

  1. RMS 均方根 → 振动强度
  2. STD 标准差 → 波动程度
  3. Mean 均值 → 基线偏移
  4. Max / Min → 冲击峰值
  5. 频域能量(可选)

最终特征向量(6~9 维)

plaintext

复制代码
[
    RMS_X, RMS_Y, RMS_Z,
    STD_X, STD_Y, STD_Z,
    MEAN_X, MEAN_Y, MEAN_Z
]

这就是 K-means 的输入。


七、完整 Python 代码(可直接运行)

1. 导入库

python

运行

复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler

2. 模拟九轴传感器振动采集(真实工程可替换为 I2C 读取)

模拟:正常振动 + 异常振动(松动 / 碰撞)

python

运行

复制代码
# ======================
# 模拟传感器采集:正常数据(大量)
# ======================
np.random.seed(42)
N_NORMAL = 500
normal_acc_X = np.random.normal(loc=0, scale=0.08, size=N_NORMAL)
normal_acc_Y = np.random.normal(loc=0, scale=0.07, size=N_NORMAL)
normal_acc_Z = np.random.normal(loc=1, scale=0.09, size=N_NORMAL)

# ======================
# 模拟异常数据(少量)
# ======================
N_ABNORMAL = 50
abn_acc_X = np.random.normal(loc=0, scale=0.8, size=N_ABNORMAL)
abn_acc_Y = np.random.normal(loc=0, scale=0.7, size=N_ABNORMAL)
abn_acc_Z = np.random.normal(loc=1, scale=0.9, size=N_ABNORMAL)

3. 滑动窗口 + 特征提取

python

运行

复制代码
def extract_features(acc_x, acc_y, acc_z, window_size=32):
    """ 振动特征提取 """
    features = []
    for i in range(0, len(acc_x) - window_size, window_size):
        x = acc_x[i:i+window_size]
        y = acc_y[i:i+window_size]
        z = acc_z[i:i+window_size]

        # 振动核心特征
        rms_x = np.sqrt(np.mean(x**2))
        rms_y = np.sqrt(np.mean(y**2))
        rms_z = np.sqrt(np.mean(z**2))

        std_x = np.std(x)
        std_y = np.std(y)
        std_z = np.std(z)

        mean_x = np.mean(x)
        mean_y = np.mean(y)
        mean_z = np.mean(z)

        feat = [rms_x, rms_y, rms_z,
                std_x, std_y, std_z,
                mean_x, mean_y, mean_z]
        features.append(feat)
    return np.array(features)

# 提取正常特征
normal_feats = extract_features(normal_acc_X, normal_acc_Y, normal_acc_Z)

# 提取异常特征
abnormal_feats = extract_features(abn_acc_X, abn_acc_Y, abn_acc_Z)

4. 训练 K-means(只使用正常数据!)

python

运行

复制代码
# 标准化(非常重要)
scaler = StandardScaler()
normal_feats_scaled = scaler.fit_transform(normal_feats)

# K-means 训练
K = 3  # 正常振动一般分 2~4 类足够
kmeans = KMeans(n_clusters=K, random_state=42)
kmeans.fit(normal_feats_scaled)

5. 异常检测核心:距离计算

python

运行

复制代码
def detect_anomaly(feature, scaler, kmeans, threshold=1.2):
    feat_scaled = scaler.transform(feature.reshape(1,-1))
    dists = kmeans.transform(feat_scaled)  # 到每个簇中心的距离
    min_dist = np.min(dists)
    return min_dist, min_dist > threshold

6. 测试效果

python

运行

复制代码
print("==== 测试正常样本 ====")
test_normal = normal_feats[0]
dist, is_abnormal = detect_anomaly(test_normal, scaler, kmeans)
print(f"距离:{dist:.2f}, 异常:{is_abnormal}")

print("\n==== 测试异常样本 ====")
test_abnormal = abnormal_feats[0]
dist, is_abnormal = detect_anomaly(test_abnormal, scaler, kmeans)
print(f"距离:{dist:.2f}, 异常:{is_abnormal}")

7. 可视化(直观看到聚类效果)

python

运行

复制代码
plt.figure(figsize=(10,5))
plt.scatter(normal_feats_scaled[:,0], normal_feats_scaled[:,1], label="Normal", alpha=0.5)
plt.scatter(kmeans.cluster_centers_[:,0], kmeans.cluster_centers_[:,1], c='red', s=200, label="Cluster Center")
plt.title("K-means 聚类正常振动特征")
plt.legend()
plt.show()

八、原理深度解释(看懂就是嵌入式 AI 入门)

1. 为什么要标准化?

振动各特征量纲不同(RMS、STD、MEAN),必须归一化,否则 K-means 会失效。

2. 为什么只训练正常数据?

异常样本太少、类型不可预测。K-means 只需要学习正常分布,偏离就是异常。

3. 阈值怎么定?

  • 训练完正常数据后,取最大距离 × 1.1~1.5
  • 工业常用:1.0~2.0

4. K 值怎么选?

  • 设备振动:K=2~4 足够
  • 用肘部法则(elbow method)简单判断

九、真实嵌入式工程(STM32 / ESP32)可直接移植

你在单片机上只需要实现:

  1. I2C 读取 LSM6DS3
  2. 滑动窗口(32~128 点)
  3. 特征计算(RMS、STD、MEAN)
  4. K-means 纯 C 语言版本
  5. 距离计算 + 阈值判断

这套方案100% 可在嵌入式运行,是工业预测性维护标准入门方案。


十、总结(这篇文章的核心)

  • 九轴传感器采集振动 → 加速度计最重要
  • 时序振动 → 特征向量(必须做)
  • K-means 只学习正常数据
  • 距离 > 阈值 = 异常
  • 轻量、无监督、可嵌入式落地、工业可用

这就是传感器 + K-means 异常检测的全部原理与代码

相关推荐
踏着七彩祥云的小丑1 小时前
嵌入式——认识电子元器件——电容系列
单片机·嵌入式硬件
NQBJT3 小时前
DMA —— 让 CPU “偷懒”的数据搬运工
stm32·单片机·dma·嵌入式
xiangw@GZ3 小时前
EMC原理:CS传导抗扰度测试总结
单片机·嵌入式硬件
三佛科技-134163842123 小时前
PL3325CS/CD/CH/CE 与PL3325BE 之间的对比与联系(应用功率与典型应用电路)
单片机·嵌入式硬件·物联网·智能家居·pcb工艺
blevoice4 小时前
杰理智能蓝牙音响开发板AC696N:文件系统操作API精讲
单片机·物联网·杰理蓝牙芯片·ac6966b蓝牙音响方案·杰理智能音箱开发·杰理ac6965e蓝牙音频开发
恶魔泡泡糖4 小时前
stm32F103C8T6标准库流水灯1——输出模式
stm32·单片机·嵌入式硬件
三佛科技-134163842125 小时前
FT838NB1-RT_5W(5V1A)原边反馈(5级能效)典型应用电路分析
单片机·嵌入式硬件·物联网·智能家居·pcb工艺
森利威尔电子-6 小时前
森利威尔SL3075 脚位完全兼容 TPS54560 65V降压恒压芯片5A电流能力
单片机·嵌入式硬件·集成电路·芯片·电源芯片
神一样的老师7 小时前
【兆易创新GD32VW553开发板试用】 BSP 从 GitHub 下载与编译指南
单片机·github·rt-thread
VBsemi-专注于MOSFET研发定制7 小时前
协作机器人螺丝锁付系统功率MOSFET选型方案——高效、精准与安全驱动系统设计指南
单片机·安全·机器人