Achten Sie sample
auf die Aufteilung, wenn Sie nach reproduzierbaren Ergebnissen suchen. Wenn sich Ihre Daten nur geringfügig ändern, ändert sich die Aufteilung auch bei Verwendung set.seed
. Stellen Sie sich zum Beispiel vor, die sortierte Liste der IDs in Ihren Daten enthält alle Zahlen zwischen 1 und 10. Wenn Sie nur eine Beobachtung fallen lassen, z. B. 4, würde die Stichprobe nach Standort zu anderen Ergebnissen führen, da jetzt 5 bis 10 alle Orte verschoben werden.
Eine alternative Methode besteht darin, eine Hash-Funktion zu verwenden, um IDs in einige Pseudozufallszahlen abzubilden und dann den Mod dieser Zahlen abzutasten. Diese Stichprobe ist stabiler, da die Zuordnung jetzt durch den Hash jeder Beobachtung und nicht durch ihre relative Position bestimmt wird.
Beispielsweise:
require(openssl) # for md5
require(data.table) # for the demo data
set.seed(1) # this won't help `sample`
population <- as.character(1e5:(1e6-1)) # some made up ID names
N <- 1e4 # sample size
sample1 <- data.table(id = sort(sample(population, N))) # randomly sample N ids
sample2 <- sample1[-sample(N, 1)] # randomly drop one observation from sample1
# samples are all but identical
sample1
sample2
nrow(merge(sample1, sample2))
[1] 9999
# row splitting yields very different test sets, even though we've set the seed
test <- sample(N-1, N/2, replace = F)
test1 <- sample1[test, .(id)]
test2 <- sample2[test, .(id)]
nrow(test1)
[1] 5000
nrow(merge(test1, test2))
[1] 2653
# to fix that, we can use some hash function to sample on the last digit
md5_bit_mod <- function(x, m = 2L) {
# Inputs:
# x: a character vector of ids
# m: the modulo divisor (modify for split proportions other than 50:50)
# Output: remainders from dividing the first digit of the md5 hash of x by m
as.integer(as.hexmode(substr(openssl::md5(x), 1, 1)) %% m)
}
# hash splitting preserves the similarity, because the assignment of test/train
# is determined by the hash of each obs., and not by its relative location in the data
# which may change
test1a <- sample1[md5_bit_mod(id) == 0L, .(id)]
test2a <- sample2[md5_bit_mod(id) == 0L, .(id)]
nrow(merge(test1a, test2a))
[1] 5057
nrow(test1a)
[1] 5057
Die Stichprobengröße beträgt nicht genau 5000, da die Zuordnung wahrscheinlich ist, aber bei großen Stichproben sollte sie aufgrund des Gesetzes der großen Zahlen kein Problem darstellen.
Siehe auch: http://blog.richardweiss.org/2016/12/25/hash-splits.html
und /crypto/20742/statistical-properties-of-hash-functions-when -berechnungsmodulo
x
kann der Index (z. B. Zeilen- / Spaltennummern) Ihres seindata
.size
kann sein0.75*nrow(data)
. Versuchen Siesample(1:10, 4, replace = FALSE, prob = NULL)
zu sehen, was es tut.