Py-FSRS

repository·main·Indexed 19 days ago

https://github.com/open-spaced-repetition/py-fsrs

A Python implementation of the Free Spaced Repetition Scheduler (FSRS) algorithm. It provides core components including a Scheduler for calculating review intervals, Card and ReviewLog classes for state and history tracking, and an optional Optimizer to compute optimal model parameters and retention rates based on user review history.

Tokens
5.8K
Snippets
24
Records
26
Agent score
65%

What's inside py-fsrs

  1. Quickstart: Initialize scheduler and review a card

    main

    To use Py-FSRS, initialize a Scheduler, create a Card (which is due immediately upon creation), and use scheduler.review_card() with a Rating to update the card's state and get a ReviewLog.

    from fsrs import Scheduler, Card, Rating, ReviewLog
    
    scheduler = Scheduler()
    
    # NOTE: all new cards are due immediately upon creation
    card = Card()
    
    # Rating.Again (==1) forgot the card
    # Rating.Hard (==2) remembered the card with serious difficulty
    # Rating.Good (==3) remembered the card after a hesitation
    # Rating.Easy (==4) remembered the card easily
    rating = Rating.Good
    
    card, review_log = scheduler.review_card(card, rating)
    
    print(f"Card rated {review_log.rating} at {review_log.review_datetime}")
  2. Install and use the FSRS Optimizer

    main

    If you have a collection of ReviewLog objects, you can use the Optimizer to compute optimal model parameters and retention rates.

    1. Install the optimizer extra: pip install "fsrs[optimizer]".
    2. Initialize Optimizer with your ReviewLog objects.
    3. Use compute_optimal_parameters() to get weights.
    4. Use compute_optimal_retention() to find the best retention rate.
    5. Use reschedule_card(card, review_logs_for_that_card) to update existing cards with the new parameters.
    from fsrs import ReviewLog, Optimizer, Scheduler
    
    # load your ReviewLog objects into a list
    review_logs = [ReviewLog1, ReviewLog2, ...]
    
    # initialize the optimizer
    optimizer = Optimizer(review_logs)
    
    # compute optimized parameters
    optimal_parameters = optimizer.compute_optimal_parameters()
    
    # compute optimal retention
    optimal_retention = optimizer.compute_optimal_retention(optimal_parameters)
    
    # initialize a new scheduler with optimized values
    optimal_scheduler = Scheduler(optimal_parameters, optimal_retention)
    
    # reschedule a card using its specific history
    rescheduled_card = optimal_scheduler.reschedule_card(card, review_logs_for_that_card)
  3. Use the Py-FSRS public API

    main

    Py-FSRS is a Python implementation of the FSRS (Free Spaced Repetition Scheduler) algorithm. The library provides core classes for managing spaced repetition logic, including scheduling, card state, and review logging.

    Key components include:

    • Scheduler: The main engine for calculating review intervals and scheduling.
    • Card: Represents an individual flashcard and its current stability/difficulty.
    • Rating: An enumeration of user feedback (e.g., Again, Hard, Good, Easy).
    • ReviewLog: Records the history of reviews for a card.
    • State: Represents the current state of a card.
    • Optimizer: A module for optimizing FSRS parameters (lazy-loaded due to heavy dependencies).
    from fsrs import Scheduler, Card, Rating, ReviewLog, State, Optimizer
  4. Configure custom Scheduler parameters

    main

    You can customize the Scheduler behavior using several parameters:

    • parameters: A tuple of 21 model weights. Do not modify these unless you are optimizing FSRS.
    • desired_retention: A float between 0 and 1 (e.g., 0.9) setting the target minimum retention rate. Higher values increase review frequency.
    • learning_steps: A tuple of timedelta objects for cards in the Learning state. Default is 1 minute then 10 minutes.
    • relearning_steps: A tuple of timedelta objects for cards in the Relearning state (cards that lapsed from Review).
    • maximum_interval: An integer cap (in days) for how far in the future a card can be scheduled.
    • enable_fuzzing: A boolean that, if True, adds small random variations to calculated intervals.
    from datetime import timedelta
    
    scheduler = Scheduler(
        parameters = (0.212, 1.2931, 2.3065, 8.2956, 6.4133, 0.8334, 3.0194, 0.001, 1.8722, 0.1666, 0.796, 1.4835, 0.0614, 0.2629, 1.6483, 0.6014, 1.8729, 0.5425, 0.0912, 0.0658, 0.1542),
        desired_retention = 0.9,
        learning_steps = (timedelta(minutes=1), timedelta(minutes=10)),
        relearning_steps = (timedelta(minutes=10),),
        maximum_interval = 36500,
        enable_fuzzing = True
    )
  5. How the Scheduler manages card states

    main

    The Scheduler transitions cards through several states based on user ratings:

    1. Learning: Initial state for new cards. Uses learning_steps to progress through small intervals. Once steps are exhausted or a high rating is given, the card moves to Review.
    2. Review: The main state for long-term memory. Intervals are calculated based on stability. If a card is forgotten (Rating.Again), it moves to Relearning.
    3. Relearning: State for cards that were previously in Review but were forgotten. Uses relearning_steps to stabilize the card before returning it to the Review state.

    Intervals for Review state cards are subject to enable_fuzzing if enabled, which adds a small random variation to prevent synchronized review sessions.

  6. Optimize FSRS parameters using the Optimizer class

    main

    The Optimizer class allows you to tune FSRS scheduler parameters based on your actual review history. This enables more accurate interval calculations tailored to your specific memory patterns.

    To use the optimizer, you must provide a collection of ReviewLog objects. The optimization process uses machine learning (via torch) to minimize the difference between predicted retrievability and actual recall (where a Rating.Again is treated as a failure to recall).

    Note: The Optimizer requires optional dependencies. If they are not installed, attempting to use the class will raise an ImportError.

    Installation:

    pip install "fsrs[optimizer]"
    from fsrs.optimizer import Optimizer
    from fsrs.review_log import ReviewLog
    
    # Assuming you have a collection of ReviewLog objects
    optimizer = Optimizer(review_logs=my_review_logs)
    optimized_params = optimizer.compute_optimal_parameters()
  7. Calculate card retrievability

    main

    Use scheduler.get_card_retrievability(card) to find the current probability that a user will correctly recall a specific card.

    retrievability = scheduler.get_card_retrievability(card)
    print(f"There is a {retrievability} probability that this card is remembered.")
  8. Serialize Scheduler, Card, and ReviewLog to JSON

    main

    All core objects (Scheduler, Card, and ReviewLog) support JSON serialization and deserialization via to_json() and from_json() methods, making them suitable for database storage.

    # serialize
    scheduler_json = scheduler.to_json()
    card_json = card.to_json()
    review_log_json = review_log.to_json()
    
    # deserialize
    scheduler = Scheduler.from_json(scheduler_json)
    card = Card.from_json(card_json)
    review_log = ReviewLog.from_json(review_log_json)
  9. Reference: Card States and Ratings

    main

    Card States

    • State.Learning (==1): New card being studied for the first time.
    • State.Review (==2): Card that has "graduated" from the Learning state.
    • State.Relearning (==3): Card that has "lapsed" from the Review state.

    Ratings

    • Rating.Again (==1): Forgot the card.
    • Rating.Hard (==2): Remembered the card with serious difficulty.
    • Rating.Good (==3): Remembered the card after a hesitation.
    • Rating.Easy (==4): Remembered the card easily.
  10. Deserialize ReviewLog from dictionary or JSON

    main

    You can reconstruct a ReviewLog object from a dictionary or a JSON string using the class methods from_dict() and from_json().

    • from_dict(source_dict): Expects a ReviewLogDict containing card_id, rating (as int), review_datetime (as ISO string), and review_duration.
    • from_json(source_json): Expects a JSON string representing a ReviewLogDict.
    from fsrs.review_log import ReviewLog
    
    # From dictionary
    new_log = ReviewLog.from_dict(log_dict)
    
    # From JSON string
    new_log_from_json = ReviewLog.from_json(log_json)
  11. Initialize the FSRS Scheduler

    main

    The Scheduler class is the core of the FSRS algorithm. You can initialize it with default parameters or provide custom configurations for retention, learning/relearning steps, and maximum intervals.

    Parameters:

    • parameters: A sequence of floats representing model weights (defaults to DEFAULT_PARAMETERS).
    • desired_retention: The target retention rate (e.g., 0.9 for 90%).
    • learning_steps: A sequence of timedelta objects defining intervals for cards in the Learning state.
    • relearning_steps: A sequence of timedelta objects defining intervals for cards in the Relearning state.
    • maximum_interval: The maximum number of days a card can be scheduled into the future.
    • enable_fuzzing: Boolean to enable/disable random interval fuzzing.
    from datetime import timedelta
    from fsrs.scheduler import Scheduler
    
    scheduler = Scheduler(
        desired_retention=0.9,
        learning_steps=(timedelta(minutes=1), timedelta(minutes=10)),
        relearning_steps=(timedelta(minutes=10),),
        maximum_interval=36500,
        enable_fuzzing=True
    )