R n 最相似的时间序列 - dwt 聚类/最近邻
R n most similar time series - dwt clustering / nearest neighbour
所附数据是一个简化的例子,因为在现实中我有数百人和数百个时间点。
我正在寻找一种方法来确定相似的时间序列。
我这里有一些代码来确定集群,但这并不是我想要的。
我想要的是,如果我选择一个人,它将return n 个最相似的时间序列的名字。
即,如果 n = 1,我输入 Bob,它将 return Dave,但是如果我输入 Sam,它将 return 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)
你想做的不是对数据进行聚类,你想根据一个特定的time-series对其进行排序,这就是问题所在。要做你想做的事,首先,你必须 select 一个“距离”的度量,例如可以是欧几里德或相关。在下一个示例中,我提供了一个包含两种距离测量(相关和欧几里德)的代码。就是简单的计算出time-series之间的距离,然后排序,最后取下的N。请注意,select距离测量的离子会改变您的结果。
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)
所附数据是一个简化的例子,因为在现实中我有数百人和数百个时间点。
我正在寻找一种方法来确定相似的时间序列。
我这里有一些代码来确定集群,但这并不是我想要的。
我想要的是,如果我选择一个人,它将return n 个最相似的时间序列的名字。
即,如果 n = 1,我输入 Bob,它将 return Dave,但是如果我输入 Sam,它将 return 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)
你想做的不是对数据进行聚类,你想根据一个特定的time-series对其进行排序,这就是问题所在。要做你想做的事,首先,你必须 select 一个“距离”的度量,例如可以是欧几里德或相关。在下一个示例中,我提供了一个包含两种距离测量(相关和欧几里德)的代码。就是简单的计算出time-series之间的距离,然后排序,最后取下的N。请注意,select距离测量的离子会改变您的结果。
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)