一个客户要求我为一个基于在线的学习站点添加一个简单的间隔重复算法(SRS)。但在我投入到其中之前,我想和社区讨论一下。
基本上,网站会问用户一大堆问题(从数据库中自动选择100个问题中的10个),用户给出的答案要么正确,要么不正确。然后将用户结果存储在数据库中,例如:
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算法,这样用户下次参加测试时,会更经常地收到错误回答的问题;而不是正确回答的问题。同样,以前被错误回答的问题,但最近经常被正确回答的问题应该少发生。
以前有人实施过这样的计划吗?有什么建议吗?
这是我发现的最好的链接:
发布于 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。
更新:实际上,您应该根据纠正而不是错误来建立数据基础。否则,很长一段时间没有回答正确或错误的问题,被选中的机会就会更小。应该是相反的。
发布于 2010-06-03 09:38:13
发布于 2020-08-08 10:05:47
这里是一个间隔重复算法,这是很好的记录和易于理解。
特性
https://github.com/Jakobovski/SaneMemo。
免责声明:我是SaneMemo的作者。
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)https://stackoverflow.com/questions/2964526
复制相似问题