本文介绍一款专业的间隔重复(spaced repetition)记忆软件 Anki,以及从 Kindle Vocabulary Builder 导入生词到 Anki 的方法。

一、记忆与 Anki

近现代的心理学家和脑科学家们对记忆进行了不少研究。一般认为,人脑是个讲求效率的机器,会自动舍弃它认为不重要的信息。如果一份信息被大脑接收后不被使用,大脑就会认为它不重要从而舍弃它。这个过程和计算机科学中的垃圾回收(GC)挺像的——没有引用,就被删除。因此要想长久地记住一份信息,自然就是反复使用,让大脑明白这份信息是重要的,不能被舍弃。然而,人生苦短,如果每天都要使用一遍所有记忆的话,时间是不够的。于是科学家们发明了间隔重复

大脑舍弃记忆的过程并不是瞬间完成的,而是一点一点地进行,先快后慢。德国科学家 Hermann Ebbinghaus 最早系统地研究了这个规律并绘制了遗忘曲线,后人根据遗忘曲线的概念,设计了间隔重复的方法,在即将遗忘的边缘对记忆进行使用,从而达到花最少的时间,保留最多的记忆的目的。

微型计算机普及之后,一家叫 SuperMemo 的公司将上述理论做成了计算机算法,并推出了同名软件。

SuperMemo 是计算机辅助记忆的先驱,但它的专有软件并不好用。SuperMemo 的算法是公开的,于是一位叫 Damien Elmes 的程序员便根据 SuperMemo 的算法开发了自由软件 Anki。如今,Anki 已经有超过 10 年的历史,已成为计算机辅助记忆软件中事实上的标准实现。

诚然,中国作为英语学习大国,市面有无数的「背单词软件」,我也曾试用过不少,但这些应用软件大多与其内容提供商强绑定,无法定制内容且通常充满了广告。Anki 则是一个纯粹的「记忆软件」,它可以用来记忆任何东西:无论是各种外语单词、语文多音字古诗词、数理化公式、历史政治选择题,还是冷知识竞猜、看脸猜人名、看海报猜电影……你能想到的,都可以做成卡组进 Anki 进行高效记忆。

Anki 本身是个空的框架,需要用户导入记忆卡组才能使用,比起傻瓜式的「背单词软件」来说的确门槛较高,但是既然你已经决定要「学习」了,多学习一个软件的使用,也是磨刀不误砍柴工的。

二、全平台的 Anki

Anki 的作者 Damien Elmes 是个全能程序员,他是 Anki 桌面版、Web 版、iOS 版的主要开发者。Anki 的桌面版是用 PyQt 构建的,可以运行于 Windows, GNU/Linux, macOS 三大桌面平台上,也是标准实现与参考实现。AnkiWeb 提供了最简单简陋的复习和制卡功能,按作者的说法是「供在外旅行没有电脑时临时使用」。AnkiWeb 同时也是数据同步的中心以及分享 Anki 牌组和插件的平台。在开发了 FOSS 的桌面版和免费的 AnkiWeb 之后,维护 Anki 已成为 Damien Elmes 的全职工作,他也需要养家糊口,因此他决定开发 iOS 版并以 AnkiMobile 之名在 App Store 上销售。

另外有一批程序员开发了同样是 FOSS 的 Android 版,称为 AnkiDroid。以上所有版本都可以通过 AnkiWeb 进行数据同步。本文以桌面版和 AnkiDroid 为例进行说明。

三、Anki 的基本概念

设计模型

Anki 这类间隔重复记忆软件也被称为 flashcard 软件,因为它们模拟了现实生活中的 flashcard。然而 Anki 的设计模型比传统的 flashcard 实现要灵活很多。

首先,记忆内容的基本单位并不是卡片(card),而是笔记(note)。每个笔记带有多个字段(field),并属于一个笔记类型(note type),而笔记类型里则设定了卡片模板(card template),最终 Anki 根据将 note 中的数据填进 card template 里生成 card。

