使用R语言文本挖掘技术应对英语考试的粗浅想法及其他
学习与考试
学习是由经验引起的相对持久的变化,而考试,一方面是对习得的知识与技能的掌握情况的测试,另一方面也是对能否进入下一阶段学习或工作的考核。虽然学习能力受个人的智力水平以及学习方法的影响,但一般而言,学习是没有捷径的;但考试却不一样,在应付考试的时候,确实存在一些捷径可走。且以我个人的经历举三个例子。
高中的时候,我的立体几何学得不是很好,对于如何解立体几何大题完全摸不着门路。然而有一天,我在一本辅导书中看到一种用空间向量解立体几何大题的方法,而且相当简单易学,做了几道类似的题,我就掌握了这个方法。随后在整个高中阶段,我就靠着这一捷径,在并不具备足够的立体几何知识的前提下做到了立体几何大题从来不丢分。
我本科是自考的英语专业,其中有一门课,叫《英美文学选读》。这门课应该是所有20多门课中最有价值的一门,同时也是最难的一门。教材中介绍了英国与美国的70多位著名的作家以及他们的代表作。我第一次没能考过,因为内容实在是太多了,不好把握重点。后来,我找了几份历年的真题,看过之后才发现,原来70多位作者当中,只有30多位会在考试中考到,这一下就把任务量缩减了一半。虽然难度还是挺大的,但第二次终于顺便通过了。我又一次找到了考试的捷径,同时也第一次意识到真题对于考试的重要性。
拿到本科毕业证之后,我就开始着手考研。专业课所涉及的内容不可谓不多,如果想全面的复习,时间肯定不够,只能有所侧重的进行复习。有了先前的经验,我开始反复地研究真题。哪些知识点会以选择题的形式考察,哪些知识点会以大题的形式考察,哪些部分的内容考试从来不涉及,可以忽略,哪些部分的内容频繁考到,必须重点记忆?经过反复地分析,我根据真题总结出了一份比较精简的笔记,并在考试中拿到了一个还算满意的分数。如果仅仅按大纲来复习的话,肯定会浪费很多时间。
从我个人经历来看,考试确实是有捷径可循,而这个捷径往往跟历年的真题有关。但是对于大部分考试来说,可用于分析的样本量太低,而且找不到客观的指标,只能通过自己的主观判断,因此在知识点的选取上难免会有一些偏差。但有一门考试却不存在这两个问题,既有足够大的样本量可供分析,又能产生客观的指标。很明显,这门考试就是大家“喜闻乐见”英语考试。
上大学之前,语数外三科同等重要;而上大学之后,大多数专业应该都不用学语文了,文科的一般也不用学数学了,只有英语,坚挺地为几乎所有专业所必学,并在很多学校作为毕业的条件之一。从这一点也可以看出来英语的重要性。学好英语不是一件轻松的事情,需要长时间的积累。虽然我恐怕不会再参加任何类型的英语考试了,但是未了将来的更好发展,我基本上保持着每天10K的英文阅读量。不过,应付英语考试就是另外一回事了,完全有可能出现我在备考《英美文学选读》时的情况。此外,我还想强调一点,我们这一辈子为了应付考试浪费了太多的生命了,也许功利地应付考试,反而倒是一种非功利的学习行为。
要准备英语考试,大部分人的第一反应应该都是要 背单词!各个级别的英语考试都有那么几千到上万的单词需要背诵,绝大多数考生都或多或少地受到过背单词的折磨。背了忘,忘了再背,背了再忘,反反复复,没有休止。一方面,对单词的记忆会随着时间的流逝而消退,另一方面,几千个单词之间往往也会产生各种干扰,导致遗忘。如果需要背诵的单词量大大减少的话,情况就会好得多了。那现在的问题就是,各级别英语考试大纲中的那些单词,真的都需要背下来吗?
社会学中有个著名的80/20定律,即这个世界80%的财富都集中在20%的人手里。对于英语试卷这一定律可能也适用,即80%的文本都是由那20%最常见的单词组成。如果真是这样的话,那只需要原先五分之一的时间(也许更少,因为这时的干扰也更少),就足以应付英语考试了。市面上其实早就有了通过词频来排列单词供人背诵的参考书,但是这些书的销量似乎并不是很好,这大概是因为这些书只是笼统的把全部文本都拿来进行统计,不够细致,也没有针对性。如果能针对不同类型的试题,甚至针对这些试题的不同部分,统计出来词频,肯定会有更好的指导作用。
针对高考英语阅读题的文本分析
为了进行验证与分析,我从网上找到了最近9年的天津高考英语试题文档。我把其中的阅读部分复制了出来,按年份保存在了txt文档中,然后利用tidyverse
和tidytext
包,制作了两份csv格式句子库文档,其中一份是以全部阅读文本为基础生成的,另一份则只针对阅读题的题干而生成。现在先载入需要的包,并把这两份数据导入:
library(tidyverse)
library(tidytext)
library(pipeR)
library(magrittr)
library(knitr)
reading <- read.csv('reading.csv', stringsAsFactors = FALSE)
question <- read.csv('question.csv', stringsAsFactors = FALSE)
因为readr
包中的函数对中文的支持不是很好,所以我这里使用了R
自带的函数。先看一下这两份数据:
reading %>% head() %>% kable()
year | region | passage | sentence | sentence_low |
---|---|---|---|---|
2007 | 天津 | A | The city of Rome has passed a new law to prevent cruelty to animals. | the city of rome has passed a new law to prevent cruelty to animals. |
2007 | 天津 | A | All goldfish bowls are no longer allowed and dog owners must walk their dogs. | all goldfish bowls are no longer allowed and dog owners must walk their dogs. |
2007 | 天津 | A | This comes after a national law was passed to give prison sentences to people who desert cats or dogs. | this comes after a national law was passed to give prison sentences to people who desert cats or dogs. |
2007 | 天津 | A | “The civilization of a city can be measured by this,” said Monica Carina, the councilor (议员) behind the new law. | “the civilization of a city can be measured by this,” said monica carina, the councilor (议员) behind the new law. |
2007 | 天津 | A | “It’s good to do whatever we can for our animals who in exchange for a little love fill our existence with their attention,” she told a Rome newspaper. | “it’s good to do whatever we can for our animals who in exchange for a little love fill our existence with their attention,” she told a rome newspaper. |
2007 | 天津 | A | The newspaper reported that round bowls don’t give enough oxygen for fish and may make them go blind. | the newspaper reported that round bowls don’t give enough oxygen for fish and may make them go blind. |
question %>% head() %>% kable()
year | region | passage | number | sentence | sentence_low |
---|---|---|---|---|---|
2007 | 天津 | A | 36 | The new law passed in Rome will ______. | the new law passed in rome will ______. |
2007 | 天津 | A | 37 | People in Rome believe that the civilization of a city can be judged by its ______. | people in rome believe that the civilization of a city can be judged by its ______. |
2007 | 天津 | A | 38 | The underlined word “compassion” in Paragraph 6 is the closest in meaning to ______. | the underlined word “compassion” in paragraph 6 is the closest in meaning to ______. |
2007 | 天津 | A | 39 | People may break the law in Turin if they ______. | people may break the law in turin if they ______. |
2007 | 天津 | B | 40 | Charles Blackman’s paintings come from ______. | charles blackman’s paintings come from ______. |
2007 | 天津 | B | 41 | Which two activities can you participate in on the same day? | which two activities can you participate in on the same day? |
可以看到,全部阅读文本(reading
)的句子库包含年份、地区、篇号、原始句子以及完全小写的句子(两种句子有不同的用处)五列变量,而阅读题干文本(question
)的句子库还多了题号一列。
首先,我要利用reading
这份数据来验证一下,是不是最常见的20%的单词组成了80%的文本。为了进行这个验证,我要先把词频统计出来,这部分统计的代码如下:
word_freq <- reading %>% unnest_tokens(word, sentence) %>%
mutate(word = str_replace_all(word, "(_)|(\\d)|(’s)|([abcd]{1}\\.)", "")) %>%
count(word) %>%
filter(nchar(word) > 2) %>%
arrange(-n) %>%
mutate(num = 1:nrow(.))
看一下:
str(word_freq)
## Classes 'tbl_df', 'tbl' and 'data.frame': 3760 obs. of 3 variables:
## $ word: chr "the" "and" "for" "that" ...
## $ n : int 1260 488 213 200 152 151 149 138 125 125 ...
## $ num : int 1 2 3 4 5 6 7 8 9 10 ...
可以看到,一共有3760个单词(实际上还有一些非英语单词字符未清理,但这个数不会差太多),乘以0.2也就是大概752个,下面分别计算前20%的单词组成了多少文本以及共有多少文本:
word_freq %>% filter(num < 660) %$% sum(n)
## [1] 12282
sum(word_freq$n)
## [1] 17820
分别是12282和17820,除一下,可以发现,大概是70%左右,虽然没有达到80%,但也没差太多。我看了一下词频表的具体情况,发现排名660的单词频次为4,为了覆盖更多的文本,我决定多加入一些词,把频次为3的单词也包括进来,这些词共组成了14668字的文本,差不多已经达到了80%,不过这时的单词量有点多,已经达到了1324个,还需要进一步的筛除。
去年刚接触文本分析的时候,用天津2016年高考英语试题画了个词汇云,有点意外的是,fatigue这个单词出现的频率极高,但这个词应该不是高中阶段需要掌握的,它可能仅仅出现在这一年的某一篇文章中,对此,我验证了一下:
filter(reading, str_detect(sentence_low, 'fatigue')) %>% kable()
year | region | passage | sentence | sentence_low |
---|---|---|---|---|
2016 | 天津 | D | We experience this tiredness in two ways: as start-up fatigue (疲惫) and performance fatigue. | we experience this tiredness in two ways: as start-up fatigue (疲惫) and performance fatigue. |
2016 | 天津 | D | Such start-up fatigue is very real, even if not actually physical, not something in our muscles and bones. | such start-up fatigue is very real, even if not actually physical, not something in our muscles and bones. |
2016 | 天津 | D | Performance fatigue is more difficult to handle. | performance fatigue is more difficult to handle. |
2016 | 天津 | D | My fatigue became almost unbearable. | my fatigue became almost unbearable. |
2016 | 天津 | D | Though I worked as hard as before, I felt no fatigue. | though i worked as hard as before, i felt no fatigue. |
2016 | 天津 | D | 51 People with start-up fatigue are most likely to ______. | 51 people with start-up fatigue are most likely to ______. |
2016 | 天津 | D | 52 What does the author recommend doing to prevent start-up fatigue? | 52 what does the author recommend doing to prevent start-up fatigue? |
2016 | 天津 | D | 53 On what occasion does a person probably suffer from performance fatigue? | 53 on what occasion does a person probably suffer from performance fatigue? |
2016 | 天津 | D | B.How to Handle Performance Fatigue | b.how to handle performance fatigue |
2016 | 天津 | D | C.Getting over Fatigue: A Way to Success | c.getting over fatigue: a way to success |
2016 | 天津 | D | D.Fatigue: An Early Sign of Health Problems | d.fatigue: an early sign of health problems |
果然,这个单词只出现在了2016年的D篇之中,而且是以带有释义的形式出现的,这样的单词,即便出现的频率很高,也没有背诵的必要。针对这一点,我决定只把在至少在3篇文章中都出现过1次的单词筛选出来,并对代码进行了相应的修改:
word_freq <- reading %>% unnest_tokens(word, sentence) %>%
mutate(word = str_replace_all(word, "(_)|(\\d)|(’s)|([abcd]{1}\\.)", "")) %>%
unite('year_passage', c(year, passage)) %>%
group_by(word) %>%
summarise(n = n(), m = length(unique(year_passage))) %>%
filter(nchar(word) > 2) %>%
arrange(-n) %>%
filter(m > 2)
看一下现在的情况:
str(word_freq)
## Classes 'tbl_df', 'tbl' and 'data.frame': 921 obs. of 3 variables:
## $ word: chr "the" "and" "for" "that" ...
## $ n : int 1260 488 213 200 152 151 149 138 125 125 ...
## $ m : int 46 46 46 46 41 42 28 42 44 41 ...
word_freq %>% head(10) %>% kable()
word | n | m |
---|---|---|
the | 1260 | 46 |
and | 488 | 46 |
for | 213 | 46 |
that | 200 | 46 |
are | 152 | 41 |
with | 151 | 42 |
you | 149 | 28 |
what | 138 | 42 |
can | 125 | 44 |
from | 125 | 41 |
此时只剩下730个单词了。由于我一共收集了9套试卷,而每套试卷中有4段阅读,所以一共是36篇文章。可以看到,the和for这两个单词在所有的文章中都出现了,and和that等单词也几乎在每一篇文章中都出现了,但是这类单词过于简单,根本就不需要再背了,因此还需要根据经验,总结一个停用词表,以便将这类词汇排除在外。不过,我目前还没有整理这份停用词表,因为文本本身还不够干净,存在一些错误,校对后还要重新整理停用词表,所以我就暂时没弄。如果根据停用词表进行了筛除的话,那最后剩下的词汇应该只有三四百个了,这三四百个单词就是天津高考英语阅读的核心词汇了。
另外,像之前查找fatigue单词的出现情况一样,可以利用建好的句子库和filter
等函数非常方便地提取包含某单词的句子,甚至直接以辅导书上例句格式的形式输出,现以包含psychology一词的句子为例,代码如下:
filter(reading, str_detect(sentence, 'psychology')) %$%
str_c(sentence[2], '(', region[2], ', ', year[2], passage[2], ')')
## [1] "Virginia Berninger, professor of educational psychology at the University of Washington, says it's important to continue teaching handwriting and help children acquire the skill of writing by hand.(天津, 2012C)"
那些辅导教材的编写者应该都有这样一个句子库,否则编写教材将会变成一个非常耗时的工作。我可以慢慢地以其他文本(如新概念之类)为依托建立新的句子库,方便以后编写教案(如果有必要的话)。另外,虽然话是这么说,但我是真的讨厌用手写字…
以上是根据全部阅读文本所作的分析,另外,我还单独把阅读题的题干提取出来,进行了类似的分析。根据我个人的学习经历和辅导他人的经历,发现很多时候,之所以做不对一道阅读题,是因为连题干都读不懂,因此很有必要对那些经常在题干中出现的词进行重点掌握。另外,也可以通过这种方式了解道各种类型的问题的分布情况。
局限与展望
虽然名为文本挖掘,实际上根本就未涉及到太深入的内容。但话说回来,像情感分析、主题模型之类的分析在这里也用不上。不过,n-gram技术倒是值得尝试。我还没见过哪本单词书把常用词组的频次排出来呢,我可以试着把它们找出来。
另外的问题是文本量太少,而且还需要进一步的校对。虽然我下载的那些文档的文件名上都标明了是“精校版”,但实际上都还存在很多错误,我还要自己校正一下。然后文本量的问题,因为我现在只找了天津的高考试题,所以比较少,如果把其他省份的试题也都加进来的话,文本量应该能有十几万,这样得出的结果会更可靠一些。然而,这也带来了新的问题,即不同地区的试卷能否互作参考?北京卷能用来指导天津的考试吗?不同地区的试卷似乎还要做个相关来验证下这个问题。
还有一个不知道该如何解决的问题,即名词的复数与动词的时态问题。book和books会被解析为两个单词,这势必会影响单词的真正频次,不过,就目前的观察来看,影响也没那么大。将来可以考虑建立若干词库来解决这一问题。
我这里只针对阅读题型进行了分析,其他题型也可以进行类似的分析。比如完形,可以考虑将其分为原始文本和空白填充后的文本,对于前者查看单词的频次,而对于后者,则查看词汇之间的关系,来寻找那些最重要的词组。在完形与阅读里所涉及的单词都是消极词汇,只需要认识和理解即可,而要能写出优秀的作文,还需要掌握一部分能熟练使用的积极词汇。对优秀范文的文本分析将可以定位出重要的积极词汇,并查看这些词汇是如何被使用的,从而对写作作出指导。前段时间看了篇文章,说道有人利用机器学习方法对《冰与火之歌》的文本进行了训练,然后写出续作……看来只要有足够的文本,完全也可以利用机器学习帮自己写出作文模板。我认为任务驱动的学习是最好的学习,我可以尝试着去实现一下这个想法,并通过这个过程学习机器学习的相关技术。
虽然我选用的是高考的试题,但显然这也可以应用到其他级别的考试,只要有相应的试题文本就可以了。但是,不同级别的考试(以及不同的题型)需要有不同的停用词库,高考中非常重要的一个词汇可能仅仅是考研词汇中的一个停用词。另外,我还在想,这个技术是不是也可以用于文献阅读?收集个一百来篇领域内的英文文献进行分析,挑出消极词汇和积极词汇,重要的消极词汇牢记在心,重要的积极词汇掌握用法,肯定对阅读文献和写作论文有很大的帮助。
牢骚
既然提到了写论文,下面将进入牢骚时间。硕士三年之间,我一共投了两次文章,一次SCI,一次SSCI;一次直接被拒,一次大修。后面这次时间赶的不是很好,刚接到通知,孩子就病了,等孩子好了,眼看就过年了,期间各种干扰,实在无法静下心来改文章;更关键的是,我虽然想考博士,但根本就没人要,既然读不了博,发不发文章也就没啥意义了,于是就这么不了了之了(最近开始学python了,对于不能研究pychology,甚感遗憾)。两年的心血,就这么付诸东流了啊,真是不甘心,不过,从另一个角度来看,也算是一种解脱。
出于对声优水濑祈的喜爱,前段时间补了个动画,叫《少女终末旅行》。动画讲述了两位少女在战后的无人区中旅行的见闻。虽说是无人区,但她们还是遇到了两个人,一个是男性地图绘制者,一个是女性飞机制造者。后者给我的触动很大。她独自一人制造着飞机,为了造好飞机之后,能飞向有人居住的地方。遇到两位女主人公的时候,飞机已接近完成,三人齐心合力,完成了最后的工作。然而,在真正飞行的时候,她的飞机没有飞出多远,就坠毁了。降落伞下的她缓缓落下,脸上带着满足的笑容。见到这一情景的女主人公之一大为不解,但随后,她就给出了自己的推测:
–
–
笑容.jpg