根据我现有的数据集生成额外的随机数据样本
Generate additional random samples of data based upon my existing dataset
我正在尝试从我现有的样本数据中生成更大的数据样本。例如 iris
是 N = 150
,我想将其重新调整为 4500(每个物种 1500)。 post 此处 https://seslezak.github.io/IrisData/ 中描述了一个示例。我不想 resample
或 bootstrap
我对生成新值很感兴趣,例如 rnorm
这是我迄今为止尝试过的方法。
muSepal.Length = mean(iris$Sepal.Length)
sdSepal.Length = sd(iris$Sepal.Length)
muSepal.Width= mean(iris$Sepal.Width)
sdSepal.Width = sd(iris$Sepal.Width)
N = 5000
simulated_data = data.frame(Sepal.Length = rnorm(N, muSepal.Length,sdSepal.Length),Sepal.Width =rnorm(N,muSepal.Width,sdSepal.Width))
我在这里从样本分布中提取了值,但我很难理解如何有效地构建整个“新”数据集?
作为@d.b。几个小时前指出,您面临对现有数据进行采样或假设它符合某些理论分布(如 rnorm
)的选择。很明显,您正在模仿的文章的作者选择了后者。新数据集的摘要清楚地显示了某些 setosa Petal.Width 的原始 iris
和 NA
中没有的值,因为在大样本中我们必然会低于 0测量。
这是一组快速但不完善的代码,您应该能够根据自己的数据调整这些代码。
set.seed(2020)
library(dplyr)
testing <- iris %>%
group_by(Species) %>%
summarise_at(vars(Sepal.Length:Petal.Width), list(mean = mean,
sd = sd)) %>%
rowwise() %>%
group_by(Species) %>%
summarise(Sepal.Length = rnorm(1500,
mean = Sepal.Length_mean,
sd = Sepal.Length_sd),
Sepal.Width = rnorm(1500,
mean = Sepal.Width_mean,
sd = Sepal.Width_sd),
Petal.Length = rnorm(1500,
mean = Petal.Length_mean,
sd = Petal.Length_sd),
Petal.Width = rnorm(1500,
mean = Petal.Width_mean,
sd = Petal.Width_sd)) %>%
ungroup %>% # so we stop being rowwise
filter_at(vars(Sepal.Length:Petal.Width), ~ . > .1) # to eliminate ridiculously small or negative values
summary(testing)
#> Species Sepal.Length Sepal.Width Petal.Length
#> setosa :1368 Min. :3.784 Min. :1.719 Min. :0.8857
#> versicolor:1500 1st Qu.:5.168 1st Qu.:2.746 1st Qu.:1.6116
#> virginica :1500 Median :5.834 Median :3.014 Median :4.2998
#> Mean :5.855 Mean :3.047 Mean :3.8148
#> 3rd Qu.:6.443 3rd Qu.:3.322 3rd Qu.:5.2312
#> Max. :8.304 Max. :4.547 Max. :7.5825
#> Petal.Width
#> Min. :0.1001
#> 1st Qu.:0.3373
#> Median :1.3439
#> Mean :1.2332
#> 3rd Qu.:1.8460
#> Max. :3.0523
比我更流利的人可能会做得更好 pivot_longer 或避免 4 次重复调用 rnorm
的自定义函数。由您来寻找不合理的值并证明为什么 rnorm
非常适合您的数据。
使用 MASS::mvrnorm
添加更复杂的解决方案来解释 Remi 在他的回答中提到的相关性。抱歉懒得想出更好的代码,这里只是暴力重复。
library(dplyr)
# Get the covariance matrix by species
sigma.setosa <- iris %>%
filter(Species == "setosa") %>%
select(-Species) %>%
cov
sigma.versicolor <- iris %>%
filter(Species == "versicolor") %>%
select(-Species) %>%
cov
sigma.virginica <- iris %>%
filter(Species == "virginica") %>%
select(-Species) %>%
cov
# generate samples based on those covariance matricies
set.seed(2020)
setosa.rows <- MASS::mvrnorm(n = 1500,
c(mean(iris$Sepal.Length), mean(iris$Sepal.Width), mean(iris$Petal.Length), mean(iris$Petal.Width)),
sigma.setosa,
empirical = TRUE)
versicolor.rows <- MASS::mvrnorm(n = 1500,
c(mean(iris$Sepal.Length), mean(iris$Sepal.Width), mean(iris$Petal.Length), mean(iris$Petal.Width)),
sigma.versicolor,
empirical = TRUE)
virginica.rows <- MASS::mvrnorm(n = 1500,
c(mean(iris$Sepal.Length), mean(iris$Sepal.Width), mean(iris$Petal.Length), mean(iris$Petal.Width)),
sigma.virginica,
empirical = TRUE)
# convert to dataframes
setosa.df <- data.frame(setosa.rows, Species = "setosa")
versicolor.df <- data.frame(setosa.rows, Species = "versicolor")
virginica.df <- data.frame(setosa.rows, Species = "virginica")
# bind them return species to a factor
newiris <- rbind(setosa.df, versicolor.df, virginica.df)
newiris$Species <- factor(newiris$Species)
summary(newiris)
#> Sepal.Length Sepal.Width Petal.Length Petal.Width
#> Min. :4.669 Min. :1.759 Min. :3.183 Min. :0.820
#> 1st Qu.:5.598 1st Qu.:2.805 1st Qu.:3.637 1st Qu.:1.130
#> Median :5.848 Median :3.064 Median :3.761 Median :1.199
#> Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
#> 3rd Qu.:6.083 3rd Qu.:3.306 3rd Qu.:3.878 3rd Qu.:1.267
#> Max. :6.969 Max. :4.288 Max. :4.342 Max. :1.578
#> Species
#> setosa :1500
#> versicolor:1500
#> virginica :1500
#>
#>
#>
summary(iris)
#> Sepal.Length Sepal.Width Petal.Length Petal.Width
#> Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100
#> 1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300
#> Median :5.800 Median :3.000 Median :4.350 Median :1.300
#> Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
#> 3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
#> Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
#> Species
#> setosa :50
#> versicolor:50
#> virginica :50
#>
#>
#>
你的问题问的很清楚了,不知道我在这post写的是不是真的
最简单的方法是使用随机重复观察来增强样本,如下所示:
SimIris <- iris[sample(1:150, 5000, replace = T),]
但是当您提出您的问题时,我想知道我们可以生成多少不重复的随机观察结果。
想法是使用经典统计框架,考虑响应变量 Y
和具有自变量的设计矩阵 X
。您需要找到一个函数 f
使得 :
Y = f(X) + eps
有了之后,只需要模拟一个不会太离奇的X
就可以了。但实际上,在您的情况下,您需要处理变量之间的依赖关系,这会使故事变得有些复杂。我们将做出错误的假设,即变量是独立的。由于 copula.
,概率论的一个领域是处理依赖关系
找到 f
的良好近似值;
模拟X
得益于基本的概率论,我们假设每个变量都是独立的并且来自高斯变量。如果你计算相关性和直方图,你就会明白这是错误的。
library(randomForest)
data("iris")
# your model
rf <- randomForest(Species ~ ., data = iris, family = )
# you simulate X
simulate_wrong <- function(X, n){
return(rnorm(n, mean = mean(X), sd = sd(X)))
}
irisSim <- apply(iris[,-ncol(iris)], 2, simulate_wrong, n = 5000)
# your Y
SpeciesSim <- predict(rf, newdata = irisSim)
# Sanity check : we absolutly need to take care of dependency inside X variables
table(SpeciesSim)
setosa versicolor virginica
1319 2333 1348
table(iris$Species)
setosa versicolor virginica
50 50 50
我们模拟的数据集票价太多versicolor
,我们需要注意X
的相关结构。也许稍后进行编辑。
参考资料:相关性table:
Sepal.Length Sepal.Width Petal.Length Petal.Width
Sepal.Length 1.00 -0.12 0.87 0.82
Sepal.Width -0.12 1.00 -0.43 -0.37
Petal.Length 0.87 -0.43 1.00 0.96
Petal.Width 0.82 -0.37 0.96 1.00
祝你好运
我正在尝试从我现有的样本数据中生成更大的数据样本。例如 iris
是 N = 150
,我想将其重新调整为 4500(每个物种 1500)。 post 此处 https://seslezak.github.io/IrisData/ 中描述了一个示例。我不想 resample
或 bootstrap
我对生成新值很感兴趣,例如 rnorm
这是我迄今为止尝试过的方法。
muSepal.Length = mean(iris$Sepal.Length)
sdSepal.Length = sd(iris$Sepal.Length)
muSepal.Width= mean(iris$Sepal.Width)
sdSepal.Width = sd(iris$Sepal.Width)
N = 5000
simulated_data = data.frame(Sepal.Length = rnorm(N, muSepal.Length,sdSepal.Length),Sepal.Width =rnorm(N,muSepal.Width,sdSepal.Width))
我在这里从样本分布中提取了值,但我很难理解如何有效地构建整个“新”数据集?
作为@d.b。几个小时前指出,您面临对现有数据进行采样或假设它符合某些理论分布(如 rnorm
)的选择。很明显,您正在模仿的文章的作者选择了后者。新数据集的摘要清楚地显示了某些 setosa Petal.Width 的原始 iris
和 NA
中没有的值,因为在大样本中我们必然会低于 0测量。
这是一组快速但不完善的代码,您应该能够根据自己的数据调整这些代码。
set.seed(2020)
library(dplyr)
testing <- iris %>%
group_by(Species) %>%
summarise_at(vars(Sepal.Length:Petal.Width), list(mean = mean,
sd = sd)) %>%
rowwise() %>%
group_by(Species) %>%
summarise(Sepal.Length = rnorm(1500,
mean = Sepal.Length_mean,
sd = Sepal.Length_sd),
Sepal.Width = rnorm(1500,
mean = Sepal.Width_mean,
sd = Sepal.Width_sd),
Petal.Length = rnorm(1500,
mean = Petal.Length_mean,
sd = Petal.Length_sd),
Petal.Width = rnorm(1500,
mean = Petal.Width_mean,
sd = Petal.Width_sd)) %>%
ungroup %>% # so we stop being rowwise
filter_at(vars(Sepal.Length:Petal.Width), ~ . > .1) # to eliminate ridiculously small or negative values
summary(testing)
#> Species Sepal.Length Sepal.Width Petal.Length
#> setosa :1368 Min. :3.784 Min. :1.719 Min. :0.8857
#> versicolor:1500 1st Qu.:5.168 1st Qu.:2.746 1st Qu.:1.6116
#> virginica :1500 Median :5.834 Median :3.014 Median :4.2998
#> Mean :5.855 Mean :3.047 Mean :3.8148
#> 3rd Qu.:6.443 3rd Qu.:3.322 3rd Qu.:5.2312
#> Max. :8.304 Max. :4.547 Max. :7.5825
#> Petal.Width
#> Min. :0.1001
#> 1st Qu.:0.3373
#> Median :1.3439
#> Mean :1.2332
#> 3rd Qu.:1.8460
#> Max. :3.0523
比我更流利的人可能会做得更好 pivot_longer 或避免 4 次重复调用 rnorm
的自定义函数。由您来寻找不合理的值并证明为什么 rnorm
非常适合您的数据。
使用 MASS::mvrnorm
添加更复杂的解决方案来解释 Remi 在他的回答中提到的相关性。抱歉懒得想出更好的代码,这里只是暴力重复。
library(dplyr)
# Get the covariance matrix by species
sigma.setosa <- iris %>%
filter(Species == "setosa") %>%
select(-Species) %>%
cov
sigma.versicolor <- iris %>%
filter(Species == "versicolor") %>%
select(-Species) %>%
cov
sigma.virginica <- iris %>%
filter(Species == "virginica") %>%
select(-Species) %>%
cov
# generate samples based on those covariance matricies
set.seed(2020)
setosa.rows <- MASS::mvrnorm(n = 1500,
c(mean(iris$Sepal.Length), mean(iris$Sepal.Width), mean(iris$Petal.Length), mean(iris$Petal.Width)),
sigma.setosa,
empirical = TRUE)
versicolor.rows <- MASS::mvrnorm(n = 1500,
c(mean(iris$Sepal.Length), mean(iris$Sepal.Width), mean(iris$Petal.Length), mean(iris$Petal.Width)),
sigma.versicolor,
empirical = TRUE)
virginica.rows <- MASS::mvrnorm(n = 1500,
c(mean(iris$Sepal.Length), mean(iris$Sepal.Width), mean(iris$Petal.Length), mean(iris$Petal.Width)),
sigma.virginica,
empirical = TRUE)
# convert to dataframes
setosa.df <- data.frame(setosa.rows, Species = "setosa")
versicolor.df <- data.frame(setosa.rows, Species = "versicolor")
virginica.df <- data.frame(setosa.rows, Species = "virginica")
# bind them return species to a factor
newiris <- rbind(setosa.df, versicolor.df, virginica.df)
newiris$Species <- factor(newiris$Species)
summary(newiris)
#> Sepal.Length Sepal.Width Petal.Length Petal.Width
#> Min. :4.669 Min. :1.759 Min. :3.183 Min. :0.820
#> 1st Qu.:5.598 1st Qu.:2.805 1st Qu.:3.637 1st Qu.:1.130
#> Median :5.848 Median :3.064 Median :3.761 Median :1.199
#> Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
#> 3rd Qu.:6.083 3rd Qu.:3.306 3rd Qu.:3.878 3rd Qu.:1.267
#> Max. :6.969 Max. :4.288 Max. :4.342 Max. :1.578
#> Species
#> setosa :1500
#> versicolor:1500
#> virginica :1500
#>
#>
#>
summary(iris)
#> Sepal.Length Sepal.Width Petal.Length Petal.Width
#> Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100
#> 1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300
#> Median :5.800 Median :3.000 Median :4.350 Median :1.300
#> Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
#> 3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
#> Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
#> Species
#> setosa :50
#> versicolor:50
#> virginica :50
#>
#>
#>
你的问题问的很清楚了,不知道我在这post写的是不是真的
最简单的方法是使用随机重复观察来增强样本,如下所示:
SimIris <- iris[sample(1:150, 5000, replace = T),]
但是当您提出您的问题时,我想知道我们可以生成多少不重复的随机观察结果。
想法是使用经典统计框架,考虑响应变量 Y
和具有自变量的设计矩阵 X
。您需要找到一个函数 f
使得 :
Y = f(X) + eps
有了之后,只需要模拟一个不会太离奇的X
就可以了。但实际上,在您的情况下,您需要处理变量之间的依赖关系,这会使故事变得有些复杂。我们将做出错误的假设,即变量是独立的。由于 copula.
找到
f
的良好近似值;模拟
X
得益于基本的概率论,我们假设每个变量都是独立的并且来自高斯变量。如果你计算相关性和直方图,你就会明白这是错误的。library(randomForest) data("iris") # your model rf <- randomForest(Species ~ ., data = iris, family = ) # you simulate X simulate_wrong <- function(X, n){ return(rnorm(n, mean = mean(X), sd = sd(X))) } irisSim <- apply(iris[,-ncol(iris)], 2, simulate_wrong, n = 5000) # your Y SpeciesSim <- predict(rf, newdata = irisSim) # Sanity check : we absolutly need to take care of dependency inside X variables table(SpeciesSim) setosa versicolor virginica 1319 2333 1348 table(iris$Species) setosa versicolor virginica 50 50 50
我们模拟的数据集票价太多versicolor
,我们需要注意X
的相关结构。也许稍后进行编辑。
参考资料:相关性table:
Sepal.Length Sepal.Width Petal.Length Petal.Width
Sepal.Length 1.00 -0.12 0.87 0.82
Sepal.Width -0.12 1.00 -0.43 -0.37
Petal.Length 0.87 -0.43 1.00 0.96
Petal.Width 0.82 -0.37 0.96 1.00
祝你好运