为什么要使用这么拗口的设计模型呢?因为这样能突破传统 flashcard「一对一」的限制,而任意实现「一对多」、「多对一」或「多对多」。比如你是一个日语初学者,正在记忆五十音,那么你的一条 note 可能是这样的:

  • Hiragana:
  • Katakana:
  • Romaji: no

这是一个三元组,记录「」这个假名的平假名、片假名和罗马字写法。你可以用这三个 field 任意组合生成卡片,比如:

  • 正面:平假名;反面:片假名 + 罗马字
  • 正面:片假名;反面:平假名 + 罗马字
  • 正面:罗马字;反面:平假名 + 片假名
  • 正面:平假名 + 片假名;反面:罗马字

排列组合是不限定的,一个 note 可以生成若干张 card。你还可以加入更多的 field,比如「Audio: [no.mp3]」加入一个音频文件,然后制作一张听写卡,或是增加一个「な行お段」然后考考自己对五十音图整体的掌握。这样方便灵活的组合能力,是传统 flashcard 所不具有的。

卡片模板

Anki 的卡片模板使用 HTML 和 CSS 进行渲染。在合适的地方使用 {{Foo}} 即可自动填入对应 note 中 Foo 字段的内容。比如要生成一张正面是平假名,反面是片假名和罗马字的卡片:

正面:

<h1>{{Hiragana}}</h1>

反面:

{{FrontSide}}
<hr>
<p>{{Katakana}} ({{Romaji}})</p>

其中 {{FrontSide}}特殊字段,用于引用正面的全部内容,这样就能在背面也显示正面的内容但却不用在模板里重复一遍了。

新安装的 Anki 里自带几个简单的 note type / card template,可以在此基础上稍做修改,也可以自己建立 note type / card template,发挥 HTML 与 CSS 的力量,制作自己喜欢的样式。

记忆周期

每个卡片的集合被称为卡组(deck)。每个卡组可以自定义记忆周期。默认的记忆周期分为 learning, relearning, graduating, young, mature 等多种(有重合)的阶段。

每张卡在不同的周期出现时,根据之前的回答情况,会有 1 个否定按钮(Again),和 1 至 3 个肯定按钮(Hard, Good, Easy)。选择否定按钮会降低卡片的简易系数(ease)并安排一次就近的复习,选择肯定按钮代表你记得这张卡,Anki 会根据这张卡当前的 ease 计算下一次复习时间,并进一步调整这张卡片的 ease。

总结:记得住的卡 ease 会越来越高;记不住的卡会频繁地出现;简单的卡如果忘记了会被调低 ease。

Anki 的整体设计还是很有趣的,推荐感兴趣的读者阅读它的完整文档

四、从 Kindle Vocabulary Builder 导入 Anki

虽然 AnkiWeb 上有很多 Anki 用户共享的卡组,用来记忆五十音、元素周期表等简单的内容已经足够,但是,要想高效地利用 Anki,还是需要自己建立卡组。现代人每天都在吸收大量信息,遇到不懂的地方随手创建一条 Anki note 是个不错的习惯。AnkiConnect 是一个 Anki 的插件,可以使桌面版的 Anki 成为一个 RESTful API 服务器,方便各种浏览器扩展「划词」添加 note 到 Anki 里。安装了 AnkiDroid 之后,手机的分享菜单也会多一条,可以在其他应用里快速创建 Anki note,然后同步到电脑再进行进一步编辑和整理。

这里我要着重介绍的是从 Kindle Vocabulary Builder 导入。事实上这也是我开始使用 Anki 的契机之一。

Kindle Vocabulary Builder 是个很棒的语料收集器。在你阅读的时候每次查字典,它都会默默地把被查询词汇记录下来,之后你可以随时进入 Kindle Vocabulary Builder 复习这些词汇,并且这些词汇都是同步到 Amazon 账户的,可以在多台设备之间同步。然而,它只有「Learning」和「Mastered」两个熟练程度,实在是不堪重用,因此我选择将它们导入 Anki 进行复习。

