美团外卖用户评价文本研究 您所在的位置:网站首页 外卖的相关数据 美团外卖用户评价文本研究

美团外卖用户评价文本研究

2023-03-23 05:55| 来源: 网络整理| 查看: 265

摘要

近年来外卖行业发展迅猛,多家外卖平台竞争激烈,提升用户体验对维持用户体量至关重要,因此平台需要着眼于用户评价,了解用户需求,分析其内容并做出改善。本报告基于美团外卖用户评价数据,对中文文本执行了情感分析、词频分析、文本聚类等方面的实际操作,旨在了解用户对于外卖服务最关心的方面,如菜品质量、送餐服务水平等,进而对外卖平台提出一定改善意见。实验过程由Python实现,论文主要内容包括:方法及模型的简要介绍、实证分析(包括实验过程及结果分析)、结论及感受等。

关键词:外卖;用户评价;自然语言处理;中文文本分析

ABSTRACT

We are now living in an era in which the takeout industry is developing rapidly, and a number of takeout platforms are competing fiercely. Therefore, improving the user experience is necessary to maintain the number of users. As a result, the platform needs to focus on users’ review/evaluation, investigate their needs, analyze their contents and make improvements. Based on the review data of meituan takeout users, this report carries out the practical operation of sentiment analysis, word frequency analysis and text clustering on Chinese text, aiming to understand the most concerned aspects of takeout service, such as the quality of dishes and the level of meal delivery service, and then puts forward some suggestions for improving the takeout service. All the program is written in Python. The main contents of this paper include: a brief introduction of the methods and models, empirical analysis (including the experimental process and result analysis), conclusions and feelings, etc.

Key words:Takeout, User Review, NLP, Chinese Text Analysis

1 研究背景及意义

1.1 研究背景 在互联网技术的支持下,多家外卖平台应运而生,众多餐饮商户也加入了提供外卖服务的行列中。然而,用户对外卖餐品或是配送服务褒贬不一的现象频发,差评甚至会在一定程度上影响商户的后续客源,导致全店盈利受损;或是致使外卖骑手信誉受损,受到平台的大额处罚。因此研究用户评价,探究影响评价的因素,进而改善服务以吸引更多的消费者是很有必要的。

1.2 数据介绍 本次文本研究采用来自美团外卖平台的用户评价,收集截至2018年左右;数据共计约12000条,其中正向评价约4000条,负向评价约8000条;包含两个特征,分别是评价类型“label”及评价文本“review”;数据来源为GitHub。

1.3 研究意义 通过情感分析、词频分析等方法,了解外卖用户的诉求,初步确定影响用户体验及评价的主要因素,以此为外卖平台、餐饮商户、骑手拟定改善方案,提高外卖服务水平及质量。

.

2 方法及模型简述

2.1 SnowNLP snownlp是基于TextBlob的启发编写成的针对中文文本内容处理的库,且不以NLTK为基础,所有算法独立实现。 在情感分析部分使用到SnowNLP作为分析器。

输入的是待解析的文本,如在本论文中即为原数据中包含的评价文本;返回的是SnowNLP专用的字段,包含sentiments属性,即为文本的情感评分,接近1即为正向评价,接近0即为负向。

使用SnowNLP进行情感分析的主要思路为:使用SnowNLP解析原始评价文本;为原始数据中的每条评价计算出情感评分并转换为0-1型,与数据自带的评价类型变量“label”做对比,得到情感分析准确率。详见实证分析3.3部分。

2.2 SVM SVM即支持向量机,广泛应用于机器学习领域中,是一种按监督学习方式对数据进行二元分类的广义线性分类器。SVM的核心思想是找到各类样本点到超平面的距离最远,即找到最大间隔超平面。 本论文中使用SVM,参考课程资料中的内容执行了基于SVM的情感分析,最终结果良好,且准确率高于SnowNLP方法所得结果,详见3.4部分。

2.3 DBSCAN DBSCAN是一个基于密度的聚类算法,将簇定义为密度相连的点的最大集合,即每个簇都是足够高密度的区域;其基本思想是对于一个类中的每个对象,在给定半径的区域中必须包含一定数量以上的对象,一个类能够被其中任一核心对象确定;在实际工作中,DBSCAN反复寻找核心对象直接密度可达的对象,可能会有一些密度可达簇在这个过程中合并,当没有新的对象可以被添加到任何簇中时,即视为聚类结束。 在本论文中,执行了基于DBSCAN 的中文文本聚类,详见3.6部分。

