如何在 python 中使用 kNN 动态时间扭曲

2024-01-04

我有一个带有两个标签的时间序列数据集(0 and 1)。我在用动态时间扭曲 (DTW)作为使用 k 最近邻 (kNN) 进行分类的相似性度量,如这两篇精彩的博客文章中所述:

  • https://nbviewer.jupyter.org/github/markdregan/K-Nearest-Neighbors-with-Dynamic-Time-Warping/blob/master/K_Nearest_Neighbor_Dynamic_Time_Warping.ipynb https://nbviewer.jupyter.org/github/markdregan/K-Nearest-Neighbors-with-Dynamic-Time-Warping/blob/master/K_Nearest_Neighbor_Dynamic_Time_Warping.ipynb
  • http://alexminnaar.com/2014/04/16/Time-Series-Classification-and-Clustering-with-Python.html http://alexminnaar.com/2014/04/16/Time-Series-Classification-and-Clustering-with-Python.html

    Arguments
    ---------
    n_neighbors : int, optional (default = 5)
        Number of neighbors to use by default for KNN
    
    max_warping_window : int, optional (default = infinity)
        Maximum warping window allowed by the DTW dynamic
        programming function
    
    subsample_step : int, optional (default = 1)
        Step size for the timeseries array. By setting subsample_step = 2,
        the timeseries length will be reduced by 50% because every second
        item is skipped. Implemented by x[:, ::subsample_step]
    """
    
    def __init__(self, n_neighbors=5, max_warping_window=10000, subsample_step=1):
        self.n_neighbors = n_neighbors
        self.max_warping_window = max_warping_window
        self.subsample_step = subsample_step
    
    def fit(self, x, l):
        """Fit the model using x as training data and l as class labels
    
        Arguments
        ---------
        x : array of shape [n_samples, n_timepoints]
            Training data set for input into KNN classifer
    
        l : array of shape [n_samples]
            Training labels for input into KNN classifier
        """
    
        self.x = x
        self.l = l
    
    def _dtw_distance(self, ts_a, ts_b, d = lambda x,y: abs(x-y)):
        """Returns the DTW similarity distance between two 2-D
        timeseries numpy arrays.
    
        Arguments
        ---------
        ts_a, ts_b : array of shape [n_samples, n_timepoints]
            Two arrays containing n_samples of timeseries data
            whose DTW distance between each sample of A and B
            will be compared
    
        d : DistanceMetric object (default = abs(x-y))
            the distance measure used for A_i - B_j in the
            DTW dynamic programming function
    
        Returns
        -------
        DTW distance between A and B
        """
    
        # Create cost matrix via broadcasting with large int
        ts_a, ts_b = np.array(ts_a), np.array(ts_b)
        M, N = len(ts_a), len(ts_b)
        cost = sys.maxint * np.ones((M, N))
    
        # Initialize the first row and column
        cost[0, 0] = d(ts_a[0], ts_b[0])
        for i in xrange(1, M):
            cost[i, 0] = cost[i-1, 0] + d(ts_a[i], ts_b[0])
    
        for j in xrange(1, N):
            cost[0, j] = cost[0, j-1] + d(ts_a[0], ts_b[j])
    
        # Populate rest of cost matrix within window
        for i in xrange(1, M):
            for j in xrange(max(1, i - self.max_warping_window),
                            min(N, i + self.max_warping_window)):
                choices = cost[i - 1, j - 1], cost[i, j-1], cost[i-1, j]
                cost[i, j] = min(choices) + d(ts_a[i], ts_b[j])
    
        # Return DTW distance given window 
        return cost[-1, -1]
    
    def _dist_matrix(self, x, y):
        """Computes the M x N distance matrix between the training
        dataset and testing dataset (y) using the DTW distance measure
    
        Arguments
        ---------
        x : array of shape [n_samples, n_timepoints]
    
        y : array of shape [n_samples, n_timepoints]
    
        Returns
        -------
        Distance matrix between each item of x and y with
            shape [training_n_samples, testing_n_samples]
        """
    
        # Compute the distance matrix        
        dm_count = 0
    
        # Compute condensed distance matrix (upper triangle) of pairwise dtw distances
        # when x and y are the same array
        if(np.array_equal(x, y)):
            x_s = np.shape(x)
            dm = np.zeros((x_s[0] * (x_s[0] - 1)) // 2, dtype=np.double)
    
            p = ProgressBar(shape(dm)[0])
    
            for i in xrange(0, x_s[0] - 1):
                for j in xrange(i + 1, x_s[0]):
                    dm[dm_count] = self._dtw_distance(x[i, ::self.subsample_step],
                                                      y[j, ::self.subsample_step])
    
                    dm_count += 1
                    p.animate(dm_count)
    
            # Convert to squareform
            dm = squareform(dm)
            return dm
    
        # Compute full distance matrix of dtw distnces between x and y
        else:
            x_s = np.shape(x)
            y_s = np.shape(y)
            dm = np.zeros((x_s[0], y_s[0])) 
            dm_size = x_s[0]*y_s[0]
    
            p = ProgressBar(dm_size)
    
            for i in xrange(0, x_s[0]):
                for j in xrange(0, y_s[0]):
                    dm[i, j] = self._dtw_distance(x[i, ::self.subsample_step],
                                                  y[j, ::self.subsample_step])
                    # Update progress bar
                    dm_count += 1
                    p.animate(dm_count)
    
            return dm
    
    def predict(self, x):
        """Predict the class labels or probability estimates for 
        the provided data
    
        Arguments
        ---------
          x : array of shape [n_samples, n_timepoints]
              Array containing the testing data set to be classified
    
        Returns
        -------
          2 arrays representing:
              (1) the predicted class labels 
              (2) the knn label count probability
        """
    
        dm = self._dist_matrix(x, self.x)
    
        # Identify the k nearest neighbors
        knn_idx = dm.argsort()[:, :self.n_neighbors]
    
        # Identify k nearest labels
        knn_labels = self.l[knn_idx]
    
        # Model Label
        mode_data = mode(knn_labels, axis=1)
        mode_label = mode_data[0]
        mode_proba = mode_data[1]/self.n_neighbors
    
        return mode_label.ravel(), mode_proba.ravel()
    

然而,对于 kNN 分类,这两篇文章使用他们自己的 kNN 算法。

我想使用 sklearn 的选项,例如gridsearchcv在我的分类中。因此,我想知道如何将动态时间规整 (DTW) 与 sklearn kNN 结合使用。

注:我不限于sklearn也很高兴在其他图书馆收到答案

如果需要,我很乐意提供更多详细信息。


您可以对 KNN 使用自定义指标。 因此,您只需要自己实现 DTW(或使用/改编 python 中任何现有的 DTW 实现)[此代码的要点] https://gist.github.com/nikolasrieble/8bd3a83e14c0b2fa66bfa2ddd8828717.

import numpy as np
from scipy.spatial import distance
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import classification_report

#toy dataset 
X = np.random.random((100,10))
y = np.random.randint(0,2, (100))
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)

#custom metric
def DTW(a, b):   
    an = a.size
    bn = b.size
    pointwise_distance = distance.cdist(a.reshape(-1,1),b.reshape(-1,1))
    cumdist = np.matrix(np.ones((an+1,bn+1)) * np.inf)
    cumdist[0,0] = 0

    for ai in range(an):
        for bi in range(bn):
            minimum_cost = np.min([cumdist[ai, bi+1],
                                   cumdist[ai+1, bi],
                                   cumdist[ai, bi]])
            cumdist[ai+1, bi+1] = pointwise_distance[ai,bi] + minimum_cost

    return cumdist[an, bn]

#train
parameters = {'n_neighbors':[2, 4, 8]}
clf = GridSearchCV(KNeighborsClassifier(metric=DTW), parameters, cv=3, verbose=1)
clf.fit(X_train, y_train)



#evaluate
y_pred = clf.predict(X_test)
print(classification_report(y_test, y_pred))

哪个产量

Fitting 3 folds for each of 3 candidates, totalling 9 fits        

[Parallel(n_jobs=1)]: Done   9 out of   9 | elapsed:   29.0s finished

                         precision    recall  f1-score   support

                      0       0.57      0.89      0.70        18
                      1       0.60      0.20      0.30        15

            avg / total       0.58      0.58      0.52        33
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 python 中使用 kNN 动态时间扭曲 的相关文章

  • PyList_SetItem 与 PyList_SETITEM

    据我所知 PyList SetItem 和 PyList SETITEM 之间的区别在于 PyList SetItem 会降低它覆盖的列表项的引用计数 而 PyList SETITEM 不会 我有什么理由不应该一直使用 PyList Set
  • 具有多处理功能的 Python 代码无法在 Windows 上运行

    以下简单的绝对初学者代码在 Ubuntu 14 04 Python 2 7 6 和 Cygwin Python 2 7 8 上运行 100 但在 Windows 64 位 Python 2 7 8 上挂起 我使用另一个片段观察到了同样的情况
  • Python Nose 导入错误

    我似乎无法理解鼻子测试框架 https nose readthedocs org en latest 识别文件结构中测试脚本下方的模块 我已经设置了演示该问题的最简单的示例 下面我会解释一下 这是包文件结构 init py foo py t
  • Python 遍历目录树的方法是什么?

    我觉得分配文件和文件夹并执行 item 部分有点黑客 有什么建议么 我正在使用Python 3 2 from os import from os path import def dir contents path contents list
  • 将 API 数据存储到 DataFrame 中

    我正在运行 Python 脚本来从 Interactive Brokers API 收集金融市场数据 连接到API后 终端打印出请求的历史数据 如何将数据保存到数据帧中而不是在终端中流式传输 from ibapi wrapper impor
  • 为什么导入 pdb 时出现此错误? “模块”对象没有属性“ascii_letters”

    尝试调试我的代码 我正在导入库pdb import sys from subprocess import check call import pdb functions if name main Code 我收到此错误 File reg p
  • conda 无法从 yml 创建环境

    我尝试运行下面的代码来从 YAML 文件创建虚拟 Python 环境 我在 Ubuntu 服务器上的命令行中运行代码 虚拟环境名为 py36 当我运行下面的代码时 我收到下面的消息 环境也没有被创建 这个问题是因为我有几个必须使用 pip
  • 如何在 ReportLab 段落中插入回车符?

    有没有办法在 ReportLab 的段落中插入回车符 我试图将 n 连接到我的段落字符串 但这不起作用 Title Paragraph Title n Page myStyle 我想要这样做 因为我将名称放入单元格中 并且想要控制单元格中的
  • 如何找到列表S的所有分区为k个子集(可以为空)?

    我有一个唯一元素列表 比方说 1 2 我想将其拆分为 k 2 个子列表 现在我想要所有可能的子列表 1 2 1 2 2 1 1 2 我想分成 1 1 2 我怎样才能用 Python 3 做到这一点 更新 我的目标是获取 N 个唯一数字列表的
  • Python 正则表达式部分匹配或“hitEnd”

    我正在编写一个扫描器 因此我将任意字符串与正则表达式规则列表进行匹配 如果我可以模拟 Java hitEnd 功能 不仅知道正则表达式何时不匹配 还知道何时匹配 这将非常有用 can t匹配 当正则表达式匹配器在决定拒绝输入之前到达输入末尾
  • 在Python中创建一个新表

    我正在尝试从数控机床中提取数据 事件每毫秒发生一次 我需要过滤掉一些用管道 分隔的变量分隔符 PuTTy exe 程序生成的日志文件 我尝试阅读熊猫 但列不在同一位置 df pd read table data log sep 日志文件的一
  • 如何对这个 Flask 应用程序进行单元测试?

    我有一个 Flask 应用程序 它使用 Flask Restless 来提供 API 我刚刚写了一些身份验证来检查 如果消费者主机被识别 该请求包含一个哈希值 通过加密 POST 的请求内容和 GET 的 URL 以及秘密 API 密钥来计
  • 在 matplotlib 中使用 yscale('log') 时缺少误差线

    在某些情况下 当使用对数刻度时 matplotlib 会错误地显示带有误差条的图 假设这些数据 例如在 pylab 内 s 19 0 20 0 21 0 22 0 24 0 v 36 5 66 814250000000001 130 177
  • Python正则表达式从字符串中获取浮点数

    我正在使用正则表达式来解析字符串中的浮点数 re findall a zA Z d d t 是我使用的代码 这段代码有问题 如果数字和任何字符之间没有空格 则不会解析该数字 例如 0 1 2 3 4 5 6 7 8 9 的预期输出为 0 1
  • 一起使用 Flask 和 Tornado?

    我是以下的忠实粉丝Flask 部分是因为它很简单 部分是因为它有很多扩展 http flask pocoo org extensions 然而 Flask 是为了在 WSGI 环境中使用而设计的 而 WSGI 不是非阻塞的 所以 我相信 它
  • 如何检查列表是否为空?

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 例如 如果通过以下内容 a 我如何检查是否a是空的 if not a print Lis
  • 如何强制 Y 轴仅使用整数

    我正在使用 matplotlib pyplot 模块绘制直方图 我想知道如何强制 y 轴标签仅显示整数 例如 0 1 2 3 等 而不显示小数 例如 0 0 5 1 1 5 2 等 我正在查看指导说明并怀疑答案就在附近matplotlib
  • Jupyter Notebook:没有名为 pandas 的模块

    我搜索了其他问题 但没有找到任何有帮助的内容 大多数只是建议您使用 conda 或 pip 安装 pandas 在我的 jupyter 笔记本中 我试图导入 pandas import pandas as pd 但我收到以下错误 Modul
  • 为什么 bot.get_channel() 会产生 NoneType?

    我正在制作一个 Discord 机器人来处理公告命令 当使用该命令时 我希望机器人在特定通道中发送一条消息 并向用户发送一条消息以表明该命令已发送 但是 我无法将消息发送到频道 我尝试了这段代码 import discord import
  • 在Python中从日期时间中减去秒

    我有一个 int 变量 它实际上是秒 让我们调用这个秒数X 我需要得到当前日期和时间 以日期时间格式 减去的结果X秒 Example If X是 65 当前日期是2014 06 03 15 45 00 那么我需要得到结果2014 06 03

随机推荐