小土刀

一个满怀热爱的手艺人。无论是文字还是代码,我都想写点不一样的。

SuperMemo与Anki算法研究与探索

SuperMemo是非常著名的记忆辅助工具,自1985年面世以来,历经近二十年的发展,从最初的SM-0算法一直进化到了最近的SM-15算法。之前提到我想做一个背单词应用,首先要面对的问题就是要选择什么算法来进行记忆的规划。SuperMemo早期的算法是开源的,但是2005年之后近十年的算法已经不公开了,当然即使公开了,我也用不上。因为从SM-5之后,算法的复杂度基本已经突破我的极限,所以这里主要研究的是SM-2与SM-5以及Anki的算法,并试图从中找到最适合自己的方式。

之前提到的三种算法,都有一个非常严重的问题,就是不会考虑推迟复习的情况,比方说中间暂停一天,算法就整个乱掉了。这在我看来是不实用的,因为没有理由像上班打卡一样有如此严格的限制。2005年之后SM的算法在这方面有了改进,不过具体的思路无从所知。

但是有一点是确定的,就是SM在这上面有些跑偏了,即使是考虑了延迟,究其根本,仍然是计算时间,基本上忽略了时间碎片化的现状。为了得到更精确的时间使用神马神经网络机器学习这些听起来高大上的技术,依然没有办法解决用户最直接的问题:我每次只能看一小段时间,这怎么办?

而Anki则是基于SM-2算法的,所以我们先把这些问题放一放,来看看SM-2算法具体是怎么个思路。

  • SuperMemo 2算法

1987年12月使用Turbo Pascal 3.0 / IBM PC编写完成,主要是在以下两个方面增强SuperMemo算法:

  1. 把优化的过程应用到可能的最小单位(之前的算法的单位是item组成的page)

  2. 根据item的不同的难度等级来进行区分

观察到复习的时间间隔接近于某个常数,所以决定使用以下公式

I(1):=1

I(2):=6

for n>2 I(n):=I(n-1)*EF

其中

I(n) - inter-repetition interval after the n-th repetition (in days)

EF - easiness factor, 表示记忆某个item的难度,后面称为E-Factor

E-Factor的范围是1.1~2.5,其中1.1是最难,2.5是最简单。当一个新的item进入SuperMemo数据库时,它的E-Factor为2.5。在不断重复的过程中,这个值将会不断减少。因此一个单词记忆的时候用户的记忆度越低,那么它的E-Factor就会下降越多。

注意!SuperMemo的机制,实际上是认为,一个item入库的时候用户已经是记住的,这与背单词不一样,千万注意!另一种做法是一开始默认用户都不会,也就是初始值为1.1,然后在不断学习的过程中递增这个数值)

后来发现E-Factor不应该低于1.3。如果低于这个数值,那么就以恼人的频率出现,看起来是公式有内在的缺陷,所以保证E-Factor不低于1.3就成了下一步改进的方向。

为了得到新的E-Factor,就需要引入用户对于问题回答的评价,也就是0-5的评分机制,新的公式为:

EF’:=f(EF,q)

其中

EF’ - E-Factor的新值

EF - E-Factor的旧值

q - 评价的分数

f - 用来计算EF’的函数

f函数原来比较复杂,经过多方考虑和改进之后,最后的形式是这样的

EF’:=EF-0.8+0.28*q-0.02*q*q (画一下函数图像)

而原来的公式是:

EF’:=EF+(0.1-(5-q)*(0.08+(5-q)*0.02))

注意当q=4时,E-Factor将不会改变

  • Anki的算法

Anki的算法基于SM2,但是在下列方面有不同:

  1. SM2定义的初始间隔是1天,然后就是6天。但是在Anki中,这个时间是可以自定义的。Anki知道在你能记住一张新卡片之前可能需要多次的查看,所以那些一开始的记忆错误并不意味着你会在接下来的几天里总是要看到那些卡片。也就是说,学习阶段的表现并不会影响到记忆阶段。

  2. 对于每张卡片,Anki给出的评级是4种,而不是SM2中的六种,并且只有一个选项是fail的情况。之所以这样做,是因为记忆错误的总体来说一定是占少数的,那么更重要的是区分。

  3. 回答卡片的时间超出预计也会被考虑在这张卡片下次出现的间隔计算中,也就是说,那些你记得但是回答晚的,会有一定的出现频率的提高。

  4. 与SM2相似,Anki的failure 按键会把卡片的出现间隔重设为默认,但是用户可以让其回到过往的某一状态而不是完全回到起点。同时你也可以在第二天再看那些没有记住的卡片,而不是当天。

  5. 如果选择了已经记住这个状态,不仅仅会增加ease factor,还会增加下一次出现的时间间隔,这样的策略会比SM2更加激进一些。

  6. 在学习某张卡片的阶段时连续的failure不会让卡片的ease factor进一步降低。标准的SM算法一个备遭诟病的地方就是连续错误会让某张卡片掉入“短间隔地狱”,反复出现。在Anki中,这种问题得到了有效解决。

Anki在各个方面表现似乎不错,但是有一个问题,就是复习的时间是按照小时来计划的,而不是按天来,但是很多研究结果表明(其实大家应该自己也有感觉),就是睡一觉才能记得牢,所以我认为按天来是比较好的方式。

另外无论是SM还是Anki的算法,用于反馈的选项都太多了,SM有6个,而Anki有4个,很多时候其实自己都很难区分到底属于哪个级别,所以这里扇贝只使用“认识”和“不认识”作为区分,我觉得反而是最好的,至于具体的难度,应该根据不同单词提示的信息多寡来决定。

这就引出了另一个新的特性:三面卡组。意识就是,原来的卡片基本上就是两面,一面是词汇,一面是释义,但是为什么不能在这之间加上另一个面——提示呢?这样如果在看提示的时候(这里可能是词根)就想起来了这个单词,就可以把原本简单的“认识”,根据用户的操作,划分出不同的掌握等级。

  • 算法的设计目标

前面说了这么多,基本上也已经可以做出选择了,也就是基于SM-2算法,结合Anki的改进,加上一些新特性,组成这个背单词应用的算法核心。总体来说有需要满足以下几点:

  1. 不限制每天的单词复习数量

  2. 使用遗忘曲线来应付中间暂停复习的情况(具体的曲线还需要调研)

  3. 至多接受三种类型的输入(记得,不记得,和某种中间状态)

  4. 三面卡组

大概就是这些,最近数据源已经准备完成,但是把mac搞挂了,等恢复过来了,再继续吧。


评论(2)
热度(17)

© 小土刀 | Powered by LOFTER