.

3 实证分析

3.1 数据准备 读取原数据“waimai_10k.csv”,观察数据规模为11987行,2列,每行包含:“label”评价类型,值为1即为好评,值为0即为差评;“review”用户评价,是由汉字及阿拉伯数字组成的评价文本。

import pandas as pd data = pd.read_csv('waimai_10k.csv')

共执行以下准备工作: 1、将review列转换为字符串类型,便于后续分词操作;

#类型转换为字符串,便于分词操作 data['review'] = data['review'].astype('str')

2、查看原数据中是否有空值,使用isnull()函数的结果为0,即无空值;

#查看是否有空值 import numpy as np np.sum(pd.isnull(data))#pd.isnull用来判断是否有空值

3、将review列定义为reviews,lable列定义为sentiments,便于后续使用;

#定义评价和情感 reviews = np.array(data['review']) sentiments = np.array(data['label']) row,col = data.shape

4、绘制饼状图,观察正向和负向的频数及占比如下:

#查看正向和负向的评价分别有多少 data['label'].value_counts() #绘制饼状图,观察到正向和负向的占比 import numpy as np import matplotlib.pyplot as plt #定义一个饼 plt.pie([4000,7987],labels = ('正向评价','负向评价')) #记得要用中文字体 #查看中文字体的代码为: #a=sorted([f.name for f in matplotlib.font_manager.fontManager.ttflist]) #for i in a: # print(i) #我的mac系统里只有pingfang hk这一种字体是中文的,就用它了 plt.rcParams['font.sans-serif'] = ['PingFang HK'] #画图 plt.show()

3.2 分词

#停用词 stopwords = pd.read_csv("StopWords.txt",header=None,names=["StopWords"]) #多加一列用于存储分词 data['cutwords'] = "cutwords" #用jieba分词 import jieba for ii in np.arange(row): cutwords = list(jieba.cut(data.review[ii],cut_all=True)) cutwords = pd.Series(cutwords)[pd.Series(cutwords).apply(len)>1] cutwords = cutwords[~cutwords.isin(stopwords)] data.cutwords[ii] = str(cutwords.values)

使用jieba进行中文分词,并以“StopWords.txt”文件作为停用词,将分析结果作为新的一列加入到数据中,结果如下图。 在这里插入图片描述 3.3 基于SnowNLP的情感分析 3.3.1 方法步骤 1、在数据中多加2个变量(列)备用,用于储存稍后得到的评分,分别命名为“number”和“number2”; 2、使用SnowNLP对评价文本做分析,返回SnowNLP字段“s”; 3、读取s中的sentiments属性,即为每条评价的情感评分,将其储存在number变量中

#使用SnowNLP from snownlp import SnowNLP #多加一列,储存评分 data['number'] = "number" #使用SnowNLP分析中文文本的情感,由内含的sentiments得到评分 #评分范围是0-1,接近0是负向,接近1是正向 for i in np.arange(row): s = SnowNLP(reviews[i]) number = s.sentiments data.number[i] = number

在这里插入图片描述 4、将number转化为0-1型数据,储存在number2变量中;

#观察到number值为小数,为了将其和sentiments做对比,转化为0-1型数据 #为避免数据损坏,此处复制一列number2,同时也可与number做对比 data['number2'] = data['number'].copy() #转为0-1型,输出结果 data['number2'] = data['number2'].apply(lambda x: 0 if x1]

3、查看分词结果的频数,观察其中靠前位置的词汇; 4、设置一个筛选工具,用于筛掉分词结果中的无意义或干扰词汇;

#设置一个筛选工具,筛掉无意义或干扰词汇 filtering = [ '没有', '一个', '外卖', '一点', '东西', '不会', '怎么', '不是', '两个', '结果', '已经', '感觉', '就是', '特别', '而且', '什么', '\n', '\t\n', '有点', '非常', '这么', '知道', '超级', '真的', '不要', '但是', '可以', '还是', '一次', '时候', '不能', '这个', '你们', '一样', '这次', '今天', '根本', '真是', '不过', '一份', '实在', '12', '11', '那么']

5、去除上述待筛掉的词汇,得到有效词汇列表;

#用分词结果cutwords3去掉待筛选的词汇,得到有效词汇cutwords4 cutwords4 = cutwords3[~cutwords3.str.contains('|'.join(filtering))]

6、读出有效词汇中的前50位,观察其特征;

