最近跟小牛队老板一样在看《Building Machine Learning Systems with Python, 2nd Edition》。

除却某些代码(特别是第 5 章的)有错,书写得很好。没怎么学过 Python ,数学也不太行的我,也能跟着一步步走进机器学习的大门。

稍微看过这本书后,我就冒出一个想法:能不能用相关技术提取出文章中的比喻句呢?要机器读懂文章中的比喻句,有点难,幸好这不是提取比喻句的必要条件。

不管难易,先找到好数据再说。记忆中最密集出现比喻句的作品是《围城》。就拿它试试。

跟书里的例子一样,拿到数据后,先处理一下:去掉《围城》里的空白字符、章节提示,把一段段的文章切成一句句,方便处理和统计。关键代码是一句正则表达式和 python 的 findall 方法:

import re
reg = re.compile(u'.*?(?:!|。|?|(?::“)|(?:[!。?]”))')
#...
for sentence in re.findall(reg, line):
  #...

正则表达式匹配感叹号、句号、问号以及人物说话的标志性开头符号“:“”和结尾符号“””,findall能匹配并包含这些标点符号,对《围城》用这一套分句效果还可以。

接着先用一个最简单的办法——关键字匹配——找出所有可能是比喻句的句子,看看这样做的效果如何。

观察从网上收集到的《围城》里的比喻句,发现很多都带一个“像”字,还有其他诸如:似、一样、如、仿佛的字眼。写下简单的代码:

import re
with open('weicheng_sentences.txt', 'r') as inputfile:
    with open('weicheng_with_simple_tag.txt', 'w') as outputfile:
        pattern = re.compile(r'|'.join(['[^不]像','似','如','一样','仿','好比','成了','俨然']))
        for line in inputfile:
            if pattern.search(line) != None:
                tag = '1'
            else:
                tag = '0'
            new_line = line.rstrip() + '\t' + tag
            outputfile.write(new_line + '\n')

试了试,从 1 万多句中找到了 800 多句,手动标记整理过后,发现当中有 400 多句是比喻句,而被判别为“不是比喻句”的有 9000 多句,我没一一手动整理,抽样看了看,估计 100 句里有 1 句是比喻句。这样算下来,准确率只有 50 % ,召回率是 81.6% 。

接下来,在匹配关键字的基础上,加上中文分词,看看能不能从中提取一些比喻句的特征。首先从一堆关键字中选了「像」字出来,用结巴分词切好,仔细看了看,发现这样选出来很多比喻句都有本体和喻体,还有部分只出现喻体,如:

孩子不足两岁,塌鼻子,眼睛两条斜缝,眉毛高高在上,跟眼睛远隔得彼此要害相思病,活像报上讽刺画里的中国人的脸。 机密得好像四壁全挂着偷听的耳朵。

我写下了一个判断方法,如果一个句子,在带「像」字的动词前后各出现一个名词,就把它判别为比喻句。如果只有一个名词,就认为它有 50 % 的可能是比喻句,因为有不少句子是这样的:

就像系主任罢,我们的系主任韩先生比赵先生高一级,赵先生又比外语系的刘东方高一级。

当然,带「像」字动词前后各有一个名词的句子也有可能不是比喻句,像下面这样的:

孙先生常跟我说,女学生像苏小姐才算替中国争面子,人又美,又是博士,这样的人哪里去找呢?

其他的关键字也作各自处理过后,关键字匹配升级成为关键词加上一些句子结构特征的匹配,比如句子中若只出现「一样」并不被当成比喻句,只有「一样」前面还出现「跟」或者「和」时才算是比喻句。但仍然会有像下面不是比喻句却被当成比喻句的句子:

从前男性所做的职业,国会议员、律师、报馆记者、飞机师等等,女性都会做,而且做得跟男性一样好。

升级后,有 689 句被标记为比喻句,其中有 486 句是比喻句,剩下的 9218 句中,假设有 92 句是比喻句。这样算下来,准确率是 70.5 % ,召回率是 84.1 % 。

看起来不错,缺憾是这个判别比喻句的方法没有接受《围城》以外的文本的考验,而且我觉得这种方法已经很难再有突破了。

接下来有两个方向,一个是在分词的基础上,增加句法依存分析甚至是语义依存分析,看能不能提取比喻句的关键特征;另一个方向是参考《Building Machine Learning Systems with Python, 2nd Edition》中的分析推特情感色彩的例子,找到字词与比喻句之间的概率对应关系。

要说感想的话,在看过书以及自己动手实践过后,发现机器学习很依赖由人肉整理过、提取特征、标记过的高质量的数据,没这样的数据,很可能都是白折腾,或者效果不好。

本文相关源码