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] How can I set the parameters in a way which can make the prediction closer to Anki's #150

Open
arungeorgesaji opened this issue Feb 23, 2025 · 4 comments

Comments

@arungeorgesaji
Copy link

arungeorgesaji commented Feb 23, 2025

Right now this is what I have,so basically it sets the new values to the same as ankis and I set the same default weights aswell and if I continuosly press good 3 times it seems like maxes the time out there and then it just procceeds to change around only because fuzziness is turned on in anki it keeps increasing. and values changes for each rating keeps changing...How can I adjust the parameters to have a closer to result to that of anki am I doing something wrong??

import { fsrs, generatorParameters, Rating } from 'ts-fsrs';

export function initializeFSRS() {
    const params = generatorParameters({ 
        enable_fuzz: true, 
        request_retention: 0.9,
        maximum_interval: 36500,
        w: [0.4026, 1.1839, 3.1730, 15.6910, 7.1949, 0.5345, 1.4604, 0.0046, 1.5458, 0.1192, 1.0193, 1.9395, 0.1100, 0.2961, 2.2698, 0.2315, 2.9898, 0.5166, 0.6621],
        enable_short_term: true, 
    });
    return fsrs(params);
}


export function updateCard(scheduling, card, rating) {
    if (scheduling) {
        const { card: updatedCard } = scheduling;
        if (card.state == 0) {
            const now = new Date();

            switch (rating) {
                case 1:
                    updatedCard.due = new Date(now.getTime() + 1 * 60 * 1000); 
                    break;
                case 2:
                    updatedCard.due = new Date(now.getTime() + 6 * 60 * 1000); 
                    break;
                case 3:
                    updatedCard.due = new Date(now.getTime() + 10 * 60 * 1000); 
                    break;
                case 4:
                    updatedCard.due = new Date(now.getTime() + 13 * 24 * 60 * 60 * 1000); 
                    break;
                default:
                    console.error("Invalid rating:", rating);
                    return;
            }
        }
        Object.assign(card, updatedCard); 
    }
}

export function processCard(f, card, rating) {
    const scheduling = f.next(card, new Date(), rating);
    updateCard(scheduling, card, rating);
}

export function getCardInterval(f, card, rating) {
    const scheduling = f.next(card, new Date(), rating);

    const intervals = {
        1: "1 minutes",      
        2: "6 minutes",  
        3: "10 minutes",     
        4: "13 days",
    };

    if (card.state == 0) {
        return intervals[rating] || "Unknown";
    }
    
    if (!scheduling) {
        console.error("No scheduling found for rating:", rating);
        return "Unknown";
    }

    const newDueDate = new Date(scheduling.card.due);
    const now = new Date();
    const intervalSeconds = (newDueDate - now) / 1000; 

    if (intervalSeconds < 3600) {
        return `${Math.round(intervalSeconds / 60)} minutes`;
    } else if (intervalSeconds < 86400) {
        return `${Math.round(intervalSeconds / 3600)} hours`;
    } else {
        return `${Math.round(intervalSeconds / 86400)} days`;
    }
}
@ishiko732
Copy link
Collaborator

ishiko732 commented Feb 23, 2025

There are three differences:

@arungeorgesaji
Copy link
Author

Thanks for the info.

@Math-Vieira
Copy link

Hey man, can you help me?
How can I change the first value of each review option?
I mean, they start like this:
again: 1 min
hard: 5 min
good: 10 min
easy: 2 weeks

How can I change the last one to a value that I assume is more correct?

@ishiko732
Copy link
Collaborator

ishiko732 commented Mar 10, 2025

Hey man, can you help me? How can I change the first value of each review option? I mean, they start like this: again: 1 min hard: 5 min good: 10 min easy: 2 weeks

How can I change the last one to a value that I assume is more correct?

There are currently no configurable parameters, but you can handle it using afterHandler.

Note: easy should not be less than 1 day.

example: (online: https://jsfiddle.net/ishiko/9vmgdys8/2)

import { createEmptyCard, fsrs, Grade, Rating, RecordLogItem, State } from 'ts-fsrs'

const learningSteps: Map<Grade, number> = new Map([
  [Rating.Again, 10 /** min */],
  [Rating.Hard, 30 /** min */],
  [Rating.Good, 60 /** min */],
])

const relearningSteps: Map<Grade, number> = new Map([
  [Rating.Again, 30 /** min */],
  [Rating.Hard, 60 /** min */],
])

function changeStep(item: RecordLogItem) {
  const grade = item.log.rating as Grade
  if (item.card.state === State.Learning) {
    const review: Date = new Date(item.card.last_review!)
    review.setTime(review.getTime() + learningSteps.get(grade)! * 60 * 1000)
    item.card.due = review
  } else if (item.card.state === State.Relearning && relearningSteps.has(grade)) {
    const review: Date = new Date(item.card.last_review!)
    review.setTime(review.getTime() + relearningSteps.get(grade)! * 60 * 1000)
    item.card.due = review
  }

  return item
}

const f = fsrs()
const now = new Date('2025-03-10T00:00:00.000Z')
const card = createEmptyCard(now)
const grade = Rating.Easy
const items_change_step = f.next(card, now, grade, changeStep)

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

No branches or pull requests

3 participants