[源码分析]短评语料Attention-based Aspect Extraction(ABAE)算法

本文在win10下,基于最新版的anaconda、Keras以及其它模块,在ABAE作者开源代码的基础上进行了移植(原程序基于Python2、Keras1等老的模块)。本文讲解了程序的大致结构,并附录了一些参考资源,最后给出进行了移植和注释的程序的GitHub链接。ABAE是一种aspect extraction算法(提取意见实体的方面),其原理解读可以参看文后链接的文章。

算法介绍

在情感分析中,aspect extraction(方面提取)是最关键的任务之一,目的是提取出opinions(意见)针对的对象,例如“The beef was tender and melted in my mouth”中,aspect term(方面关键词)就是beef(细粒度)。ABAE是一种aspect extraction算法。

aspect是opinion mining中意见实体的方面,例如:我们可以把上面找到的beef作为entity,把其归为aspect(food)(粗粒度),当然把beef本身当作aspect也是可以的,但是这个粒度就太细了。为了更好地理解aspect,可以参考文献[1][2]。下图给出一些抽取出的aspect的例子,以建立更直观的理解。
这里写图片描述
目前在aspect extraction方面state-of-the-art的工作都是基于LDA的,而LDA本身有一定的缺点,例如:
(1)不编码word co-occurrences(词同现)统计特性,往往导致提取出的aspect中词语关联性不强(指的是top N的词语)。
(2)LDA给每个训练文档都估计一个topics分布,而review corpus往往很短,使得这个估计很困难。

文献[3]提出了一种Attention-based Aspect Extraction,ABAE算法,很好地弥补了LDA-based方法的缺点,取得了不错的效果。作者Ruidan He给出了算法的开源实现,本文主要目的是分析源码并复现其结果。

ABAE算法的原理可以参考上一篇博客

运行环境

根据作者GitHub上的介绍,对本地环境进行配置。

作者的代码基于Python 2,而我本机上的版本是Python 3,因此实际运行中需要对一些地方进行修改(主要是print语句)。

复现过程在Win10系统下进行,Python则直接采用最新版本的anaconda。

调试的全部过程都是在命令行下进行的,代码在notepadd++和PyCharm上编辑。

程序调试过程的依赖安装会在下面的具体步骤中介绍,实际上直接将各个.py文件中import进的模块全部安装即可,如果安装过程遇到一些问题,一般可以比较容易地查到解决方法。

这里需要特别说明,各种依赖模块我在安装时都没有指定版本,也就是说基本都是安装的最新版本,因此在调试程序过程中遇到了很多问题,需要逐一解决,实际上可以安装作者使用的Theano、Keras版本,并配合Python2,这样可以避免很多麻烦。

源码与数据下载

直接将GitHub上的源码打包下载即可。下载后解压。

根据作者GitHub上的介绍下载原始数据集datasets和作者处理好的preprocessed_data,然后解压到程序主目录下,此时程序的目录如下图:
这里写图片描述
注意到解压后的语料库还是很大的,有700多Mb。

数据预处理

首先要进行数据预处理的工作,主要是两步:
(1)去掉stop words,提取名词的主干。
(2)利用word2vec算法将原始数据转换为词向量。

我们从code中找到preprocess.py和word2vec.py两个文件。

preprocess

preprocess需要调用四个文件,如下所示:

from sklearn.feature_extraction.text import CountVectorizer
from nltk.corpus import stopwords
from nltk.stem.wordnet import WordNetLemmatizer
import codecs

因此,我们需要保证已经安装了sklearn、nltk、codec模块。可以直接用pip指令安装,在命令行中输入:

pip install sklearn
pip install nltk
pip install codecs

其中,nltk模块仅仅通过pip安装还是不够的,为了程序能够顺利运行,还需要先执行以下语句加载stop words和wordnet(用来提取名词的主干),在命令行中:

python
>>>import nltk
>>>nltk.download('stopwords')
>>>nltk.download('wordnet') # 这一句可能会等待较长时间

运行preprocess之前,要注意把print语句加上括号。

preprocess首先把两个语料的训练数据按行读取,逐行处理数据;然后preprocess会逐行读取测试数据,并根据论文中的设置,对于restaurant语料只保留[‘Food’, ‘Staff’, ‘Ambience’]三个aspect的数据,并逐行处理。

下面我们把逐行处理的函数从程序中单独拿出来,稍微进行修改,保存到preprocesstest.py文件中,我们运行这个文件来查看预处理的效果。

from sklearn.feature_extraction.text import CountVectorizer
from nltk.corpus import stopwords
from nltk.stem.wordnet import WordNetLemmatizer
import codecs

# lmtzr.lemmatize(w)只修改名词,如需修改动词时态,需要lmtzr.lemmatize(w, 'v')

# remove stop words and lemmatize words of one sentence.(提取单词主干,例如:'loving'->'love')
if __name__ == '__main__':
    line = 'Bar was a little bit crowded , but these five girls know how to have fun ! ! it was a little hard to understand the waitress and she seemed to have little patience with our questions .'
    lmtzr = WordNetLemmatizer()    
    stop = stopwords.words('english')
    print('[original ]', line)
    text_token = CountVectorizer().build_tokenizer()(line.lower())
    print('[tokenize ]', text_token)
    text_rmstop = [i for i in text_token if i not in stop]
    print('[rmvstops ]', text_rmstop)
    text_stem = [lmtzr.lemmatize(w) for w in text_rmstop]
    print('[lemmatize]', text_stem)

在命令行中运行这个文件,效果如下:
这里写图片描述
程序分别输出原始的一个review, tokenize的结果,去掉停止词的结果,提取名词主干的结果。图片明确展示了每一步操作的效果。

最后,运行preprocess.py文件,发现需要较长时间才能处理完毕,尤其是对beer数据集的预处理。作者已经给出了预处理的结果,我们可以直接使用其结果。

其余代码比较简单,不详细分析。

word2vec

word2vec利用神经网络将原始数据转换为词向量。其需要调用两个模块:gensim和codecs。我们仿照上一步直接安装即可。

利用gensim可以方便地进行word2vec操作,因此代码非常简短。需要注意的是,之所以构造一个generator传入gensim.models.Word2Vec函数,是为了避免加载数据过程中消耗很多时间,可以提高效率。

作者已经提供了训练好的模型,但是在windows下这个模型直接读取的话会出错,我们需要在命令行运行一次word2vec来更新模型,这个操作需要较长时间。更新完成后,我们可以利用这个模型来查看一些单词的向量形式,检验word2vec的效果。

import gensim
import codecs
import numpy as np

if __name__ == '__main__':
    model_file = '../preprocessed_data/restaurant/w2v_embedding'
    model = gensim.models.Word2Vec.load(model_file)
    print(model.wv['like', 'hello'])

    model_file = '../preprocessed_data/beer/w2v_embedding'
    model = gensim.models.Word2Vec.load(model_file)
    print(model.wv['like', 'hello'])

输出为:
这里写图片描述
这样就成功转换了。

其余代码比较简单,不详细分析。

训练

训练过程主要依赖train.py文件,首先给出运行的方法(以下各个阶段的测试都如此运行),在命令行中输入:

python train.py --emb ../preprocessed_d
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值