【发布时间】:2017-11-15 08:29:14
【问题描述】:
我正在寻找一种方法来加速这个算法。
我的情况如下。我有一个包含 6 个习惯的 25,000 个用户的数据集。我的目标是为 25,000 个用户开发一个层次聚类。我在具有 16 核、128GB RAM 的服务器上运行它。 我花了 3 周时间才让 10,000 名用户在我的服务器上不间断地使用 6 核来计算这个距离矩阵。正如你可以想象的那样,这对我的研究来说太长了。
我为这 6 个习惯中的每一个创建了概率质量分布 (PMF)。每个习惯的 PMF 大小(列)可能不同。有些习惯有 10 列,大约 256 列,全部取决于具有最不道德行为的用户。
我算法的第一步是建立一个距离矩阵。我使用 Hellinger 距离来计算距离,这与某些使用例如的包相反。凯瑟琳/曼哈顿。我确实需要 Hellinger 距离,请参阅 https://en.wikipedia.org/wiki/Hellinger_distance
我目前尝试的是通过应用一个多核进程来加速算法,每个进程在一个单独的核心上有 6 个习惯。有两件事可能有助于加快速度
(1) C 实现 - 但我不知道如何执行此操作(我不是 C 程序员)如果有帮助,您能帮我解决这个 C 实现吗?
(2) 通过自己加入表格来制作笛卡尔积,并让所有行及其后进行逐行计算。关键是R在默认情况下会给出错误,例如数据表。对此有什么建议吗?
还有其他想法吗?
最好的问候尤尔詹
# example for 1 habit with 100 users and a PMF of 5 columns
Habit1<-data.frame(col1=abs(rnorm(100)),
col2=abs(c(rnorm(20),runif(50),rep(0.4,20),sample(seq(0.01,0.99,by=0.01),10))),
col3=abs(c(rnorm(30),runif(30),rep(0.4,10),sample(seq(0.01,0.99,by=0.01),30))),
col4=abs(c(rnorm(10),runif(10),rep(0.4,20),sample(seq(0.01,0.99,by=0.01),60))),
col5=abs(c(rnorm(50),runif(10),rep(0.4,10),sample(seq(0.01,0.99,by=0.01),30))))
# give all users a username same as rowname
rownames(Habit1)<- c(1:100)
# actual calculation
Result<-calculatedistances(Habit1)
HellingerDistance <-function(x){
#takes two equal sized vectors and calculates the hellinger distance between the vectors
# hellinger distance function
return(sqrt(sum(((sqrt(x[1,]) - sqrt(x[2,]))^2)))/sqrt(2))
}
calculatedistances <- function(x){
# takes a dataframe of user IID in the first column and a set of N values per user thereafter
# first set all NA to 0
x[is.na(x)] <- 0
#create matrix of 2 subsets based on rownumber
# 1 first the diagronal with
D<-cbind(matrix(rep(1:nrow(x),each=2),nrow=2),combn(1:nrow(x), 2))
# create a dataframe with hellinger distances
B <<-data.frame(first=rownames(x)[D[1,]],
second=rownames(x)[D[2,]],
distance=apply(D, 2, function(y) HellingerDistance(x[ y,]))
)
# reshape dataframe into a matrix with users on x and y axis
B<<-reshape(B, direction="wide", idvar="second", timevar="first")
# convert wide table to distance table object
d <<- as.dist(B[,-1], diag = FALSE)
attr(d, "Labels") <- B[, 1]
return(d)
}
【问题讨论】:
-
我建议 (1) 将矩阵更改为
long格式,(2) 使用data.table在成对观察值之间进行计算,(3) 将结果转换回wide上的矩阵必要时格式化。 Here is the most efficient way I've found so far to calculate distances between data points using this approach -
感谢您的回答,我不完全理解您的解决方案,也不是链接中的示例。该链接显示了空间距离而不是 Hellinger 距离的解决方案。 1.数据的长格式是Habit中的,是你的意思吗? 2. 如何最好地实现
data.table来计算成对的观察值?谢谢你的回答 -
R 中有一个
hellinger函数。你考虑过使用它吗? -
我考虑过这个函数,但普通的
Hellinger采用分布函数而不是离散分布本身。因此我不得不编写自己的函数。不过谢谢你的建议。
标签: r algorithm performance matrix distance