R 从稀疏矩阵中随机选择k个数值元素
我有一个稀疏矩阵(57%稀疏),我想从矩阵中随机选择k个数值,以便能够将我的数据拆分为训练和测试数据集 我创建了一个可复制的数据集:R 从稀疏矩阵中随机选择k个数值元素,r,matrix,R,Matrix,我有一个稀疏矩阵(57%稀疏),我想从矩阵中随机选择k个数值,以便能够将我的数据拆分为训练和测试数据集 我创建了一个可复制的数据集: movies = c("HP1", "HP2", "HP3", "TW", "SW1", "SW2", "SW3") users = c("A", "B", "C",
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) 完全同意质疑列的子集。。。对我来说似乎很奇怪,一定是关于数据我们不知道的其他事情。(也许它应该是长格式而不是宽格式?)为没有提供进一步的信息来澄清而道歉。我正在尝试构建一个推荐系统,并希望遵循“训练/测试分离”方法,即我们如何编辑此代码,以便在训练和测试矩阵中至少有一个条目。如果我以这种方式对列进行采样,我会得到这样的情况:培训矩阵可能没有来自特定用户的任何评论。