Kindle Vocabulary Builder 所有的信息都存在 /system/vocabulary/vocab.db 文件里。这是一个 SQLite3 数据库,包含了被查询词汇所在句子、书籍,以及查询时间。值得一提的是,查询时间在 Vocabulary Builder 的 UI 里是看不到的,但是的确在数据库中存在。我发现最夸张的单词,从 2015 年到 2018 年在不同的书里被我查询了 6 次——但是我依然没有记住它。可见被动学习(passive study)效率实在不高,还要用 Anki 这样的主动回忆(active recall)和间隔重复软件比较靠谱。

vocab.db 里并没有保存字典释义,因此想到达到和 Vocabulary Builder 一样的「单词 + 例句 + 释义」三元组,我们还需要把 Kindle 中所用的字典拉过来协助。

我写了两个简单的脚本来做这些事:

  1. 安装 requirements.txt 中的依赖。
  2. Kindle 自带的字典是带 DRM 的,需要先用 DeDRM Tools 扒掉 DRM。如果你使用的字典没有 DRM,此步跳过。
  3. Kindle 字典是 MOBI 格式,需要用 KindleUnpack 将其拆解成方便读取的 HTML 文件。
  4. 使用 convert_dict.py 脚本,对 HTML 字典进行解析,转换成简单的 TSV 文件。
  5. 使用 convert_vocab.py 脚本,将 vocab.db 中的数据取出、处理,配上字典里的释义,导出成一行一条的 Anki note。

更新:关于 Kindle 字典的格式与技术细节,请阅读《使用 dictd 搭建 DICT 字典服务器 § 转换 Kindle 字典

最终生成的文件是个三列的 TSV,分别是 Word, Usage, Definition。其中 Usage 列包含了这个词所有被记录到查询,因此如果一个词被查了多次的话,会有多个例句。

在 Anki 中新建一个 note type,包含 Word, Usage, Definition 这三个 fields,参考如下 template:

正面:

<h1>{{Word}}</h1>
<hr>
{{Usage}}

反面:

{{FrontSide}}
<hr>
{{Definition}}

样式:

h1 {
 text-align: center;
}
blockquote small:before {
 content: " -- ";
}

然后将生成的 TSV 文件导入进 Anki,由于 Usage 和 Definition 列是 HTML,导入时记得勾选「Allow HTML in fields」。

附一张最终 AnkiDroid 渲染效果与 Kindle Vocabulary Builder 对比图:

kindle-vocab-vs-ankidroid_1000px

本文地址: https://wzyboy.im/post/1223.html


读者来信

2018-06-03 读者明晓阅读本文之后吐露了她在英文学习中的困惑,经读者授权摘录如下:

[...]

所以我也只能分享一下我对记单词 学英语的经历和困惑啦。

毕业后其实我平时用不上英文,但是又并不想放弃,我试过记单词书,用APP,听VOA,听英语电台,尝试读英文书,薄荷阅读,听BEC网课 等方式去学,当然还有 英语角 和 教堂、Bible Study。前段时间试图通过背诵 新概念4的课文的形式 去学习语法 以及 背单词,但是因为 个人懒惰、时间安排、优先级等因素 目前也暂停,最近也是 在想 能通过什么有效可行的方式去再一次提上日程。

不可否认我觉得记单词是 学习英语过程中必要基石,但它也无聊 枯燥。遗忘曲线或者说记忆曲线 这种说法 其实并不新鲜,自己建立Note 而不是直接参照 规定的内容 去记忆 其实我也不是第一次接触,自建Note 其实会存在 自身筛选信息和判断的过程,虽然说它可能因为更深的交互和参与 让记忆更加深刻,但是它会因为 使用者的英文水平 而在 效率 和 效果 上有较大的不同。而且,同样是 用了 记忆曲线的 原理,比如 贝壳单词 还是 什么的APP里 会让你自己的判断“你还记不记得这个单词”,这里,其实可能会有 自欺欺人的 情形出现。

