【问题标题】:R data frame transformationR数据框转换
【发布时间】:2014-03-06 16:12:00
【问题描述】:

我有一个数据框如下,每一行代表一个事务(即用户001听了Nirvana,也听了Metallica,但没有听Slayer)

userid   artist      gender    country
001      nirvana     m         germany
001      metallica   m         germany
002      slayer      m         usa
003      nirvana     m         germany
003      metallica   m         germany
...      ...         ...       ...

现在我需要对此进行预处理以进行基于项目的推荐。我需要以某种方式结束歌曲元素之间的余弦相似度矩阵

             nirvana       metallica      slayer
nirvana                    0.2            0
metallica    0.24                         0
slayer       0             0               

这是为了建立一个推荐系统,所以如果有人能指出我正确的方向或给我一个方法,我将不胜感激。

【问题讨论】:

标签: r recommendation-engine


【解决方案1】:

方法

执行此操作的步骤包括:

  1. 转换数据集
  2. 创建歌曲/歌曲数据框
  3. 计算每个单元格的余弦相似度

转型

为了转换数据集,我们使用 plyr 库来获取 Country 为 Germany 的子集(我只对德国感兴趣) 图书馆(plyr) data.germany

然后我们想创建一个频率表,我们只需要用户听过的歌曲

germany.frequency<-as.data.frame((table(data.germany$user,data.germany$artist,dnn=c("user","artist"))))

germany.frequency<-subset(germany.frequency,Freq>=1)

然后我们填充一个二进制矩阵,其中 1 代表用户收听的歌曲

germany.users <- as.matrix(unique(data.germany$user))
germany.artists <- as.matrix(unique(data.germany$artist))
holder <- matrix(NA, nrow=nrow(germany.users),ncol=nrow(germany.artists),dimnames=list((germany.users),(germany.artists)))
holder[,] <- 0
for(i in 1:nrow(holder)) {
  for(j in 1:ncol(holder)) {
    if(nrow(subset(germany.frequency, (user == rownames(holder)[i] & artist ==    colnames(holder)[j])))>0)
    {  holder[i,j]<-1 }  
  }
}

# Reorder the column names alphabetically
data.germany<-(holder[,order(colnames(holder))])

我们现在读取了持有人矩阵。注意:R 中的 for 循环需要很长时间。

基于项目的相似性

删除用户列并创建一个新的数据框

data.germany.ibs <- (data.germany[,!(names(data.germany) %in% c("user"))])

创建一个辅助函数来计算两个向量之间的余弦

getCosine <- function(x,y) 
{
  this.cosine <- sum(x*y) / (sqrt(sum(x*x)) * sqrt(sum(y*y)))
  return(this.cosine)
}

创建一个占位符数据框列出项目与项目

holder <- matrix(NA, nrow=ncol(data.germany.ibs),ncol=ncol(data.germany.ibs),dimnames=list(colnames(data.germany.ibs),colnames(data.germany.ibs)))

data.germany.ibs.similarity <- as.data.frame(holder)

让我们用余弦相似度填充那些空白

for(i in 1:ncol(data.germany.ibs)) {
    for(j in 1:ncol(data.germany.ibs)) {
      data.germany.ibs.similarity[i,j]= getCosine(data.germany.ibs[i],data.germany.ibs[j])
}

}

将相似度结果输出到文件

write.csv(data.germany.ibs.similarity,file="final-germany-similarity.csv")

获取每个邻居的前 10 个邻居

data.germany.neighbours <- matrix(NA, nrow=ncol(data.germany.ibs.similarity),ncol=11,dimnames=list(colnames(data.germany.ibs.similarity)))

for(i in 1:ncol(data.germany.ibs)) 
{
    data.germany.neighbours[i,] <- (t(head(n=11,rownames(data.germany.ibs.similarity[order(data.germany.ibs.similarity[,i],decreasing=TRUE),][i]))))
}

将邻居结果输出到文件

  write.csv(file="final-germany-item-neighbours.csv",x=data.germany.neighbours[,-1])

【讨论】:

    【解决方案2】:

    我建议使用 arules 包并传递用户 ID 和艺术家。包装上有非常清晰的说明。快速简单...生成的规则质量很高。

    假设您需要基于项目的 CF 而没有其他办法,请尝试 Recommender Lab 包。它有预建的功能,虽然我发现它很不稳定并且没有很多文档,但它可能会有所帮助。

    我发现大多数人将推荐引擎和协同过滤视为同义词,而实际上它们根本不是。

    【讨论】:

    • 我必须在一个项目中同时使用这两个 ^_^ 我之前看到了推荐实验室,我同意它看起来很阴暗。我想出了一个我现在要提出的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-04
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    • 1970-01-01
    • 2015-04-16
    • 1970-01-01
    相关资源
    最近更新 更多