从数据框创建稀疏矩阵

Posted

技术标签:

【中文标题】从数据框创建稀疏矩阵【英文标题】:Create Sparse Matrix from a data frame 【发布时间】:2014-11-30 05:14:03 【问题描述】:

我正在执行一项任务,我正在尝试为 Netflix 奖品数据构建一个协作过滤模型。我使用的数据在一个 CSV 文件中,我很容易将它导入到数据框中。现在我需要做的是创建一个由用户作为行和电影作为列的稀疏矩阵,并且每个单元格都由相应的评级值填充。当我尝试绘制数据框中的值时,我需要为数据框中的每一行运行一个循环,这在 R 中花费了大量时间,请任何人提出更好的方法。以下是示例代码和数据:

buildUserMovieMatrix <- function(trainingData)

  UIMatrix <- Matrix(0, nrow = max(trainingData$UserID), ncol = max(trainingData$MovieID), sparse = T);
  for(i in 1:nrow(trainingData))
  
    UIMatrix[trainingData$UserID[i], trainingData$MovieID[i]] = trainingData$Rating[i];
  
  return(UIMatrix);

从中创建稀疏矩阵的数据框中的数据样本:

    MovieID UserID  Rating
1       1      2       3
2       2      3       3
3       2      4       4
4       2      6       3
5       2      7       3

所以最后我想要这样的东西: 列是电影 ID,行是用户 ID

    1   2   3   4   5   6   7
1   0   0   0   0   0   0   0
2   3   0   0   0   0   0   0
3   0   3   0   0   0   0   0
4   0   4   0   0   0   0   0
5   0   0   0   0   0   0   0
6   0   3   0   0   0   0   0
7   0   3   0   0   0   0   0

所以解释是这样的:用户 2 将电影 1 评为 3 星,用户 3 将电影 2 评为 3 星,以此类推其他用户和电影。我的数据框中大约有 8500000 行,我的代码只需要大约 30-45 分钟来创建这个用户项矩阵,我想得到任何建议

【问题讨论】:

【参考方案1】:

Matrix 包有一个专门为您的数据类型制作的构造函数:

library(Matrix)
UIMatrix <- sparseMatrix(i = trainingData$UserID,
                         j = trainingData$MovieID,
                         x = trainingData$Rating)

否则,您可能想了解[ 函数的那个​​很酷的特性,即矩阵索引。您可以尝试:

buildUserMovieMatrix <- function(trainingData) 
  UIMatrix <- Matrix(0, nrow = max(trainingData$UserID),
                        ncol = max(trainingData$MovieID), sparse = TRUE);
  UIMatrix[cbind(trainingData$UserID,
                 trainingData$MovieID)] <- trainingData$Rating;
  return(UIMatrix);

(但我肯定会推荐 sparseMatrix 方法。)

【讨论】:

sparseMatrix 方法比第二种方法工作得更快,谢谢。 :)【参考方案2】:

这可能比循环更快。

library(reshape2)
m <- dcast(df,UserID~MovieID,fill=0)[-1]
m
#   1 2
# 1 3 0
# 2 0 3
# 3 0 4
# 4 0 3
# 5 0 3

如果你使用data.tables,它会快很多

library(data.table)
DT <- as.data.table(df)
m  <- dcast(DT,UserID~MovieID,fill=0)[-1]

我相信有人会指出,你可以改用这个

setDT(df)
m  <- dcast(df,UserID~MovieID,fill=0)[-1]

这会将df 转换为适当的data.table(不制作副本)。如果您的数据集非常庞大,那可能会有所不同...

【讨论】:

这种方法有一个小问题,这种方法不能正确映射 USERID 和 MOVIEID,例如训练数据中缺少 USER 11,所以现在在第 11 行中,我有用户 12 的用户 ID 和电影 ID 评级,随后所有行都移动了 1,我的火车集中有 10916 个用户,我想保留所有这些都在我的用户项矩阵中,如果我的训练数据中缺少用户,我可以将整个行向量标记为零,这将防止训练数据数据框和我的矩阵中的任何不匹配,你能建议一些其他的吗方法,谢谢

以上是关于从数据框创建稀疏矩阵的主要内容,如果未能解决你的问题,请参考以下文章

将稀疏矩阵转换为熊猫数据框

如何将数据框转换为具有混合列类型的稀疏矩阵?

迭代稀疏矩阵并连接每一行的数据和索引

从 numpy 数组创建稀疏矩阵

数据结构之稀疏矩阵

从稀疏矩阵导入时出现 Modin AttributeError