2016-07-04 7 views
1

45000ユーザーと40個の奇妙な映画の評価があります。ピアソンと他のユーザーとの相関関係に基づいて、各ユーザーの新しい評価を予測する必要があります。私はまた、類似したユーザーのセットとその類似点を各ユーザームービーの組み合わせごとに保存する必要があります。ループを並行して実行するためにforeachパッケージを使用しています。私が書くために管理しているコードは、このです:Foreach並列 - 複数出力の結合機能

library(foreach) 

x <- matrix(rnorm(1:1000), nrow = 100 , ncol =10) 
df = list() 

# correlation matrix 
cor_mat <- cor(t(x)) 
cor_mat = abs(cor_mat) 
# similarity limits 
upper = 1 
lower = 0.04 


# Initiating parallel environment 
cl = makeCluster(3) 
registerDoParallel(cl) 

res <- foreach(i = 1:nrow(x) , .combine = rbind,.packages=  c('base','foreach')) %dopar%{ 
     foreach(j = 1:ncol(x) , .combine = c, .packages = c('base','foreach')) %do%{ 

sim_user = which(cor_mat[i,] >= lower & cor_mat[i,] < upper) 

bx = as.numeric(t(x[sim_user,j]) %*% 
    cor_mat[sim_user,j]/sum(cor_mat[sim_user,j])) 
df[[length(df)+1]] = data.frame(i,j,sim_user,cor_mat[sim_user,j]) 

return(bx) 

    } 
} 
stopCluster(cl) 

私はすなわち「RES」foreachの出力から予測評価のマトリックスを作成し、私の仕事の半分を達成することができますよ。しかし、似たようなユーザーのリストを追加している私のリストdfは、foreachループの最後では空です。

予測された評価のマトリックスと同様のユーザーのリストの両方を出力するために、どのようなカスタム結合機能を書くことができますか?

答えて

2

複数の出力関数の場合、リスト内のすべてを返すほうがよいでしょう。その場合、データを結合する独自の関数を指定する必要があることを意味します。ここでは、毎回2つの要素、すなわちbxとdfを返します。したがって、私の結合関数は、これら2つの要素のそれぞれを別々に結合し、長さ2のリストに返します。

combine_custom_j <- function(LL1, LL2) { 

    bx <- c(LL1$bx, LL2$bx) 
    dfs <- c(LL1$df, LL2$df) 
    return(list(bx = bx, df = dfs)) 
} 

combine_custom_i <- function(LL1, LL2) { 

    bx <- rbind(LL1$bx, LL2$bx) 
    dfs <- c(LL1$df, LL2$df) 
    return(list(bx = bx, df = dfs)) 

} 

res <- foreach(i = 1:nrow(x) , .combine = combine_custom_i,.packages= c('base','foreach')) %dopar%{ 
    foreach(j = 1:ncol(x) , .combine = combine_custom_j, .packages = c('base','foreach')) %do%{ 

    sim_user = which(cor_mat[i,] >= lower & cor_mat[i,] < upper) 

    bx = as.numeric(t(x[sim_user,j]) %*% 
         cor_mat[sim_user,j]/sum(cor_mat[sim_user,j])) 

    return(list(bx = bx, df = data.frame(i,j,sim_user,cor_mat[sim_user,j]))) 

    } 
} 

あなたのコードは、提案のように、私はリストにあなたのデータフレームを返されたが、私はあなたがそれらをrbindする場合があります信じますか?その場合は、両方の結合機能でc(LL1$df, LL2$df)rbind(LL1$df, LL2$df)に置き換えるだけです。

+0

Zheyuanを編集していただきありがとうございます。私はインラインコードを追加する方法がわかりませんでした(今は私の以前のすべての回答を編集しています) – Choubi

+0

それはそれです!ありがとう@ Choubi! – RUser

+0

@ Choubi ..コードは正常に動作しますが、通常のforループよりも遅く動作します。 combine_custom_i関数とcombine_custom_j関数の複数のrbind呼び出しが原因ですか? – RUser

関連する問題