如何使用R项目创建电影评级的矢量矩阵?

时间:2012-01-17 01:11:01

标签: r data-mining sparse-matrix

假设我正在使用此电影评级数据集:http://www.grouplens.org/node/73

它包含格式为的文件中的评级 用户ID :: movieID ::评级::时间戳

鉴于此,我想在R项目中构建一个特征矩阵,其中每一行对应一个用户,每列指示用户给予电影的评级(如果有的话)。

示例,如果数据文件包含

1::1::1::10
2::2::2::11
1::2::3::12
2::1::5::13
3::3::4::14

然后输出矩阵看起来像:

UserID, Movie1, Movie2, Movie3
1, 1, 3, NA
2, 5, 2, NA
3, NA, NA, 3

在R项目中是否有一些内置的方法来实现这一点。我写了一个简单的python脚本来做同样的事情,但我敢打赌,有更有效的方法来实现这一点。

3 个答案:

答案 0 :(得分:3)

您可以在dcast包中使用reshape2函数,但生成的data.frame可能很大(并且稀疏)。

d <- read.delim(
  "u1.base", 
  col.names = c("user", "film", "rating", "timestamp")
)
library(reshape2)
d <- dcast( d, user ~ film, value.var = "rating" )

如果您的字段以双冒号分隔,则不能使用sep的{​​{1}}参数,该参数必须只有一个字符。 如果你已经在R之外做了一些预处理,那么在那里做更容易(例如,在Perl中,它只是read.delim),但你也可以在R中执行:将文件作为单个列读取,拆分字符串,并连接结果。

s/::/\t/g

答案 1 :(得分:0)

从上一个问题中指出的网站,您似乎想要代表

> print(object.size(integer(10000 * 72000)), units="Mb")
2746.6 Mb

another question中引用的8 GB应该是“简单”。此外,总长度小于R中的最大矢量长度,因此也应该没问题。但是看到回复的结尾有一个重要的警告!

我在R之外创建了一个制表符分隔的数据文件版本。然后我读了我感兴趣的信息

what <- list(User=integer(), Film=integer(), Rating=numeric(), NULL)
x <- scan(fl, what)

'NULL'删除未使用的时间戳数据。 “用户”和“电影”条目不是连续的,我平台上的numeric()占用的内存是integer()的两倍,因此我将用户和电影转换为因子,并将评级转换为整数()加倍(原始分数为1到5,增量为1/2)。

x <- list(User=factor(x$User), Film=factor(x$Film),
          Rating=as.integer(2 * x$Rating))

然后我分配了矩阵

ratings <- matrix(NA_integer_ ,
                 nrow=length(levels(x$User)),
                 ncol=length(levels(x$Film)),
                 dimnames=list(levels(x$User), levels(x$Film)))

并使用两列矩阵可用于索引另一个矩阵的事实

ratings[cbind(x$User, x$Film)] <- x$Rating

这是内存使用最多的步骤。然后我删除不需要的变量

rm(x)

gc()函数告诉我我使用了多少内存......

> gc()
            used   (Mb) gc trigger   (Mb)  max used   (Mb)
Ncells    140609    7.6     407500   21.8    350000   18.7
Vcells 373177663 2847.2  450519582 3437.2 408329775 3115.4

......略高于3 Gb,所以这很好。

这样做之后,你现在会遇到严重的问题。 kmeans(来自您对先前早期答案中的问题的回答)不适用于缺失值

> m = matrix(rnorm(100), 5)
> m[1,1]=NA
> kmeans(m, 2)
Error in do_one(nmeth) : NA/NaN/Inf in foreign function call (arg 1)

作为一个非常粗略的经验法则,我希望现成的R解决方案需要的内存是起始数据大小的3-5倍。您是否使用较小的数据集进行了分析?

答案 2 :(得分:0)

很简单,您可以使用sparseMatrix包中的Matrix将其表示为稀疏矩阵。

只需创建一个3列坐标对象列表,即以(i, j, value)形式,例如在名为myDF的data.frame中。然后,执行mySparseMat <- sparseMatrix(i = myDF$i, j = myDF$j, x = myDF$x, dims = c(numRows, numCols) - 您需要确定行数和列数,否则最大索引将用于决定矩阵的大小。

就是这么简单。如果不是怪诞的话,将稀疏数据存储在密集矩阵中是不合适的。