2009-06-20 9 views
7

मैं Weighted slope one algorithm (और औपचारिक रूप से here (PDF)) के बारे में पढ़ रहा था, जो कि विभिन्न उपयोगकर्ताओं से आइटम रेटिंग लेना है और, कम से कम 1 रेटिंग और 1 गुम मूल्य वाले उपयोगकर्ता वेक्टर को देखते हुए, भविष्यवाणी करें गायब रेटिंगभारित ढलान एक एल्गोरिदम? (पायथन से आर तक पोर्टिंग)

मुझे Python implementation of the algorithm मिला, लेकिन मुझे R (जिसे मैं अधिक आरामदायक हूं) पर पोर्टिंग करने में कठिनाई हो रही है। नीचे मेरा प्रयास है। इसे कैसे काम करना है इस पर कोई सुझाव?

अग्रिम धन्यवाद, दोस्तों।

# take a 'training' set, tr.set and a vector with some missing ratings, d 
pred=function(tr.set,d) { 
    tr.set=rbind(tr.set,d) 
    n.items=ncol(tr.set) 

    # tally frequencies to use as weights 
    freqs=sapply(1:n.items, function(i) { 
     unlist(lapply(1:n.items, function(j) { 
      sum(!(i==j)&!is.na(tr.set[,i])&!is.na(tr.set[,j])) })) }) 

    # estimate product-by-product mean differences in ratings 
    diffs=array(NA, dim=c(n.items,n.items)) 
    diffs=sapply(1:n.items, function(i) { 
     unlist(lapply(1:n.items, function(j) { 
      diffs[j,i]=mean(tr.set[,i]-tr.set[,j],na.rm=T) })) }) 

    # create an output vector with NAs for all the items the user has already rated 
    pred.out=as.numeric(is.na(d)) 
    pred.out[!is.na(d)]=NA 

    a=which(!is.na(pred.out)) 
    b=which(is.na(pred.out)) 

    # calculated the weighted slope one estimate 
    pred.out[a]=sapply(a, function(i) { 
     sum(unlist(lapply(b,function (j) { 
      sum((d[j]+diffs[j,i])*freqs[j,i])/rowSums(freqs)[i] }))) }) 

    names(pred.out)=colnames(tr.set) 
    return(pred.out) } 
# end function 

# test, using example from [3] 
alice=c(squid=1.0, octopus=0.2, cuttlefish=0.5, nautilus=NA) 
bob=c(squid=1.0, octopus=0.5, cuttlefish=NA, nautilus=0.2) 
carole=c(squid=0.2, octopus=1.0, cuttlefish=0.4, nautilus=0.4) 
dave=c(squid=NA, octopus=0.4, cuttlefish=0.9, nautilus=0.5) 
tr.set2=rbind(alice,bob,carole,dave) 
lucy2=c(squid=0.4, octopus=NA, cuttlefish=NA, nautilus=NA) 
pred(tr.set2,lucy2) 
# not correct 
# correct(?): {'nautilus': 0.10, 'octopus': 0.23, 'cuttlefish': 0.25} 
+0

मैंने कोड को और अधिक पठनीय बनाने के लिए प्रारूपित करने का प्रयास किया, लेकिन आर मुझसे अपरिचित है। क्षमा करें अगर यह अच्छी शैली नहीं है। – ephemient

उत्तर

9

मैं ढाल वन के एक अनुसंधान संस्करण एक समय पहले लिखने के लिए एक ही संदर्भ (ब्रायन ओ'सुलिवान के अजगर कोड) का इस्तेमाल किया। अगर यह मदद करता है तो मैं नीचे दिए गए कोड को चिपका रहा हूं।

predict <- function(userprefs, data.freqs, data.diffs) { 
    seen <- names(userprefs) 

    preds <- sweep(data.diffs[ , seen, drop=FALSE], 2, userprefs, '+') 
    preds <- preds * data.freqs[ , seen] 
    preds <- apply(preds, 1, sum) 

    freqs <- apply(data.freqs[ , seen, drop=FALSE], 1, sum) 

    unseen <- setdiff(names(preds), seen) 
    result <- preds[unseen]/freqs[unseen] 
    return(result[is.finite(result)]) 
} 

update <- function(userdata, freqs, diffs) { 
    for (ratings in userdata) { 
     items <- names(ratings) 
     n <- length(ratings) 

     ratdiff <- rep(ratings, n) - rep(ratings, rep(n, n)) 
     diffs[items, items] <- diffs[items, items] + ratdiff 

     freqs[items, items] <- freqs[items, items] + 1 
    } 
    diffs <- diffs/freqs 
    return(list(freqs=freqs, diffs=diffs)) 
} 


userdata <- list(alice=c(squid=1.0, cuttlefish=0.5, octopus=0.2), 
       bob=c(squid=1.0, octopus=0.5, nautilus=0.2), 
       carole=c(squid=0.2, octopus=1.0, cuttlefish=0.4, nautilus=0.4), 
       dave=c(cuttlefish=0.9, octopus=0.4, nautilus=0.5)) 

items <- c('squid', 'cuttlefish', 'nautilus', 'octopus') 
n.items <- length(items) 
freqs <- diffs <- matrix(0, nrow=n.items, ncol=n.items, dimnames=list(items, items)) 

result <- update(userdata, freqs, diffs) 
print(result$freqs) 
print(result$diffs) 

userprefs <- c(squid=.4) 
predresult <- predict(userprefs, result$freqs, result$diffs) 
print(predresult) 
संबंधित मुद्दे