You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用tslearn实现DTW分类遇错及多维分类等技术问询

使用tslearn实现DTW分类时的问题

我在用tslearn库做Dynamic Time Warping(DTW)分类时,训练阶段报错ValueError: setting an array element with a sequence.。我的数据是多组长度可变、维度多样的时间序列,先导入成DataFrame列表用于可视化,筛选列转成numpy数组,划分训练测试集后用DTW作为距离度量训练模型,试过展平数组、重塑为(-1,1)、修改dtype为float都没用。

代码片段:

from tslearn.neighbors import KNeighborsTimeSeriesClassifier
from tslearn.metrics import dtw
import pandas as pd
import numpy as np          
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split

# timeseries()返回多个不同长度的DataFrame
print(timeseries())
# 输出示例:两个不同行数的DataFrame,各包含10列

ts = timeseries()
# 只保留TC列
[i.drop(columns=['time','IRtime','value','value.1','value.2','value.3','IR','TS','p'],inplace = True) for i in ts]
X = []
for i in ts:
    i = i.values
    X.append(i.flatten())
y = labels()['target'].values 
X = np.array(X)
y = np.array(y)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 初始化模型并训练
knn = KNeighborsTimeSeriesClassifier(n_neighbors=2,metric =dtw)
knn.fit(X_train, y_train)

# 报错:
# TypeError: only size-1 arrays can be converted to Python scalars
# ValueError: setting an array element with a sequence.

问题

Q1. 如何修复该错误?
Q2. 有没有其他可计算距离矩阵并完成分类的库?(试过dtai库计算距离矩阵,但不知如何用于分类,且遇到同样的错误)
Q3. 我想基于IR、TC、TS多特征实现多维DTW分类,有哪些可行方法?


解答

Q1:修复错误的方法

核心问题是tslearn的KNeighborsTimeSeriesClassifier要求输入格式为三维结构:每个样本是(时间步长, 特征数)的二维数组,整体以列表形式传入(支持变长序列),而你当前的X_train是一维数组的集合,不符合要求。

修复步骤:

  1. 保留时间序列的二维结构,不要展平:
    ts = timeseries()
    # 处理数据时保留二维结构,不要用inplace修改原列表
    ts_processed = [i.drop(columns=['time','IRtime','value','value.1','value.2','value.3','IR','TS','p']) for i in ts]
    # 转成(时间步长, 1)的二维数组,组成列表
    X = [df.values.reshape(-1, 1) for df in ts_processed]
    y = labels()['target'].values 
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
    
  2. 使用tslearn内置的DTW度量标识:
    不需要直接传入dtw函数,用字符串'dtw'即可,避免函数调用格式不匹配:
    knn = KNeighborsTimeSeriesClassifier(n_neighbors=2, metric='dtw')
    knn.fit(X_train, y_train)
    

tslearn原生支持变长时间序列,只要每个样本是符合维度要求的二维数组,列表形式传入即可。

Q2:其他可用于DTW分类的库

  • scikit-learn + 预计算距离矩阵:
    用sklearn的KNeighborsClassifier结合预计算的DTW距离矩阵,适合自定义距离逻辑:
    from sklearn.neighbors import KNeighborsClassifier
    from tslearn.metrics import dtw
    
    # 预计算训练集的距离矩阵
    def build_dtw_matrix(X):
        n_samples = len(X)
        dist_matrix = np.zeros((n_samples, n_samples))
        for i in range(n_samples):
            for j in range(i+1, n_samples):
                dist = dtw(X[i], X[j])
                dist_matrix[i,j] = dist
                dist_matrix[j,i] = dist
        return dist_matrix
    
    # 训练阶段
    train_dist = build_dtw_matrix(X_train)
    knn = KNeighborsClassifier(n_neighbors=2, metric='precomputed')
    knn.fit(train_dist, y_train)
    
    # 测试阶段:计算测试样本到训练样本的距离
    test_dist = np.array([[dtw(x_test, x_train) for x_train in X_train] for x_test in X_test])
    y_pred = knn.predict(test_dist)
    
  • fastdtw:比原生DTW更快的实现,适合大数据量,用法和上述逻辑一致,替换dtw函数为fastdtw即可。
  • pyDTW:轻量级DTW库,专注于距离计算,同样可配合sklearn分类器使用。

Q3:多维DTW分类的可行方法

多维DTW用于处理多特征时间序列,有以下几种实用方案:

  1. tslearn原生多维支持:
    tslearn的DTW和分类器原生支持多维时间序列,只要每个样本是(时间步长, 特征数)的二维数组即可。比如保留IR、TC、TS三列:
    ts_processed = [i[['IR', 'TC', 'TS']] for i in ts]
    X = [df.values for df in ts_processed]  # 每个样本是(时间步长, 3)的二维数组
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
    knn = KNeighborsTimeSeriesClassifier(n_neighbors=2, metric='dtw')
    knn.fit(X_train, y_train)
    
    tslearn会自动对每个特征维度计算DTW距离后求和,也可通过metric_params设置权重。
  2. 加权多维DTW:
    如果不同特征重要性不同,可自定义加权距离函数:
    def weighted_mdtw(x, y, weights=[0.3, 0.5, 0.2]):
        # x、y为(时间步长, 3)的数组
        total_dist = 0
        for idx in range(3):
            total_dist += weights[idx] * dtw(x[:, idx].reshape(-1,1), y[:, idx].reshape(-1,1))
        return total_dist
    
    knn = KNeighborsTimeSeriesClassifier(n_neighbors=2, metric=weighted_mdtw)
    knn.fit(X_train, y_train)
    
  3. 特征对齐后做DTW:
    先对多特征时间序列做时序对齐(比如用插值统一长度),再用多维DTW,但会丢失原始时序的变长特性,仅适合对长度一致性有要求的场景。

内容的提问来源于stack exchange,提问作者memonj12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 08:30:47