【问题标题】:R n most similar time series - dwt clustering / nearest neighbourR n 最相似的时间序列 - dwt 聚类/最近邻
【发布时间】:2021-01-22 10:43:50
【问题描述】:

所附数据是一个简化示例,因为实际上我有数百人和数百个时间点。

我正在寻找一种方法来确定相似的时间序列。

我这里有一些代码来确定集群,但这并不是我想要的。

我想要的是,如果我选择一个人,它将返回 n 个最相似的时间序列的名称。

即,如果 n = 1,并且我输入 Bob,它将返回 Dave,但是如果我输入 Sam,它将返回 Bob(这些名称将进入带有 df 的新列)。如果 n = 2,第一列将包含最相似的时间序列,第二列将包含下一个最相似的时间序列。这类似于 K 个最近邻居,但跨越时间序列,因此每个人都有一组不同的“邻居”。

如果这不可行或太难,我也希望指定每个组中的人数,而不是组数。

在这个例子中,我指定了 4 个组,这并不是 4 个 2 个组。

B 组有 4 人,而 C 和 D 组只有 1 人。

        hc@cluster
James            A
Dave             B
Bob              B
Joe              C
Robert           A
Michael          B
Sam              B
Steve            D

library(dtwclust)

df <- data.frame(
  row.names = c("James", "Dave", "Bob", "Joe", "Robert", "Michael", "Sam", "Steve"),
  Monday    = c(82, 46, 96, 57, 69, 28, 100, 10),
  Tuesday   = c(77, 62, 112, 66, 54, 34, 107, 20),
  Wednesday = c(77, 59, 109, 65, 50, 37, 114, 30),
  Thursday  = c(73, 92, 142, 77, 54, 30, 128, 40),
  Friday    = c(74, 49, 99, 90, 50, 25, 111, 50),
  Saturday  = c(68, 26, 76, 81, 42, 28, 63, 60),
  Sunday    = c(79, 37, 87, 73, 53, 33, 79, 70)
)

hc<- tsclust(df, type = "h", k = 4,
             preproc = zscore, seed = 899,
             distance = "sbd", centroid = shape_extraction,
             control = hierarchical_control(method = "average"))

plot(hc)

yo <- as.data.frame(hc@cluster)
yo$`hc@cluster` <- LETTERS[yo$`hc@cluster`]
print(yo)

【问题讨论】:

    标签: r cluster-analysis similarity nearest-neighbor dtw


    【解决方案1】:

    您要做的不是对数据进行聚类,而是要根据一个特定的时间序列对其进行排序,这就是问题所在。为了做你想做的事,首先,你必须选择一个“距离”的度量,例如可以是欧几里得或相关。在下一个示例中,我提供了一个包含距离测量(相关性和欧几里得)的代码。它简单地计算时间序列之间的距离,然后对其进行排序,最后选择 N 较低的。请注意,距离测量的选择会改变您的结果。

    df <- data.frame(
      Monday    = c(82, 46, 96, 57, 69, 28, 100, 10),
      Tuesday   = c(77, 62, 112, 66, 54, 34, 107, 20),
      Wednesday = c(77, 59, 109, 65, 50, 37, 114, 30),
      Thursday  = c(73, 92, 142, 77, 54, 30, 128, 40),
      Friday    = c(74, 49, 99, 90, 50, 25, 111, 50),
      Saturday  = c(68, 26, 76, 81, 42, 28, 63, 60),
      Sunday    = c(79, 37, 87, 73, 53, 33, 79, 70)
    )
    
    df <- as.data.frame(t(df))
    colnames(df) <- c("James", "Dave", "Bob", "Joe", "Robert", "Michael", "Sam", "Steve") 
      
    get_nearest_n <- function(data, name, n = 1){
      #' n must be positive and integer
      #' name must be a column name of data
      #' data must be a dataframe
      
      serie <- data[,name]
      data <- data[,-which(colnames(data) == name)]
      
      dist <- sqrt(colSums((data-serie)**2))
          
      sorted_names <- names(sort(dist)[1:n])
      return(data[,sorted_names])
    }
    
    get_nearest_n2 <- function(data, name, n = 1){
      #' n must be positive and integer
      #' name must be a column name of data
      #' data must be a dataframe
      
      serie <- data[,name]
      data <- data[,-which(colnames(data) == name)]
      
      dist <- as.data.frame(cor(serie,data))
      
      sorted_names <- names(sort(dist,decreasing = T)[1:n])
      return(data[,sorted_names])
    }
        
    get_nearest_n(data = df, name = 'Bob', n = 3)
    get_nearest_n2(data = df, name = 'Bob', n = 3)
    

    【讨论】:

    • 对于其中之一,Bob 不应该返回 Dave,因为它最相似?对于 get_nearest_n,Bob 返回 Sam、James 和 Joe。对于 get_nearest_n2,Bob 返回 Steve、Joe 和 James。不过这确实很有帮助,我不知道为什么我忘记了相关矩阵!
    • 函数 get_nearest_n2 排序错误,我现在编辑。
    猜你喜欢
    • 2019-01-03
    • 2016-10-14
    • 2021-12-26
    • 2019-10-01
    • 1970-01-01
    • 2020-02-09
    • 1970-01-01
    • 2023-04-07
    • 2013-06-06
    相关资源
    最近更新 更多