#读出有效词汇中前50位 top50 = cutwords4.value_counts()[:50] top50

7、读出有效词汇中的前100位,并转换为适用于词云图的数据类型;

#读出有效词汇中前100位 top100 = cutwords4.value_counts()[:100] #用有效词汇前100位设置适配于词云图的数据,并转换数据类型 data_for_wordcloud = [(x, y) for x, y in zip(top100.index.tolist(), top100.tolist())] data_for_wordcloud = str(data_for_wordcloud)

8、绘制词云图。 在这里插入图片描述

from wordcloud import WordCloud wc = WordCloud( background_color='white', # 设置背景色 mode = 'RGBA', # 默认为“RGB” width = 2000, # 设置背景宽,默认为400像素 height = 1200, # 设置背景高,默认为200像素 max_font_size=300, # 最大字体 min_font_size=5, # 最小字体 font_path='songti.ttc', # 由于要显示中文,需要设置字体,否则会出现乱码 max_words = 200, # 最大词汇个数 colormap='Greens' # 指定词云色系,默认随机分配颜色 ) wc.generate(data_for_wordcloud) wc.to_file("meituan.png")

3.5.2 方法及结果分析 先前3.2的分词结果是由若干个list构成,无法精确到词分析词频,因此此处需要重新进行适用于词频分析的分词。将文本全部拼接,再分词后的结果是214017行数据,每行仅有一个词汇;筛掉长度为1的词汇,剩余如下88355行。 在这里插入图片描述

随后便可对上述结果进行计数,得到词频分布。结果如下: 在这里插入图片描述 在本报告中,我进行词频分析的主要目的是要探究用户评价中最常出现的内容,即用户最注重的方面。因此有一些词汇在这个条件下可以被视作是没有意义的,如“一个”、“就是”等量词或副词是可以忽略的;“没有”也很难判断用户是针对哪个方面而写下的评论,像“菜品没有让我失望”和“没有按我的要求送达”就是完全不同的方向及情感;而“外卖”这样出现了652词的高频词汇与背景完全一致,对其做分析也无实义。于是,我需要对词频分析的结果做出筛选,去掉上述高频词汇中无意义的部分;低频词汇中当然也存在诸多无意义内容,但对研究效果的整体影响不大,且全部去除的操作难度大,因此可忽略不计。基于上述分析结果,得到筛选后新的词频分布如下: 在这里插入图片描述 观察这些有效高频词汇,如“味道”、“好吃”、“难吃”等代表着该条评价涉及到对菜品的评价,“送餐”、“送到”、“速度”、“太慢”等是对外卖送餐服务的评价,而“不错”、“一般”等既可能是在说菜品,也可能是在说送餐,需要具体根据文本内容再做进一步判断。

对有效词汇的前50位手动进行简单的分类及累加,得到结果如下。 在这里插入图片描述 其中,关于送餐服务的提及次数接近半数,远超其他方面的频次。

基于这个数据,我认为用户在使用外卖平台时最关心的是送餐服务,包括骑手的送达速度、服务态度;其次是菜品质量,通常会点评“好吃”或“不好吃”等;同时也有一些用户会表达自己的意愿,如“下次还会买这家”等等。 我对这个结果的理解是:用户在订餐时已经可以看到先前其他用户同一家商户进行消费行为时对菜品的点评及评分,结合自己的喜好选择要购买的商家及菜品,因而对菜品的“踩雷”情况较少;但负责送餐服务的骑手是在下单后才由系统分配或骑手接单,用户在下单前对骑手的情况是未知的,因而在骑手服务过后,用户会更愿意对这个“未知数”做出评价,夸赞或抱怨的情况均会出现。所以该数据中,用户在评价时提及送餐服务的次数占比最高。

因此,外卖平台提升用户体验的方法应从送餐服务的角度切入,针对性地完善用户对于骑手的了解和选择上,如被用户A打出过好评的骑手B,系统可在用户A再次购买外卖时优先安排骑手B接单;被用户A打出过差评的骑手C,系统尽可能避免其再次为用户A送餐,以减少用户A产生不良情绪,维持用户A的粘性等。

3.6 基于DBSCAN的文本聚类 3.6.1 方法步骤 1、对3.2中分词结果cutwords使用TfidfVectorizer提取稀疏文本特征;

from sklearn.feature_extraction.text import TfidfVectorizer vectorizer = TfidfVectorizer(max_df=0.2, max_features=400, min_df=1,ngram_range=(1, 2), use_idf=True) from sklearn.decomposition import TruncatedSVD from sklearn.preprocessing import Normalizer from sklearn.pipeline import make_pipeline svd = TruncatedSVD(200) normalizer = Normalizer(copy=False) lsa = make_pipeline(svd, normalizer)

2、对稀疏文本特征使用LSA降维;

#提取稀疏文本特征,并用LSA降维 tezheng = vectorizer.fit_transform(data['cutwords']) X = lsa.fit_transform(tezheng)

3、执行完上述准备工作后,使用DBSACN做聚类;

#用DBSCAN聚类 from sklearn.cluster import DBSCAN db = DBSCAN().fit(X) core_samples_mask = np.zeros_like(db.labels_, dtype=bool) core_samples_mask[db.core_sample_indices_] = True

4、在数据中多加1个变量,命名为“cluster”,储存聚类得到的标签;

#多加一列,储存聚类标签 data['cluster'] = "cluster" data['cluster'] = db.labels_

5、计算并输出聚类簇群数量(此处为218);

#计算并输出聚类数量 n_clusters_ = len(set(db.labels_)) - (1 if -1 in db.labels_ else 0) n_clusters_

6、对聚类结果进行可视化处理,设置颜色等相关参数,绘制聚类气泡图。

#设置颜色 colors = [plt.cm.Spectral(each) for each in np.linspace(0, 1, 200)] #设置图像相关参数并绘制聚类结果 for k, col in zip(db.labels_, colors): class_member_mask = (db.labels_ == k) xy = X[class_member_mask & core_samples_mask] plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),markeredgecolor='k', markersize=19)

在这里插入图片描述 3.6.2 聚类结果分析 在前面得到的218个聚类簇群中任意挑选一个,具体观测该簇群,以了解聚类情况。此处选择的是编号为48的簇群,命名为db48并输出查看。

#具体查看某一簇群的情况,了解聚类情况,这里查看编号48的簇群 db48 = data[data['cluster'] == 48]

在这里插入图片描述 该簇群共有11条评价。我们统计该簇群的词频,得到结果如下:

#查看48簇的词频 pin48 = '\n'.join(db48['review'].tolist()) pin48fc = pd.Series(list(jieba.cut(pin48))) pin48fc = pin48fc[pin48fc.str.len()>1] pin48fc.value_counts()

在这里插入图片描述 在这里插入图片描述 由上述词频分布可知,该簇群中的评价100%涉及到“小哥”、“外卖”这两个关键词,结合文本内容也不难看出这11条评价全部涉及到“外卖小哥”这一主题,其中更不乏“大雾霾,外卖小哥记得带口罩哦!”这样令人暖心的内容。同时还可以输出簇群db48的词云图,同样可以观察到外卖小哥是核心内容。

#查看48簇群的词云图 db48wc = [(x, y) for x, y in zip(pin48fc.index.tolist(), pin48fc.tolist())] db48wc = str(db48wc) from wordcloud import WordCloud wc2 = WordCloud(background_color='lightyellow',mode = 'RGBA',width = 300,height = 300,max_font_size=300,min_font_size=3,font_path='songti.ttc',max_words = 200,colormap='Reds') wc2.generate(db48wc) wc2.to_file("db48.png")

在这里插入图片描述 因此我判断这一簇群的聚类标准是:文本内容与外卖小哥高度相关。 我们还可以输出另一个簇群,同样可以感受到这样的聚类特点。

#再看一个簇群123 data[data['cluster'] == 123].head(14)

在这里插入图片描述 至此,已经成功判明了DBSCAN的聚类准则,且效果良好。 .

4 结论

本报告使用美团外卖用户评价数据进行实验,共操作了基于SnowNLP的情感分析、基于SVM的情感分析、词频分析、基于DBSCAN的文本聚类四个部分的研究。所使用的模型及方法均有较高的合理性及准确率(具体分析及结论已分别在前文3.3.2、3.3.3、3.4.2、3.5.2、3.6.2部分中给出)。

其中,我认为实际意义最佳的是词频分析部分,从中我得到了“外卖平台应优先从送餐服务方面来提升用户体验”的结论,并给出了具体方案的简要说明;在情感分析方面,基于SnowNLP的方法可以更具体地分析用户的情感,SVM则拥有更高的准确率;文本聚类则提供了更有针对性地分析用户评价的视角。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有