Live data from Hacker News

Algorithms Every Programmer Should Know: Reservoir Sampling

omniref.com

91–100 of 114 posts

Re: Algorithms Every Programmer Should Know: Reservoir Sampling

#91
post #5

This algorithm was introduced with the premise > "I have a database table with #{17.kajillion} records, and I want to take a random sample of #{X} of them. How can I do this efficently?" And goes on to say that something like `YourBigTable.all.sample(X)` is bad in time and space. And the link that explains why doing `ORDER BY RANDOM()` is bad lists one reason being that generation of random numbers is relatively expe…

one reason being that generation of random numbers is relatively expensive Say again? My laptop can read from /dev/urandom at over 1 Gbps. If you're running in userland on modern hardware you can easily hit 10 Gbps. Seeding is hard, but once you've done that, generating random numbers is insanely cheap.

Yeah, I dunno why it says generating random numbers is expensive. I was just quoting his linked source.

Re: Algorithms Every Programmer Should Know: Reservoir Sampling

#92
post #42
post #26

Earlier quoted context omitted.

> But these problems aren't solved by reservoir sampling. Reservoir sampling is still O(N), and it requires generating a random number for every element. I had the same thought reading this. This solution is only really suitable if the number of elements to select is within some constant of the total number of elements. > More generally, reservoir sampling is appropriate when you don't know the size of the set before…

As I said on another comment in this thread: if you have the addresses (i.e. database ID values) for all of your records in memory, then sure, sampling directly from that set is faster than iterating over every record in a table. There are lots of cases where this assumption doesn't hold: if you're sampling from a join, or from a table with non-contiguous ID values, for example.

Or, even better, if you're sampling from a data set as it's being generated. For example, let's say you want to grab 1,000 random tweets out of the output of Twitter's firehose for the next 2 hours - when you decide whether to keep tweet #1,329, you have no idea how many tweets are going to come in after that one, because they haven't been written yet!

Re: Algorithms Every Programmer Should Know: Reservoir Sampling

#93
post #70

Earlier quoted context omitted.

Yeah - unfortunately there isn't a great way to select n random rows in standard SQL. If you have an integral primary key, you could select its max and generate random numbers up to that. Continuity isn't guaranteed so you would need to check for nonexistent primary keys in addition to checking for duplicates. If there's no integral primary key, then there's no standard SQL solution faster than O(n).

If N is sufficiently larger than k, it might actually be faster to do something like let count = query("SELECT COUNT() FROM table") let indices = computeIndices(count, k) for index in indices { results.append(query("SELECT * FROM table LIMIT 1 OFFSET ?", index)) } Yeah, you're doing a bunch of queries, but you're removing all of copying all the data from all the rows.

OFFSET j is O(j) in most RDMSes. You made an o(N/2 * k) algorithm given j is a random number in [0,N).

Re: Algorithms Every Programmer Should Know: Reservoir Sampling

#94
This is awesome. I asked about this question on Stack Overflow back in September, but my question go shut down.

http://stackoverflow.com/questions/25942333/how-do-reservoir...

I use this algorithm in one of my tweet bots that tweets out a random tweet from a txt file containing 10k different quotes, works fantastically and has been for several months with no duplicates or malfunctions.

Re: Algorithms Every Programmer Should Know: Reservoir Sampling

#95
This reminded me of the card shuffling algorithm from Sedgewick

http://algs4.cs.princeton.edu/lectures/21ElementarySorts.pdf

In that he assigns a random number to each element. Sorts the elements based on the random number. Then takes the first N elements from the beginning.

Re: Algorithms Every Programmer Should Know: Reservoir Sampling

#98
post #5

This algorithm was introduced with the premise > "I have a database table with #{17.kajillion} records, and I want to take a random sample of #{X} of them. How can I do this efficently?" And goes on to say that something like `YourBigTable.all.sample(X)` is bad in time and space. And the link that explains why doing `ORDER BY RANDOM()` is bad lists one reason being that generation of random numbers is relatively expe…

> Reservoir sampling is still O(N), and it requires generating a random number for every element.

I agree with your comment in general. Only: you can do better than generate a random number for each element. (Generate a random number to tell you how many elements in the steam to skip.)

Re: Algorithms Every Programmer Should Know: Reservoir Sampling

#99

I used to work on a hospital database, back before the internet. It happened a few times that we were asked for a random sample of records. It was quite common to want to recalculate the rehabilitation rates and other stats. This was a problem, as patient records filled several tapes and, being the youngster, I had to sit loading tapes for hours. Because our data set was bigger than memory, we had trouble deciding wh…

So the hospital was expecting random samples each time, but kept getting the same sample (with some appended records)?

They were getting a new random sample each night. Same (or probably better!) distribution as before.
Post reply on HN