而且我现阶段的状态,或者说 为什么我前段时间选择通过 文章的方式 去 学习,是因为,我已经有点不信任单个单独单词的记忆的方式了,无聊不说,它的使用场景和没那么生动形象,也容易忘掉。但我同时也有个 工作几年又重新考研的师兄,说就是 刻苦的死记硬背的方式,也让他顺利 通过了 研究生的考试。

还是那个说法,工作以后,因为 优先级 和 合适方法(这里就包括了与自身懒惰的对抗)的问题,还是蛮困扰我的英语学习之路的,不知道怎样的方法更适合自己。我一开始觉得 我还是非常想 工作几年之后再出去读个研什么的,但是现在也是不知道了,所以学习英语 到底是为了去外企、去留学、还是只是日常使用(也并没有日常使用) 或是 纯碎自我满足 我也是不知道了,只是一直不断试错。

BTW 大概一年前 我很想 把 Out of Africa 看完,写读完,是真的读,录到 喜马拉雅APP里或者怎么样都好,但是我可能 两页 就要停下来查不知道多少个单词,但是文章真的感觉很美,我也蛮喜欢 朗读 的感觉,就是这种 既没有放弃 又没有继续的感觉…

[...]

对此,我的回应是:

首先,有关记忆方法的问题。诚然,不同方法对不同人效果不同,有些人可能要图片 + 助记词才能记住,但有些人就对着枯燥的释义就能记住了。但 IMHO 这只是效率问题,哪怕是不比较依赖助记词的人用简单的 flashcard 也是能记住东西的,但可能留存率(retention rate)较低。这方面 Anki 是有专门的考虑的,那就是如果它发现一个词反复被忘记(被称为 leech),会自动挂起(suspend),不再向你展示。所以,可以先用字典释义做成简单的 flashcard,积累了一些的 leeches 之后,再对这些「老大难」进行单独的处理,比如专门为它们编写助记词,或是干脆删掉不记了,把时间和精力留给别的。

其次,阅读方法的问题。虽然我也偶尔看纸书,但其实我看的大部分英文书都是电子书。电子书的最大好处还是方便,「哪里不会点哪里」,Kindle 甚至有功能,直接把生僻单词的简短释义像振假名一样标注在上面,连长按查字典都免了。这样的阅读体验,在阅读词汇量要求较高的图书时,效果非常好。同时,正如我文章里说的,Kindle 里查的单词导入 Anki 之后是有例句的,事后记忆的时候能回想起当时所在的书和句子,也是一种很好的助记。

最后,习惯问题。每天记单词其实就和日记一样吧,开始一段时间可能会比较难,经常会断,但是一旦养成习惯之后到点了自然就会想起来了。至于目的?并不用考虑这是为了外企还是为了留学,你的内心知道这是对自己有益的,去挑战就行了嘛。有个电影叫 Everest,里面提过,有人问登山家「为什么要登山」,登山家回答「因为山就在那里」。

既然说到枯燥释义的问题,也就顺便说一下:对我来说这样用 Kindle 收集带语境的生词(在复习时能看到我是在哪本书的哪句话里遇到这个单词的),然后在每日复习中慢慢消化吸收挺好的。但如果你需要「为了背单词而背单词」,比如备考 GRE 等,这时候就只能制作不带语境的 Anki note 了,一个弥补方案是使用带例句的英汉双解字典作为释义源。网上流传的词汇表往往只是每个词头配一个简短的释义,并不利于真正掌握这个单词的用法;使用带例句的双解字典多少能弥补一些缺少语境的不足。

在此贴上一份我制作的 GRE 词汇表,供导入 Anki 使用:gre_anki.zip

词头来自网络流传的多份 GRE 词汇表的合并与去重,共 8255 条;释义来自《牛津高阶英汉双解字典(第 7 版)》。


欢迎留下评论。评论前,请先阅读《隐私声明》。