首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >间隔重复用于学习

间隔重复用于学习
EN

Stack Overflow用户
提问于 2010-06-03 09:05:30
回答 3查看 6.3K关注 0票数 18

一个客户要求我为一个基于在线的学习站点添加一个简单的间隔重复算法(SRS)。但在我投入到其中之前,我想和社区讨论一下。

基本上,网站会问用户一大堆问题(从数据库中自动选择100个问题中的10个),用户给出的答案要么正确,要么不正确。然后将用户结果存储在数据库中,例如:

代码语言:javascript
复制
userid  questionid  correctlyanswered  dateanswered
1       123         0 (no)             2010-01-01 10:00
1       124         1 (yes)            2010-01-01 11:00
1       125         1 (yes)            2010-01-01 12:00    

现在,为了最大限度地提高用户学习所有答案的能力,我应该能够应用SRS算法,这样用户下次参加测试时,会更经常地收到错误回答的问题;而不是正确回答的问题。同样,以前被错误回答的问题,但最近经常被正确回答的问题应该少发生。

以前有人实施过这样的计划吗?有什么建议吗?

这是我发现的最好的链接:

  • 重复
  • http://www.mnemosyne-proj.org/principles.php
  • http://www.supermemo.com/english/ol/sm2.htm
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-06-03 10:02:30

您想要做的是为所有的问题( X_i )设置一个数字i。你可以规范这些数字(使它们的和1),并用相应的概率随机选择一个。

如果N是不同问题的数量,M是每个问题平均回答的次数,那么您可以在M*N time中找到X,如下所示:

  • 将数组X[N]设置为0。
  • 运行数据,每次您看到问题i回答错误时,增加N[i] by f(t),其中t是应答时间,f是一个递增的函数。

由于f在增加,一个很久以前回答错的问题比昨天回答错的问题的影响要小。您可以尝试不同的f,以获得一个良好的行为。

----一种更快的方法不是每次选择问题时都生成X[],而是将其保存在数据库表中。您将无法使用此解决方案应用f。相反,只要每次问题被错误回答时加1,然后定期浏览表格--比如每到午夜--然后把所有的X[i]乘以一个常数--比如0.9

更新:实际上,您应该根据纠正而不是错误来建立数据基础。否则,很长一段时间没有回答正确或错误的问题,被选中的机会就会更小。应该是相反的。

票数 8
EN

Stack Overflow用户

发布于 2010-06-03 09:38:13

安基是一个实现间隔重复的开源程序。作为开放源码,您可以浏览利班基的源代码,这是Anki的一个间隔重复库。截至2013年1月,Anki 2源代码可以浏览这里

源代码是用可执行的伪代码语言Python编写的。读取源来理解该算法可能是可行的。数据模型是使用sqlalechmey、Python工具包和定义的,这给了应用程序开发人员充分的能力和灵活性。

票数 8
EN

Stack Overflow用户

发布于 2020-08-08 10:05:47

这里是一个间隔重复算法,这是很好的记录和易于理解。

特性

  • 引入子甲板,有效地学习大型甲板(超级有用!)
  • 直观的变量名和算法参数。完全开放源代码与人类可读的例子。
  • 容易配置的参数,以适应不同用户的记忆能力。
  • 计算成本低计算下一张卡。不需要在甲板上的每一张卡片上进行计算。

https://github.com/Jakobovski/SaneMemo

免责声明:我是SaneMemo的作者。

代码语言:javascript
复制
import random
import datetime

# The number of times needed for the user to get the card correct(EASY) consecutively before removing the card from
# the current sub_deck.
CONSECUTIVE_CORRECT_TO_REMOVE_FROM_SUBDECK_WHEN_KNOWN = 2
CONSECUTIVE_CORRECT_TO_REMOVE_FROM_SUBDECK_WHEN_WILL_FORGET = 3

# The number of cards in the sub-deck
SUBDECK_SIZE = 15
REMINDER_RATE = 1.6

class Deck(object):

    def __init__(self):
        self.cards = []

        # Used to make sure we don't display the same card twice
        self.last_card = None

    def add_card(self, card):
        self.cards.append(card)

    def get_next_card(self):
        self.cards = sorted(self.cards)  # Sorted by next_practice_time
        sub_deck = self.cards[0:min(SUBDECK_SIZE, len(self.cards))]
        card = random.choice(sub_deck)

        # In case card == last card lets select again. We don't want to show the same card two times in a row.
        while card == self.last_card:
            card = random.choice(sub_deck)

        self.last_card = card
        return card


class Card(object):

    def __init__(self, front, back):
        self.front = front
        self.back = back

        self.next_practice_time = datetime.utc.now()
        self.consecutive_correct_answer = 0
        self.last_time_easy = datetime.utc.now()

    def update(self, performance_str):
        """ Updates the card after the user has seen it and answered how difficult it was. The user can provide one of
        three options: [I_KNOW, KNOW_BUT_WILL_FORGET, DONT_KNOW].
        """

        if performance_str == "KNOW_IT":
            self.consecutive_correct_answer += 1

            if self.consecutive_correct_answer >= CONSECUTIVE_CORRECT_TO_REMOVE_FROM_SUBDECK_WHEN_KNOWN:
                days_since_last_easy = (datetime.utc.now() - self.last_time_easy).days
                days_to_next_review = (days_since_last_easy + 2) * REMINDER_RATE
                self.next_practice_time = datetime.utc.now() + datetime.time(days=days_to_next_review)
                self.last_time_easy = datetime.utc.now()
            else:
                self.next_practice_time = datetime.utc.now()

        elif performance_str == "KNOW_BUT_WILL_FORGET":
            self.consecutive_correct_answer += 1

            if self.consecutive_correct_answer >= CONSECUTIVE_CORRECT_TO_REMOVE_FROM_SUBDECK_WHEN_WILL_FORGET:
                self.next_practice_time = datetime.utc.now() + datetime.time(days=1)
            else:
                self.next_practice_time = datetime.utc.now()

        elif performance_str == "DONT_KNOW":
            self.consecutive_correct_answer = 0
            self.next_practice_time = datetime.utc.now()

    def __cmp__(self, other):
        """Comparator or sorting cards by next_practice_time"""
        if hasattr(other, 'next_practice_time'):
            return self.number.__cmp__(other.next_practice_time)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2964526

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档