R 从稀疏矩阵中随机选择k个数值元素

R 从稀疏矩阵中随机选择k个数值元素,r,matrix,R,Matrix,我有一个稀疏矩阵(57%稀疏),我想从矩阵中随机选择k个数值,以便能够将我的数据拆分为训练和测试数据集 我创建了一个可复制的数据集: movies = c("HP1", "HP2", "HP3", "TW", "SW1", "SW2", "SW3") users = c("A", "B", "C",

我有一个稀疏矩阵(57%稀疏),我想从矩阵中随机选择k个数值,以便能够将我的数据拆分为训练和测试数据集

我创建了一个可复制的数据集:

movies = c("HP1", "HP2", "HP3", "TW", "SW1", "SW2", "SW3")
users = c("A", "B", "C", "D")

row1 = c(4, NA, NA, 5, 1, NA, NA)
row2 = c(5, 5, 4, NA, NA, NA, NA)
row3 = c(NA, NA, NA, 2, 4, 5, NA)
row4 = c(NA, 3, NA, NA, 1, NA, 3)

ratings_matrix = rbind(row1, row2, row3, row4)
ratings_matrix = as.matrix(ratings_matrix)

colnames(ratings_matrix) = movies
rownames(ratings_matrix) = users
假设可以内置一些随机抽样,我希望得到如下输出:

培训矩阵:

  HP1 HP2 HP3 TW SW1 SW2 SW3
A   4  NA  NA  5  NA  NA  NA
B   5   5  NA NA  NA  NA  NA
C  NA  NA  NA  2   4  NA  NA
D  NA  NA  NA NA   1  NA   3
测试矩阵:

  HP2 HP3 SW1 SW2
A  NA  NA  1   NA
B  NA   4  NA  NA
C  NA  NA  NA   5 
D  3   NA  NA  NA

我根据行数将数据集随机划分为训练集和测试集,例如,训练集获得75%的数据,测试集获得25%的数据

这是代码,其中我所做的所有更改都是前两行,表示我要向训练集和测试集提供多少数据(这里称为
dat
,但将是
ratings\u matrix
):

## Set the fractions of the dataframe to split into training and test.
training.size   <- 0.75
test.size       <- 0.25

## Compute sample sizes based on proportion of data I want for each data set. 
training.N   <- floor(training.size   * nrow(dat)) 
test.N       <- floor(test.size       * nrow(dat))

# Create the randomly-sampled indices for the dataframe. Use setdiff() to avoid overlapping subsets of indices.
#For example, training.indices explained: randomly sample the dataset for all columns, choose 75% of the total values, and do not sample with replacement. Assign those new values to a new data.frame, training.indices.

set.seed(4444) #Because the sorting is random, setting the seed ensures reproducibility for future analyses

training.indices    <- sort(sample(seq_len(nrow(dat)), size=training.N, replace=FALSE))
NOTtraining.indices <- setdiff(seq_len(nrow(dat)), training.indices)

# Assign the dataframes for training and test.
training.data   <- dat[training.indices, ]
test.data       <- dat[NOTtraining.indices, ]

这将使您获得所需的输出,如问题中所述。

我根据行数将数据集随机划分为训练集和测试集,例如,训练集获得75%的数据,测试集获得25%的数据

这是代码,其中我所做的所有更改都是前两行,表示我要向训练集和测试集提供多少数据(这里称为
dat
,但将是
ratings\u matrix
):

## Set the fractions of the dataframe to split into training and test.
training.size   <- 0.75
test.size       <- 0.25

## Compute sample sizes based on proportion of data I want for each data set. 
training.N   <- floor(training.size   * nrow(dat)) 
test.N       <- floor(test.size       * nrow(dat))

# Create the randomly-sampled indices for the dataframe. Use setdiff() to avoid overlapping subsets of indices.
#For example, training.indices explained: randomly sample the dataset for all columns, choose 75% of the total values, and do not sample with replacement. Assign those new values to a new data.frame, training.indices.

set.seed(4444) #Because the sorting is random, setting the seed ensures reproducibility for future analyses

training.indices    <- sort(sample(seq_len(nrow(dat)), size=training.N, replace=FALSE))
NOTtraining.indices <- setdiff(seq_len(nrow(dat)), training.indices)

# Assign the dataframes for training and test.
training.data   <- dat[training.indices, ]
test.data       <- dat[NOTtraining.indices, ]

这将使您获得所需的输出,如问题所示。

您可以通过从1到列大小的数组中随机采样列,然后使用
sample(数组,数字到样本)从该数组中随机采样。

#选择列数

ncol您可以通过从1到列大小取一个数组来随机采样列,然后使用
sample(array,number\u to\u sample)从该数组中随机采样。

#选择列数

ncol根据您的评论和您提供的示例网站(),我正在创建一个完全不同的答案,因为我的原始答案仍然针对您的原始问题

以下是我对您在评论中修改的问题的回答:

创建示例数据对象。 注意:示例网站已将电影名称和分级分为不同的列,这是更整洁的数据。您的示例数据不会将电影名称和分级分开,因此,如果您希望像提供的网站一样对电影分级进行分区,则必须按用户和电影名称进行分组

movies = c("HP1", "HP2", "HP3", "TW", "SW1", "SW2", "SW3")
users = c("A", "B", "C", "D") 
row1 = c(4, NA, NA, 5, 1, NA, NA)
row2 = c(5, 5, 4, NA, NA, NA, NA)
row3 = c(NA, NA, NA, 2, 4, 5, NA)
row4 = c(NA, 3, NA, NA, 1, NA, 3)

ratings_df <- as.data.frame(rbind(row1, row2, row3, row4))
colnames(ratings_df) <- movies 
ratings_df <- cbind(ratings_df, users) #users cannot be rownames, because they are not unique values, so I created a column for users, which is similar to the example website you provided

ratings_df
     HP1 HP2 HP3 TW SW1 SW2 SW3 users
row1   4  NA  NA  5   1  NA  NA     A
row2   5   5   4 NA  NA  NA  NA     B
row3  NA  NA  NA  2   4   5  NA     C
row4  NA   3  NA NA   1  NA   3     D
您的输出是
test.matrix

      test.matrix
             TW  SW2 HP2 HP1 SW1 users
        [1,] 5   NA   NA   4   1   A  
        [2,] NA  NA   5    5   NA  B  
        [3,] 2   5    NA   NA  4   C  
        [4,] NA  NA   3    NA  1   D 


这个输出,
test.matrix
与您的示例结构匹配,我只是随意选择了80%。

根据您的评论和您提供的示例网站(),我创建了一个完全不同的答案,因为我的原始答案仍然针对您的原始问题

以下是我对您在评论中修改的问题的回答:

创建示例数据对象。 注意:示例网站已将电影名称和分级分为不同的列,这是更整洁的数据。您的示例数据不会将电影名称和分级分开,因此,如果您希望像提供的网站一样对电影分级进行分区,则必须按用户和电影名称进行分组

movies = c("HP1", "HP2", "HP3", "TW", "SW1", "SW2", "SW3")
users = c("A", "B", "C", "D") 
row1 = c(4, NA, NA, 5, 1, NA, NA)
row2 = c(5, 5, 4, NA, NA, NA, NA)
row3 = c(NA, NA, NA, 2, 4, 5, NA)
row4 = c(NA, 3, NA, NA, 1, NA, 3)

ratings_df <- as.data.frame(rbind(row1, row2, row3, row4))
colnames(ratings_df) <- movies 
ratings_df <- cbind(ratings_df, users) #users cannot be rownames, because they are not unique values, so I created a column for users, which is similar to the example website you provided

ratings_df
     HP1 HP2 HP3 TW SW1 SW2 SW3 users
row1   4  NA  NA  5   1  NA  NA     A
row2   5   5   4 NA  NA  NA  NA     B
row3  NA  NA  NA  2   4   5  NA     C
row4  NA   3  NA NA   1  NA   3     D
您的输出是
test.matrix

      test.matrix
             TW  SW2 HP2 HP1 SW1 users
        [1,] 5   NA   NA   4   1   A  
        [2,] NA  NA   5    5   NA  B  
        [3,] 2   5    NA   NA  4   C  
        [4,] NA  NA   3    NA  1   D 


这个输出,
test.matrix
与示例中的结构匹配,我只是随意选择了80%。

(1)除了将
nrow
更改为
ncol
,您还需要更改代码最后两行中的逗号索引。(2) 这可能并将产生不符合要求的75%/25%的训练/测试对,而这并不是真正可以避免的。可能有必要循环和/或以某种方式添加约束,以便能够保证比10和2(83%/17%)更接近的值(如果不能真正保证的话)。(3) 完全同意质疑列的子集。。。对我来说似乎很奇怪,一定是关于数据我们不知道的其他事情。(也许它应该是长格式而不是宽格式?)为没有提供进一步的信息来澄清而道歉。我正在尝试构建一个推荐系统,并希望遵循“训练/测试分离”方法,即我们如何编辑此代码,以便在训练和测试矩阵中至少有一个条目。如果我以这种方式对列进行采样,我得到的情况是,培训矩阵可能没有来自特定用户的任何评论。(1)除了将
nrow
更改为
ncol
,您还需要更改代码最后两行中的逗号索引。(2) 这可能并将产生不符合要求的75%/25%的训练/测试对,而这并不是真正可以避免的。可能有必要循环和/或以某种方式添加约束,以便能够保证比10和2(83%/17%)更接近的值(如果不能真正保证的话)。(3) 完全同意质疑列的子集。。。对我来说似乎很奇怪,一定是关于数据我们不知道的其他事情。(也许它应该是长格式而不是宽格式?)为没有提供进一步的信息来澄清而道歉。我正在尝试构建一个推荐系统,并希望遵循“训练/测试分离”方法,即我们如何编辑此代码,以便在训练和测试矩阵中至少有一个条目。如果我以这种方式对列进行采样,我会得到这样的情况:培训矩阵可能没有来自特定用户的任何评论。