Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Decrease difficulty without pressing Easy? (Ease hell/Difficulty hell) #33

Closed
kuroahna opened this issue Sep 26, 2022 · 1 comment · Fixed by #35
Closed
Labels
question Further information is requested

Comments

@kuroahna
Copy link

kuroahna commented Sep 26, 2022

I've been playing around with the new update to fsrs4anki_optimizer version v1.6.1 and I love being able to see the rating_history, interval_history and difficulty_history.

One thing I noticed is that if you press Again (1), the difficulty will increase, and when you press Good (3), the difficulty stays the same. Only when you press Easy (4) the difficulty will decrease.

However, I use Anki slightly differently from most users. I only press Again (1) and Good (3). I never press Hard (2) or Easy (4). This means my grading style is binary (Pass or Fail). This is because it is much easier for me (less cognitively taxing) to grade my cards on a binary system; either I know the card or I don't know it, no in-between. But this also means that the difficulty for a card will always be the same. If I keep pressing Again (1), the difficulty will always increase, but never be able to decrease. This means that the intervals will be very short.

For example, with settings:

defaultDifficulty = 1.1873
defaultStability = 3.6988
difficultyDecay = -0.9949
stabilityDecay = -0.1412
retrievabilityFactor = 1.2742
increaseFactor = 2.9295
lapsesBase = -0.062

requestRetention = 0.9  # recommended setting: 0.8 ~ 0.9
easyBonus = 1.3
hardInterval = 1.2

test_rating_sequence = "3,1,3,1,3,1,3,3,3,3,3,3,3,3"

OUTPUT

rating history: 3,1,3,3,1,3,3,3,1,3,3,3,3,3
interval history: 0,4,4,8,15,3,6,10,17,3,5,8,12,18,27
difficulty history: 0,1.2,1.9,1.9,1.9,2.7,2.7,2.7,2.7,3.4,3.4,3.4,3.4,3.4,3.4

This is something known as "Ease hell" in the Anki community. Pressing Again (1) in Anki SM-2 will decrease the ease factor by 20%, pressing Hard (2) will decrease the ease factor by 15%, pressing Good will leave the ease factor the same, and pressing Easy will increase the ease factor by 15%. So we have the same behaviour in Anki SM-2. If we press Again (1) and Good (3) only, the ease factor will always decrease and never increase again since we don't press Easy (4). This means that the intervals will grow really slow if the ease factor stays around <=150%

I currently solve this issue by using an Anki Addon called Straight Reward which simply increases the ease factor if you press Good or Easy after X consecutive times (some Anki users use Auto Ease Factor addon instead to solve this issue). Here are my settings

image

This means that after pressing Good 3 times in a row, the ease factor will increase by 5%. And if I press Good 5 times in a row, it will increase by 5% + 5% * (5 - 3) = 15%, with an upper limit of 250% ease. This means that the card has a chance to regain its ease factor as long as I keep pressing Good consecutively.

I'm looking at the fsrs4anki_scheduler.js code and I see that there is some calculation here for the difficulty:

    const interval = states.current.normal?.review.elapsedDays ? states.current.normal.review.elapsedDays : states.current.filtered.rescheduling.originalState.review.elapsedDays;
    const last_d = customData.again.d;
    const last_s = customData.again.s;
    const retrievability = Math.exp(Math.log(0.9) * interval / last_s);
...
    customData.good.d = constrain_difficulty(last_d + retrievability - 1 + 0.1);
    customData.good.s = next_stability(customData.good.d, last_s, retrievability);

Correct me if I'm wrong, but it seems like pressing Good will decrease difficulty, but this doesn't seem to be the case in the fsrs4anki_optimizer. EDIT: Nevermind, it seems like interval = elapsedDays. I assume that's how many days has passed since the scheduled interval. For example, if the scheduledDays = 10 and 10 days has passed where I'm given the card by Anki, then elapsedDays=0. Otherwise, if 11 days has passed, and I finally review the card, then elapsedDays=1? If this is the case, then retrievability = e^(ln(0.9) * 0 / x) = 1 since I will always review cards every day and not miss a day. Then customData.good.d = constrain_difficulty(last_d + retrievability - 1 + 0.1) = constrain_difficulty(last_d + 1 - 1 + 0.1) = constrain_difficulty(last_d + 0.1) Seems like difficulty will always increase by 0.1 by pressing good. I feel like my math is wrong here... The optimizer doesn't change the difficulty at all when pressing good

If pressing Good (3) will never decrease the difficulty, even after consecutively pressing Good a few times, is it expected that we use the Easy button using fsrs4anki then? I don't expect the fsrs4anki algorithm to change to fit my use case, I'm open for new ideas, but I'm curious about the behaviour here and I'm interested in seeing how fsrs4anki handles this.

I also realize there is an issue with using Anki SM-2 + Straight Reward + Again/Good only solution. For mature cards, if ease factor is 250%, this means that the interval grows really fast (say, 365 days * 2.5 = 913 days). This is probably not the best interval for such a mature card. It'll be more likely that I forget this card and have to relearn it (This is probably the reason why I have 81.9% mature card retention rate, since the intervals are too large. My young card retention rate is ~88.2%). Using fsrs4anki algorithm, I get intervals:

first rating: 3
rating history: 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
interval history: 0,4,10,25,56,119,240,460,845,1493,2551,4227,6812,10707,16451,24757
difficulty history: 0,1.2,1.2,1.2,1.2,1.2,1.2,1.2,1.2,1.2,1.2,1.2,1.2,1.2,1.2,1.2

where the change between each interval is

0 -> 4 = N/A
4 -> 10 = 10 / 4 = 2.5 = 250%
10 -> 25 = 25 / 10 = 2.5 = 250%
25 -> 56 = 56/ 25 = 2.24 = 224%
56 -> 119 = 119 / 56 = 2.125 = 212.5%
119 -> 240 = 240 / 119 = 2.017 = 201.7%
...

This shows that the change between each interval starts at 250% then decreases slowly as the card keeps maturing. This makes a lot of sense to me since the next optimal interval for a mature card probably doesn't increase as fast as 250% anymore compared to a young card.

@L-M-Sherlock
Copy link
Member

L-M-Sherlock commented Sep 27, 2022

I'm working on the updating function of difficulty. It is still heuristic and magic. But I think I will figure it out.

And for the ease hell problem. It is difficult for the algorithm to determine if the interval is too long or too less if you only use again and good. Maybe I need to add mean reversion to the difficulty updating function for this case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants