基于六维力传感器数据的拳法分类系统,使用支持向量机(SVM)对9种不同拳法进行自动识别和分类。
- 高精度分类:测试集准确率达到84.21%
- 多类别支持:支持9种拳法的识别
- 特征工程优化:提取122维特征并降维至40维
- 数据不平衡处理:使用class_weight平衡样本权重
- 传感器设置:六维力传感器放置于立式沙袋下方
- 数据采集:采样率50Hz,记录每次打击的完整力学响应
- 数据格式:JSON格式,包含sensor_data和punch_info两部分
系统支持以下9种拳法分类:
- 刺拳
- 右手摆拳
- 右手直拳
- 右手勾拳击体
- 右手勾拳击头
- 左手摆拳
- 左手直拳
- 左手勾拳击体
- 左手勾拳击头
{
"编号": 292,
"时间": 7.738439321517944,
"Fx": -32.08159456759245,
"Fy": -20.730219690487207,
"Fz": -40.28523895934745,
"Mx": -44.52140103653073,
"My": 72.51020076870918,
"Mz": 0.0,
"raw_data": [...]
}
{
"punch_type": "刺拳",
"peak_force": 79.22955278600695,
"avg_force": 59.94796724876606,
"duration_ms": 157.4251651763916,
"confidence": 0.5659253770429068,
"impulse": 9.83270228526255,
"impact_position": [-0.33, 0.009, 5.18],
"impact_direction": [0.74, 0.65, -0.13],
"position_confidence": 0.5864065236199365
}
对六维力数据(Fx, Fy, Fz, Mx, My, Mz)各计算9个统计量:
- 基础统计:均值、标准差、最大值、最小值、中位数
- 分位数特征:25%分位数、75%分位数
- 分布特征:偏度(skewness)、峰度(kurtosis)
# 示例:Fx维度的统计特征
fx_features = [
np.mean(fx_data), # 均值
np.std(fx_data), # 标准差
np.max(fx_data), # 最大值
np.min(fx_data), # 最小值
np.median(fx_data), # 中位数
np.percentile(fx_data, 25), # 25%分位数
np.percentile(fx_data, 75), # 75%分位数
stats.skew(fx_data), # 偏度
stats.kurtosis(fx_data) # 峰度
]
捕获拳法的动态演化模式,每维计算7个时序特征:
- 峰值时间比例:峰值出现的时间位置
- 上升比例:从开始到峰值的时间占比
- 下降比例:从峰值到结束的时间占比
- 变异系数:标准差与均值的比值
- 波动率:相邻点差值的标准差
- 上升斜率:峰值前的平均变化率
- 下降斜率:峰值后的平均变化率
分析六维力之间的相互关系:
- 轴间相关:Fx-Mx, Fy-My, Fz-Mz相关系数
- 合力相关:总合力与总合力矩的相关性
- 力的相关:Fx-Fy, Fx-Fz相关系数
从物理角度提取的综合特征:
- 合力统计:平均合力、最大合力、合力标准差
- 合力矩统计:平均合力矩、最大合力矩、合力矩标准差
- 序列长度:打击持续时间的采样点数
- 力矩比:平均合力与平均合力矩的比值
来自punch_info的预处理特征:
- 力学参数:峰值力、平均力、持续时间、置信度、冲量
- 空间特征:撞击位置(x,y,z)、撞击方向(x,y,z)
- 置信度:位置置信度
def prepare_data(raw_data, labels):
# 1. 特征提取
features = extract_all_features(raw_data) # 122维原始特征
# 2. 数据清洗
features = remove_invalid_features(features)
# 3. 特征标准化
features_scaled = StandardScaler().fit_transform(features)
# 4. 特征选择
features_selected = SelectKBest(k=40).fit_transform(features_scaled)
# 5. 标签编码
labels_encoded = LabelEncoder().fit_transform(labels)
return features_selected, labels_encoded
def train_model(X, y):
# 1. 数据划分
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, stratify=y, random_state=42
)
# 2. 超参数网格搜索
param_grid = [
{'C': [1, 10, 100], 'kernel': ['rbf'], 'class_weight': ['balanced']},
{'C': [1, 10, 100], 'kernel': ['linear'], 'class_weight': ['balanced']}
]
# 3. 交叉验证训练
svm_model = GridSearchCV(SVC(), param_grid, cv=3, scoring='accuracy')
svm_model.fit(X_train, y_train)
# 4. 模型评估
y_pred = svm_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
return svm_model, accuracy
- 测试集准确率:84.21%
- 交叉验证得分:79.44%
- 训练样本数:93个拳击事件
- 特征维度:122维 → 40维(特征选择后)
拳法类别 | 精确率 | 召回率 | F1分数 | 样本数 |
---|---|---|---|---|
刺拳 | 100% | 100% | 100% | 2 |
右手勾拳击体 | 100% | 100% | 100% | 2 |
右手摆拳 | 100% | 100% | 100% | 2 |
右手直拳 | 100% | 100% | 100% | 2 |
左手摆拳 | 100% | 100% | 100% | 2 |
左手勾拳击头 | 67% | 100% | 80% | 2 |
左手直拳 | 60% | 100% | 75% | 3 |
右手勾拳击头 | 100% | 50% | 67% | 2 |
左手勾拳击体 | 0% | 0% | 0% | 2 |
- 数据不平衡处理:使用class_weight='balanced'显著提升小样本类别性能
- 特征工程优化:从85维基础特征提升至122维增强特征
- 特征选择:通过SelectKBest选择最优40维特征,避免过拟合
- 核函数选择:RBF核在该数据集上表现最佳
pip install numpy scikit-learn matplotlib scipy
from punch_svm_classifier_lite import LitePunchSVMClassifier, PunchDataLoader
# 1. 加载数据
loader = PunchDataLoader("Data")
raw_data, labels = loader.load_all_data()
# 2. 训练模型
classifier = LitePunchSVMClassifier()
X, y = classifier.prepare_data(raw_data, labels)
results = classifier.train(X, y)
# 3. 模型预测
# new_sample = extract_features(new_punch_data)
# prediction = classifier.svm_model.predict(new_sample)
punchClassify/
├── Data/ # 训练数据目录
│ ├── 刺拳 10/
│ ├── 右手摆拳 10拳/
│ └── ...
├── punch_svm_classifier.py # 基础版本分类器
├── punch_svm_classifier_lite.py # 轻量级优化版本(推荐)
├── trainSVM.py # 原始演示代码
└── README.md # 本文档
支持向量机通过寻找最优超平面来实现分类:
- 线性可分:直接寻找分离超平面
- 非线性:通过核函数映射到高维空间
- 多分类:使用one-vs-rest策略
本系统最佳核函数为RBF(径向基函数):
K(xi, xj) = exp(-γ||xi - xj||²)
- 优点:能处理非线性关系,适合高维特征
- 参数:C=1, γ=scale(自适应调整)
使用方差分析F检验选择特征:
F = Var_between_groups / Var_within_groups
选择F值最大的40个特征,平衡信息保留与维度降低。
- 样本数量:总样本93个,平均每类约10个样本
- 类别不平衡:某些类别识别困难(如左手勾拳击体)
- 传感器位置:固定在沙袋下方,限制了撞击角度的多样性
-
数据增强:
- 增加训练样本数量
- 使用数据合成技术生成虚拟样本
- 添加不同力度、速度的变化样本
-
算法优化:
- 尝试集成学习方法(Random Forest、XGBoost)
- 探索深度学习方法(LSTM、CNN)
- 使用半监督学习利用无标签数据
-
特征工程:
- 增加频域分析(FFT特征)
- 小波变换提取多尺度特征
- 基于物理模型的特征设计
-
系统扩展:
- 实时分类系统开发
- 支持更多拳法类别
- 个性化适应不同用户的打击风格
- Cortes, C., & Vapnik, V. (1995). Support-vector networks. Machine learning.
- Chang, C. C., & Lin, C. J. (2011). LIBSVM: a library for support vector machines.
- Pedregosa, F., et al. (2011). Scikit-learn: Machine learning in Python.
- v1.0(基础版):基础特征提取,准确率68.42%
- v2.0(轻量级优化版):增强特征工程,准确率84.21%
如有问题或建议,请通过以下方式联系:
- 项目仓库:[GitHub链接]
- 技术支持:[邮箱地址]
最后更新:2025年9月24日