当前位置:首页 > 数据挖掘

豆瓣电影短评数据情感分析Baseline

作者:admin     时间:2020-07-29 15:02:38     来源:互联网    
一.数据集处理

原始的电影评论数据共4428475条,样例数据如Fig 1所示,数据里面还夹着一些没有评分的数据,将这些RATING为NaN的过滤掉之后,剩下来的数据有4166704条。

除了数据评分取值的问题,CONTENT里的文本有的还是繁体,所以在进行情感分析之前,我们还需要对文本的格式统一起来,代码核心部分如下(仅供参考):

fromlangconvimport* deftraditional2simplified(text): text = Converter('zh-hans').convert(text) returntext dataset["CONTENT"] = dataset.CONTENT.apply(lambdax: traditional2simplified(x))

对400多万的文本数据进行分类,乍一看也还算OK,不过在单机上还是有些吃力,所以我们需要对数据进行进一步的去脏以达到缩放的效果,而这一阶段需要做的工作量还是比较多的。

1.去除干扰评论数据

影评数据的评分RATING评分值为1-5星,这些评分跟评论的相关性还是比较大的。虽然如此,评论里面还是存在很多的干扰数据,笔者对数据集的进行了简单的比较,发现相同的评论,其RATING值居然不一样,这类数据还占了15%以上,真是恐怖如斯!!考虑到数据集的数据量本来就比较大,所以索性对这部分数据直接去掉了,最后剩下3795251条影评数据。


2.去除过短或过长的数据

在这份电影评论数据集里,文本长度从1-3000+不等,长度过于波动,不太符合短评数据的长度规范。为此,笔者将文本长度限制在了[5,140],上下都取闭区间(豆瓣的短评数据集长度为140),最后得到的数据集3582251条。


3.情感类别定义

先前提到豆瓣电影评论携带的评分在1-5星,仔细看了评论内容你会发现,1-2星的评论以及4-5星的评论确实很难区分,好在豆瓣给出了1-5星每个星值的意义(1-很差,2-较差,3-还行,4-推荐,5-力荐),所以最后将评论划分为三个:1-2星为消极negative,3星为正常normal,4-5星为正向positive,如此以来,就将评论划分成三个类别了,各个类别的数据量如Fig 2所示。接下来就可以对这个label取值为3类的文本数据进行模型训练与预测了。

二.数据预处理

对于中文文本分词,这里采用的jieba,同时文本数据进行了去停留词处理,代码如下:

importjieba fromsklearn.feature_extraction.textimportCountVectorizer defget_stopwords(): stopwords = [line.strip()forlineinopen('data/stopwords/stopword_normal.txt',encoding='UTF-8').readlines()] returnstopwords importre stopwords = get_stopwords() deftext_process(text): ''''' 按照下面方式处理字符串 1. 去除标点符号 2. 去掉无用词 3. 返回剩下的词的list ''' text = re.sub("[\s+\.\!\/_,$%^*(+'\']+|[+——!,。?、~@#¥%……&*()]", "",text) ltext = jieba.lcut(text) res_text = [] forwordinltext: ifwordnotinstopwords: res_text.append(word) returnres_text X = dataset.CONTENT y = dataset.label bow_transformer = CountVectorizer(analyzer=text_process).fit(X) X = bow_transformer.transform(X)

通过上面的处理之后,我们可以得到X和y,接下来,可以用这部分数据进行模型训练了。

三.模型训练与评估

采用sklearn将数据集划分为训练集和测试集,即使比例为9:1,测试数据也有358226t条,一个demo足够了。

fromsklearn.model_selectionimporttrain_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=99)

由于是多分类,所以就直接采用了MultinomialNB作为baseline,核心代码如下:

rom sklearn.naive_bayesimportMultinomialNB nb = MultinomialNB() nb.fit(X_train, y_train) preds = nb.predict(X_test) 四.模型评估

得到了预测的preds值之后,直接调用sklearn的metrics里面的方法,就可以轻松地将相关的模型评估指标值计算,代码如下:

rom sklearn.metricsimportconfusion_matrix, classification_report #根据预测值和真实值计算相关指标 print(classification_report(y_test, preds))

输出结果:

precision recall f1-score support -10.560.560.5670406 00.500.440.47121276 10.660.720.69166544 accuracy0.59358226 macro avg0.570.570.57358226 weighted avg0.590.590.59358226

可以看出,三个label的平均precision和recall都接近0.6,整体上还是OK的,后续再进一步优化吧,预测方法封装如下:

defsentiment_pred(text): text_transformed = bow_transformer.transform([text]) score = nb.predict(text_transformed)[0] returnscore

预测结果如下Fig 3,测试数据样例不要太当真,仅仅作为参考:

五.结束语

各位看客如有需要数据集的可见参考文献[1],其他的就不多说了,情感分类内部细节还有很多待处理,本文仅仅是一个简单的baseline,如果采用深度学习如LSTM进行分类的话,单机上内存可能会不够,所以还需要对数据集进行进一步的处理。OK,就将这个当做是下一个任务项吧!

六.References 豆瓣影评数据集:http://moviedata.csuldw.com http://www.csuldw.com https://scikit-learn.org

End.