Open matomatical opened 3 years ago
First, thank you so much for spending so much time and attention on Ebisu, on coming up with this approach, and for writing it up in such detail! I am very grateful!!
Second—yes! I like this!!! I am confident you have found a much better alternative to the rebalancing that we currently do—we can replace the very ad hoc check for rebalance (0.5 < α / β < 2
) and the coarse grid search with a very reasonable and self-explanatory alternative.
And as you note, it will give us a cheap and good approximation to start the fine search for the true halflife (that gives us posterior mean of 0.5) to properly do #31.
I'm also confident it will be straightforward to incorporate this approach with the binomial quiz case.
Are you interested in a version of Ebisu that does #31 (always rebalances), using this approach? If so, I can try to focus on that plus some other outstanding issues that are mostly done and release a new minor version—alas due to life commitments, I'm not sure when I'll be able to give this the time it needs. But it sounds like you have a version that is working for you, and while, yes, it may be possible that we need a fallback in case this algebraic approach to approximating the halflife fails, I think barring pathological cases it should work just fine.
Again, many, many thanks for your hard work!!!
Right, I have my own implementation, which I will continue to use for my memory exercises. So there's no pressure from me to get this into a new minor version. Please consider this issue a 'feature suggestion' rather than an 'issue' or urgent feature request.
In the mean time, I'll continue to use (my implementation of) the ebisu algorithm for my memory exercises and I can update you once I have more data on how this heuristic updating scheme performs, or if it destroys my memory models, or if I come across any other suggestions.
@fasiha, I dare say, I think you're going to like this!
Overview
I've been working on a pure-Python implementation of the ebisu algorithm and I was not satisfied with the current approach to determining a new half-life during updates (that being 'just use the old half-life, unless the Beta model gets too unbalanced, then 'rebalance' it using a coarse grid search over halflives').
I came up with a different approach which turns out, from my initial experiments, to be simpler, work faster, and actually lead to more accurate/meaningful half-life updates than the current rebalancing strategy (see also #31).
Key idea
They key idea is as follows:
You have shown that in this case the time-decaying beta distribution's mean does not undergo exponential decay exactly, but that it's pretty close. If we were to (approximately) model the probability of recall's mean over time as exponential decay with some half-life, we would get an (approximate) closed form equation for that half-life in terms of the mean at any other given time.
Let P_recall@t be the random variable representing the probability of recall at elapsed time t. Then:
E[P_recall@t] =approx. 2 ^ {-t / λ}
where λ is the half-life of the exponential decay. We can invert this equation to get:
λ =approx. - t / log_2 E[P_recall@t].
Algorithm
The resulting update algorithm works as follows. If my understanding of the ebisu algorithm is correct, the only change from the current algorithm is in step 4.
Note: some of those steps are conceptual rather than computational; pseudocode illustrating the computational steps is below (all in log-space, of course):
Results
I have experimented by performing these Bernoulli updates at 0.0001, 0.01, 1, 100, and 10000 half-lives, for both failed (successes=0) and passed (successes=1) trials. The initial half-life was exactly 1 (so t = δ).
I tried the following four update schemes for comparison:
λ_new = λ_old (no rebalance)
: Do not attempt to rebalance, just force fit a Beta distribution to the posterior, no matter how unequal alpha and beta are.OK, no question, this strategy is Really Bad, obviously. The half-life parameter loses all interpretability and, as I think you mentioned elsewhere, moment-matching would probably be pretty inaccurate for such extremely skewed posteriors.
ebisu (AUTO rebalance)
: The current implentation: Do (1) unless alpha and beta differ by a factor of two or more, then use coarse grid-search to find a new half-life.Behaving as expected. Interestingly, there is never a need to rebalance for fail trials even for extremely quick fails.
ALWAYS ebisu-rebalance
: Always use coarse grid-search to find a new half-life.Also behaving as expected. Interestingly, the grid search finds an increased half-life parameter as the best fit even for failed trials. Of course, the effective 'half-life' determining scheduling probably still goes down, and this is probably captured through appropriate changes in alpha and beta.
always APPROX. rebalance
: Always use the approximation discussed above to find a new half-life.This behaviour is, I think, really neat! So we see that for the cases where the existing ebisu algorithm (above) decided to rescale the half-life, this approximate method got a similar value (e.g. 3361 v. 3466, 61 v. 35, about 1 v. about 1). In a few notable cases, I think it did a 'better' job, especially in that the half-life actually goes down for failed trials. Perhaps most importantly, the changes to the alpha and beta parameters at the new half-life are pretty contained, i.e. the beta distribution has stayed very well balanced. More on this in the following plot.
Finally, here's a plot of some of the posterior Beta distributions at their new half-lives after these updates, for the various algorithms. Of course, the no-rebalancing scheme is useless, and the ebisu rebalancing scheme works pretty well. But here you can see visually how the new approximate balancing scheme looks even a little more centered at its half-life than the current ebisu rebalancing scheme.
Remaining issues
So far, I have only implemented this for Bernoulli quizzes, because that's all my pure-Python port aims to implement (because my memory app doesn't offer any Binomial trials with total > 1). However, I think the math would go through regardless and so this approach could easily be incorporated into ebisu proper in principle.
I haven't extensively tested the approach, it may be possible that the exponential approximation is pretty dramatically off outside of the range of values I tested, and there it may lead to bad updates. I was actually hoping that with your experience testing ebisu algorithms you might be able to (help) confirm whether this algorithm works over a broader range of situations.
The result of the algorithm is still not completely centered, and so perhaps over many updates it would become unbalanced and need a more sophisticated rebalancing operation. Or, for reasons deeper than what I have considered, this approach might be kind of self-stabilising. Anyway, either way, to be safe it would be easy to use as a default strategy followed by a more sophisticated balancing strategy if the alpha and beta get too out of kilter.
In case you are interested, I do have code to back this up and I am in principle willing to share it all in the public domain, but it's not quite ready for sharing yet. Anyway you can probably find some of it if you look hard enough around my own github.