R成对聚类

时间:2015-05-08 22:37:36

标签: r cluster-analysis

有一个问题我几周都无法解决。

我有他们喜欢的用户和电视剧的数据库。有成千上万的用户(A,B,C,D ...)和成千上万的电视剧(1,2,3,4 ......)。因此结果是数百万对“user; likesseries”数据库。例如:

A;10 #user A liked series 10
A;23
A;233
A;500
B;5
B;10
B;343
C;10
C;233
C;340
...

我在R中寻找一种方法如何比较:

1)基于他们喜欢的电视剧的类似用户群集

2)基于用户喜欢的类似电视剧集群

你知道如何解决它吗?

谢谢

2 个答案:

答案 0 :(得分:1)

如果您将数据转换为交易,那么您就拥有了一个经典的市场购物篮分析方案,这对于推荐系统很受欢迎:

UserA: M1 M11 M17

有很多算法和工具,例如arules包。

答案 1 :(得分:1)

以下是您可以使用的生成算法的示例。如果样本量非常大,您可能希望使用data.table包和/或外部数据库对其进行优化。编写的代码对于初学者来说相对容易阅读。

下面有12,000个用户和90个节目,以及5种不同类型的节目/用户。每个用户都有7倍的机会喜欢他们的类别中的节目,而不是他们类别之外的节目。生成的数据框显示用户的估计集群,用户集群成员资格的概率以及特定节目与集群关联的概率(您需要对值进行规范化,因为列中的概率加起来为1)。 This是此处使用的算法。

library(plyr)

#creates "true" values
trueclass = sample(5,12000,replace=TRUE)
sid.sample <-function(x){ sapply(x,function(x) sample(1:90,1,prob = rep(1,90)*1+((0:89)%%5 == (x-1))*6))}
df = data.frame(user = rep(1:12000,each = 4),sid = sid.sample(rep(trueclass,each=4)))

#create empty frames
k = 5
uids = unique(as.numeric(df$user))
sids = unique(df$sid)

#initialize probabilities
uclass = uprobs = rdply(function() {x=rep(0,k);x[sample(k,1)] = 1;return(x)},
                        .n = length(uids))[,-1]
sprobs = matrix(0,nrow = length(sids),ncol = k)
scounts = sprobs*0

row.to.max <- function(x) rep(1,length(x)) * (1:length(x) == which.max(x))

#priors for each group; initially make them unbiased
priors = rep(0.2,5)

#slow method that still works
#20 iterations
for (counter in 1:40){
  print(counter)
  #smoothing
  scounts[,] = 1
  #calculate show probabilities
  for (i in 1:nrow(df)){
    scounts[df[i,2],which.max(uclass[df[i,1],])]=scounts[df[i,2],which.max(uclass[df[i,1],])]+1
  }
  sprobs = apply(scounts,2,function(x) x/sum(x))
  #to calculate user probabilities
  uprobs[,] = 0
  for (i in 1:nrow(df)){
    uprobs[df[i,1],] = uprobs[df[i,1],] + log(sprobs[df[i,2],])
  }
  #convert from log to actual, and add prior
  uprobs = t(apply(uprobs,1,function(x,priors,temperature){ x = x + log(priors);x=x-max(x);x=exp(x);x/sum(x)},priors = priors))
  uclass = t(apply(uprobs,1,row.to.max))
  priors = colSums(uclass)
  #small bit of smoothing
  priors = (priors+0.01)/sum(priors+0.01)
  print(priors)
}

final.classes = apply(uclass,1,which.max)
table(trueclass,final.classes)