神经网络文本分类技术实践总结

本文是基于深度学习的书评情感分析工程项目的总结,涉及数据处理、word embedding、CNN、RNN、Attention及bagging模型的应用。项目使用豆瓣书评数据,通过CNN、RNN和带有注意力机制的双向GRU进行文本分类,最后通过bagging提升模型性能。实验结果显示,二星和五星评论对于模型分类效果最佳,且自训练的词向量优于预训练模型。
摘要由CSDN通过智能技术生成

本文内容为学校的工程实践项目总结,项目名为:“基于深度学习的书评情感分析”。
源数据集是队友在豆瓣上爬下来的书评,附带星级评分;词嵌入模型尝试了两种,网上下载的大规模预料训练出的词向量和用word2vec在自己的全部书评预料上训练出的词向量;分类模型尝试了三种,CNN、多层RNN、双向RNN加attention;最后又加了一个基于bagging的ensemble过程。
项目代码:https://github.com/guanchongz/TextClassifier
这是我的个人代码,不包含爬虫代码。
推一下个人技术微信公众号:浪漫主义AI
项目中所有代码文件(无数据集):
这里写图片描述
其中,
langconv.py zh_wiki.py:实现简繁转换的两个文件
textprocess.py :数据集处理和word2vec模型训练文件
text2vec.py:词嵌入代码文件,将文本转换成向量并记录语句长度
CNN.py:CNN文本分类模型
RNNs.py:多层LSTM文本分类模型
biRNN_Attention.py:双向GRU加attention机制的文本分类模型
driver_bagging.py:基于投票的bagging模型及预测功能实现
parameters recording:调参记录文件
下面分两个部分总结此次工作:
一、数据处理及word embedding模型
二、CNN、RNN、Attention及bagging模型

数据处理及word embedding模型

数据来源

首先,我们的任务是做书评的情感分析工作,那么就要考虑,我们需要什么样的数据。
我们需要关注于书籍本身性质的数据。所以,我们选择从豆瓣网上爬数据,而不是当当网、京东和淘宝上的书籍类电商评论,因为电商平台上的评论势必会受到物流、服务等因素的影响,且很多人都是刚收到、还没看多少的情况下就写下了评论,而偏离了书籍本身的内容。
我们需要很多种书籍的数据。要明确,我们做的是整个书籍类的情感分析,而不是某一种或者某一本书籍的情感分析,由于word2vec和分类模型存在领域敏感性,如果我们使用的数据集中某一种书籍占的比重太大,势必会影响其他领域的分析效果。
我们需要分类性质尽量好的数据。为了保证训练模型的质量,我们要保证正负样本数量相对接近,但是这儿就有一个问题,对于书籍来说,好的书籍评论多,但绝大部分都是好评,差的书籍虽然差评占比高了,但是本身评论数量就很少,所以找差评数据还是有些难度的。另外,豆瓣书评分为五个星级,四星和五星的评论占据了绝大部分,二星评论最少,但是,经过测试,我们发现五星和二星评论的分类性能是最好的,也就是说五星和二星评论最能分得开,五星评论毫无疑问含有很正面的情感,但是一星评论则不然,很多评论阴阳怪气,人看上去都有些难以分辨,并不是直白的说“差”,例如,我从一星数据集中摘的几个评论:
白纸无辜。
一点微小的贡献
又开放评分了,美滋滋
这三条评论属于很内敛的评论,连人都要联系一星评价思考一下才能知晓评论的含义。
用心写的书,真实感人,书如其人
太经典了……没话说了……
美得像个梦。
太正能量叻。接不住,,
这四条评论属于反讽类型,我觉得面对这部分评论分类模型应该是很无力的。。上述评论并不是个例,一星评论分类难度可见一斑。
但是二星相对来说就很明显直白了,大部分是这样的评论:
写的好幼稚,貌似就是想让人多冥想和瑜伽。。
中考有韩寒说的那么恐怖嘛……有点做作
挺烂的。两次都没看完
我居然给了四颗星!!!原来以前真的是没什么鉴赏力可言。就冲着它的搞笑程度勉强给两颗吧。小朋友别被这种书坑坏了。
直观看上去就知道,二星比一星对于人类来说更像是一般意义上的差评,在训练中也发现,只要采用一星的数据分类性能就会大幅下滑,而采用二星和五星的数据可以获得最好的准确率。
但是,话说回来,我们可以为了准确率而单单采用二星和五星的数据吗?一星评论难以分辨就要当它不存在吗?答案理应是否定的,但是我并不认为单纯的分类模型能解决这样的问题,那需要具备更强的推理能力的模型才有效,计算机目前不具备处理如此曲折的人类情感的能力。

文本处理

上代码:

    with codecs.open(datafile, "r",encoding='utf-8') as doc:
file=csv.reader(doc)
for line in file:
    try:
        #Obtain the sentence of the classes I need
        starpre=line[0]
        if starpre=='力荐':
            star=4
        elif starpre=='推荐':
            star=3
        elif starpre=='还行':
            star=2
        elif starpre=='较差':
            star=1
        elif starpre=='很差':
            star=0
        else :
            continue
        text=line[1]
        #only chinese character can be saved
        p = re.compile(r'[^\u4e00-\u9fa5]')
        text = " ".join(p.split(text)).strip()
        #convert Traditional Chinese characters to Simplified Chinese characters
        text = Converter('zh-hans').convert(text)
        #abandon the line breaker
        text = text.replace("\n", "")
        text = text.replace("\r", "")
        #cut the sentence into words(perhaps phrase?)
        seglist=jieba.cut(text,cut_all=False)
        seglist=list(seglist)
        final=[]
        for seg in seglist:#abandon stop words
 #               if seg not in stopwords:#abandon empty lines,when training word2vec ,#this line
            if seg != ' ':
                final.append(seg)
        if len(final)>0:
            #for convenience in shuffle action,I use a tuple to keep the pair.
  #              data[star].append((final,star))#abandon this line when training word2vec
            data_word2vec.append(final)
    except:
        continue

首先对于CSV文件中的每一行,将评价转化成int数字,便于分类处理,然后使用正则表达式去掉汉字外的部分,利用split函数去掉空格、换行符等,利用Converter(‘zh-hans’).convert函数将繁体字转换为简体字,然后进行jieba分词,分出来的词可选择去掉停止词,然后去掉空词,最后将非空的词列表添加进分星级的data[star]列表或者不分星级的data_word2vec列表。
分星级的data列表是用于创建分类模型的数据集的,而不分星级的data_word2vec是给word2vec训练词向量用的。
另外,要注意,我在data列表中保存的是元组(sentence,star),为的是有打乱需求时能保持labels和inputs的匹配。这里其实也可以不做这种处理,但是对于我来说,数据过大时会出现内存不足的情况&

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值