如何在Python中用SVM实现时间序列电流信号的聚类归属判定
时间序列电流信号的聚类判定:SVM适配与替代方案
问题背景
拥有多段时间序列电流信号(每个CSV文件包含100个采样值,采样间隔0.02秒,持续2秒),已通过Soft-DTW K-Means完成聚类并为数据添加聚类标签,现需实现新输入电流信号的聚类归属判定,计划使用SVM但不清楚如何适配时间序列数据,寻求技术指导或替代方案。
用户已完成的数据导入、标准化及聚类代码如下:
数据处理代码
file_list= glob.glob(folder_path + "/*.csv") main_dataframe= pd.DataFrame(pd.read_csv(file_list[0], delimiter= ';')) main_dataframe['Current '].values.tolist() Data=list() for i in range (0,len(file_list)): data=pd.read_csv(file_list[i], delimiter= ';') Data.append(data['Current '].values.tolist()) Current=np.array(Data) X_train = TimeSeriesScalerMeanVariance().fit_transform(Current)
Soft-DTW K-Means聚类代码
# Soft-DTW-k-means print("Soft-DTW k-means") sdtw_km = TimeSeriesKMeans(n_clusters=3, metric="softdtw", metric_params={"gamma": .01}, verbose=True, random_state=seed) y_pred3 = sdtw_km.fit_predict(X_train)
一、SVM适配时间序列的实现思路
SVM无法直接处理序列型数据,需先将时间序列转换为固定维度的特征向量,再输入SVM训练分类模型,核心步骤如下:
1. 时间序列特征提取
常用特征提取方式:
- 统计特征:计算每个序列的均值、方差、最大值、最小值、峰值、峭度、偏度等统计量,组合为特征向量
- DTW距离特征:计算目标序列与各聚类中心的Soft-DTW距离,将距离值作为特征
- 频域特征:通过FFT将时域信号转换为频域,提取频谱峰值、能量分布等特征
2. SVM分类实现示例
结合现有代码,实现从特征提取到预测的完整流程:
import numpy as np from sklearn.svm import SVC from tslearn.metrics import soft_dtw from joblib import dump, load # 保存训练时的标准化器(避免新数据重新拟合导致偏差) scaler = TimeSeriesScalerMeanVariance() X_train = scaler.fit_transform(Current) dump(scaler, 'ts_scaler.joblib') # 定义特征提取函数 def extract_features(ts, cluster_centers): # 统计特征 stats_features = [ np.mean(ts), np.var(ts), np.max(ts), np.min(ts), np.ptp(ts), np.mean(np.abs(ts)), np.std(ts), np.kurtosis(ts), np.skew(ts) ] # 与聚类中心的Soft-DTW距离特征 dtw_features = [soft_dtw(ts, center, gamma=0.01) for center in cluster_centers] return np.hstack([stats_features, dtw_features]) # 获取聚类中心,提取训练数据特征 cluster_centers = sdtw_km.cluster_centers_ X_features = np.array([extract_features(ts, cluster_centers) for ts in X_train]) y_labels = y_pred3 # 训练SVM分类器 svm_clf = SVC(kernel='rbf', random_state=seed) svm_clf.fit(X_features, y_labels) # 新信号预测函数 def predict_cluster(new_ts_path): # 加载并标准化新信号 new_data = pd.read_csv(new_ts_path, delimiter=';') new_ts = new_data['Current '].values.reshape(1, -1) scaler = load('ts_scaler.joblib') new_ts_scaled = scaler.transform(new_ts)[0] # 提取特征并预测 new_features = extract_features(new_ts_scaled, cluster_centers) return svm_clf.predict([new_features])[0]
二、替代方案
1. 直接使用Soft-DTW K-Means的内置预测方法
tslearn中的TimeSeriesKMeans本身支持predict方法,无需额外训练SVM,直接计算新序列与各聚类中心的Soft-DTW距离,归属到距离最小的聚类:
from joblib import dump, load # 保存训练好的聚类模型 dump(sdtw_km, 'sdtw_kmeans_model.joblib') # 新信号预测函数 def predict_with_kmeans(new_ts_path): new_data = pd.read_csv(new_ts_path, delimiter=';') new_ts = new_data['Current '].values.reshape(1, -1) scaler = load('ts_scaler.joblib') new_ts_scaled = scaler.transform(new_ts) sdtw_km = load('sdtw_kmeans_model.joblib') return sdtw_km.predict(new_ts_scaled)[0]
2. 时间序列专用分类模型
若后续需更复杂的故障类型细分,可考虑:
- TSfresh:自动提取时间序列的海量特征,再结合SVM等分类器
- LSTM/CNN:深度学习模型,直接处理序列数据,适合识别复杂模式
- k-NN + DTW:以DTW为距离度量的k近邻分类,实现简单且适配时间序列特性
三、关键注意事项
- 新信号必须使用训练数据拟合的标准化器进行转换,禁止重新拟合,避免数据分布偏差
- 特征提取后可通过方差阈值、互信息等方法筛选冗余特征,提升SVM性能
- 若使用SVM,建议通过交叉验证调整
kernel、C等超参数,优化分类效果
内容的提问来源于stack exchange,提问作者Sara.A
相关产品推荐
相关产品推荐

