2015-05-08 71 views
-3

有幾個星期我都無法解決的問題。R從成對的羣集

我有他們喜歡的用戶和電視劇的數據庫。有成千上萬的用戶(A,B,C,D ...)和成千上萬的電視劇(1,2,3,4 ...)。所以結果是數百萬對「用戶;喜歡的」數據庫。例如:

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中的方法如何比較:基於電視連續劇,他們喜歡

2)類似的電視連續劇的集羣相似用戶

1)集羣基於用戶喜歡

你有什麼想法如何解決它?

謝謝

+0

如果您訪問亞馬遜網站,您會看到推薦的書籍或其他內容。類似的事情可以做,並且k最近鄰算法可以是一個。 –

+0

目前還不清楚你爲我們提供了什麼,但我的直覺是數據很稀少。隨機森林可能會奏效,但我懷疑你的大部分集羣都是由更受歡迎的節目組成的(這對你的第一個請求來說可能是很好的)。對於第二個問題,例如購物籃分析,您不一定會劃分數據,但形成可能的關係,例如{辛普森和Futurama} - > {Family Guy}可能會有用。 –

+0

假設電視劇的數量比用戶數少數量級,您可以使用遵循貝葉斯規則的生成模型。基本上是P(cluster_i)= prod(P(cluster_i(show_j))),並且您最初隨機地將展示分配給不同數量的聚類。只要你有一個平滑的參數(例如,一個節目的集羣成員的最小概率),你可能會好起來的。這樣做有更好的方法,但這是最簡單的方法之一。 –

回答

1

如果您轉動您的數據轉化爲交易,你有市場購物籃分析的經典場景,流行的推薦系統:

UserA: M1 M11 M17 

有大量的算法和工具,這等作爲arules包裝。

+0

謝謝。我使用Apriori圖書館的Arules,結果非常好。 – Larssen

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) 
+0

感謝您提供這個有趣的解決方案。 – Larssen