What’s the Algorithm for Spaced Repetition?

16 points by mrfusion ↗ HN
I want to make a quick command line app to help me memorize stuff using spaced repetition but I can’t seem to find the algorithm spelled out anywhere? How often to show missed facts, how often to show ones you know?

12 comments

[ 2.7 ms ] story [ 42.7 ms ] thread
Thanks. I read the section “ Description of SM-2 algorithm” but I don’t what determines when to show a given card.
I'd look at this from the SuperMemo site: https://www.supermemo.com/en/archives1990-2015/english/ol/sm...

It does a better job of explaining the algorithm. Initially all cards will have an e-factor (easiness in the wiki description) of 2.5. Your card database should have the following per card:

  contents, e-factor(easiness), repetition, interval, last_shown_date
You can optionally add in a next_review_date which you'll calculate after showing and grading the card. Query your database (which may be a flat file, sqlite, whatever) for all cards whose interval + last_shown_date (initially this should be the creation date) is today or earlier (or whose next_review_date is today or earlier if you calculated that already). Those are the ones to review.

You can also distinguish between new, learning, and review cards. New cards have repetition of 0, learning have repetition of 1 or 2, and review are higher than that. This can help with determining which cards to show each day. If you create 1000 new cards today, you don't want to review them all in the same day. A reasonable count may be 20 new + 20 learning + 100 review. This means with 1k new cards today, assuming you learn all of them and don't reset any, you have 50 days to get all the new cards learned, 57 or so days to move all of them to review, and after that you start reviewing them. During that time, your busiest review would only be 140 cards or so. Play with those numbers based on your own experience.

Something Anki does is increase the interval based on the actual review date. So let's say I review something and the new interval is 100 days. If I don't get to it for 200 days and it's "easy" (3 or 4 or 5), should it only be modified by easiness * 100? Anki adjusts it (in my understanding) by the actual interval (not the minimum) so it'd be easiness * 200. On a really easy card that means 500 days from now, versus only 250 days if the target interval were used. An example of this being helpful, I have a Spanish deck with a lot of verbs, some I know well like "ser". If I don't study for a couple months and "ser" pops up, I know it without thinking I give it a 5 and I don't see it for a very long time. A harder verb for me like "olvidar" that I get wrong would just get reset back to 0 repetitions/smallest interval.

As a long time Anki user, I built my own SRS for a product I was involved in. I just used a basic heuristic based off my experience. It goes as follows:

1 day

3 days

1 week

2 weeks

1 month

3 months

6 months

1 year

And it works roughly as well. You add a bit of random jitter in so reviews dont pile up on the same day.

Can implement it in an afternoon

I made my own, that IMO is a lot more flexible and elegant than these heuristics/look up tables - you just store a Strength s value for each memory in your db/storage system. Then using Ebbinghaus' forgetting curve formula, given Strength S and time t since last studied, you can calculate R, and thereby have your app trigger a notification when the R value drops below a specified value. No lookup tables needed. Plus if you review something before or after the originally specified review time, the dynamic nature of the formula calculates the next best time to review the item.

Also, using the same formula you can estimate the Strength value s in the first place.

-https://en.wikipedia.org/wiki/Forgetting_curve

-https://medium.com/p/65135451e06c/ - medium article I wrote explaining the units I made up to measure a memory's Strength value.

- https://github.com/JohnSimerlink/branches_front_end_private/...

-https://github.com/JohnSimerlink/branches_front_end_private/...

^^ I have an implementation in that forgettingCurve.ts file of an app I was working on, but it's somewhat coupled with the rest of my app.

I also have a VueJs component here that let's you experience around with the 3way relationship between R, S, and t here: https://github.com/JohnSimerlink/branches_front_end_private/...

I'm too lazy to finish building the app that my implementation is in right now, but I can explain more over video chat or something - just email me john simerlink @ the most popular email provider dot com. Or linkedin

The algorithm is exponential backoff. Every item has an interval associated with it. The interval determines when you will see the item next. If you recognize the item, the interval increases geometrically by some configurable factor, like say 1.25. If you lapse, then the interval shrinks by some other configurable factor, like say 0.6.

The initial short intervals for learning new items can follow some canned pattern measured in minutes: 5, 15, 45, 60. When an item goes through the by-the-minute intervals, then it jumps to a some initial interval that is measured in days (say 1 day, so you see all the new cards again tomorrow), and after that the exponential backoff kicks in.

To make the algorithm usable, you need a strategy for lapsed items. Suppose that you lapse on an item that has a 6 month interval. It cannot be that you just see the item once, lapse on it, and then the interval is adjusted to 4 months and you do not see the item again for that 4 months. A lapsed item requires relearning. It should go through a re-learning cycle with a sequence of temporarily instituted short intervals, like 10 minutes, 20 minutes, 40 minutes. This is similar to the initial learning, but it can be less intensive: fewer reviews. Once it goes through that relearning sequence, then its regular interval (now adjusted to 4 months) kicks in, and you don't see it until then.

The learning and relearning sequences are like a ladder. When the user lapses during learning, they fall off the ladder and go back to the shortest interval. E.g. you're shown a new item. Then you see it again in 5 minutes, and again in 15, then again in 40. Oops, you forgot it; so you slide back to 5 minutes, then 15, then 40, ... you must climb it through the learning or re-learning ladder to propagate or return the item to the long-term schedule.

When re-learning a lapsed item, additional lapses during re-learning can further trim its long interval. E.g. lapse on a 6 month item, it might go to 4. Lapse on it again during re-learning, it might drop to 2.4 months.

Thanks for the help everyone.

I actually threw in the towel and just made two bins, known and unknown. I show unknown 90% of the time.

Very simple but seems to work pretty well.