续前面的——https://blog.csdn.net/m0_49621298/article/details/107603652
二、数据处理
1、去掉字段中的换行、空格等
2、应用jieba进行分词,这里需要根据不同业务场景设计词库
comment=data['评论'].tolist()
commentArr=[]#存储评论分词
for i in range(len(comment)):#
jieba.load_userdict('./file/自定义词库.txt')
cut=jieba.cut(comment[i])
commentArr.append(list(cut))
3、对分词后的结果进行处理,如提取中文、近义词替换统一、去掉标点符号等
pattern = re.compile(r'[^\u4e00-\u9fa5]')
chinese = []
for review in commentArr:
new_review = []
for token in review:
new_token = re.sub(pattern, '', token)#保留中文
new_token=new_token.replace('安装师傅','师傅')
if not new_token == '':
new_review.append(new_token)
chinese.append(new_review)
4、自行创建和添加需要的停用词库,去除停用词
stopwordArr=[]#停用词
with open('./file/停用词.txt', 'r',encoding='utf-8') as f:
stop_word = f.readlines()
stopwordArr.append(stop_word)
stopwordArr=[i.replace('\n','') for i in stopwordArr[0]]
# print(stopwordArr)
for i in range(len(chinese)):
temparr=[]
for j in range(len(chinese[i])):
if chinese[i][j] not in(stopwordArr):
temparr.append(chinese[i][j])
no_stopword.append(temparr)
5、处理后的数据保存入文件,方便后续使用。
三、数据分析
1、从细类评论数量看热销款
xilei={}
for i in data['细类'].unique():
indices = np.where(data['细类'] == i)
xilei[i]=[len(indices[0]),0]
gailei = np.take(data['clean_word'].values, indices)
sumgailei = np.sum(gailei) # 合并细类下的评论
xilei[i][1]=sumgailei
Top10如下
2、提取关键词,寻找购买者的关注点
for k in xilei.keys():
temparr=[]
tfidf = jieba.analyse.extract_tags(str(xilei[k][1]), topK=10, withWeight=True)
temparr.append(k)
temparr.append(xilei[k][0])
temparr.append([i[0] for i in tfidf])
output.append(temparr)
从前10的高频词来看,可以发现除了常规的好评外,有几个词值得注意下,“实体店”、“垃圾”和“简艺”。“简艺“指的是该商品的特点,也是用户的关注点。“实体店”这个原评论查看后得到的信息:一是线下实体店在逐步拓展,很多评论出现"刚开"字样,二是客户的购物行为很多是【网上看款—实体店体验—下单】这样一个流程。另外的“垃圾”有点“与众不同”,这里用户评论更多提到的安装人员完工后主动把垃圾清理干净~看来这个服务的细节也备受用户关注。
3、评价分类
(1)snownlp
先用snownlp来试下,也顺便找下负面评价(基于种种原因一般情况网上商品的负面评价是不平衡类的,稀有类),给其他算法当训练集用。
def fenlei(text):
s=SnowNLP(text)
return s.sentiments
data['评论分类']=data['评论'].apply(fenlei)
snownlp给出的分值在0-1之间,越低分代表越负面。按分值升序后看了前20来条,还是找出了一些差评的,有几个误判,其中4个涉及前面说到的“垃圾”这个高频词,“垃圾”在本次的数据集中大部分指的是安装师傅带走垃圾,在第三方库会是贬义词,尝试把“垃圾”这个词语去除后,确实有所改善,果然数据分析还是要以业务为基础~初略看大概0.000025分以上都要计入正面了。
混淆矩阵,这里重点关注下负面评价的(稀有类),召回率=72.7%,精度=88.9%,F1度量值=80.0%。还算可以吧~~另外自己手工打标签是真的累!!数据分析的大头除了数据处理部分,打标签也少不了。
为什么关注负面评价?因为有一部分客户好评是系统到期自动评的,客户后来追加的负面评论会被掩盖而未得到客服回应。关注这些负面评价可以及时进行客户修复。虽说量少,但口碑却会是一传十,十传百。
混淆矩阵 | 预测类 | ||
负面 | 正面 | ||
实际类 | 负面 | 16 | 6 |
正面 | 2 | 1954 |
(2)尝试用贝叶斯、SVM来分类
负面标签少,都挑出来
neg = data[data['手工标签'] == "负面"]['clean_word'].tolist()
# print(len(neg))#22
negArr=[]
for i in range(len(neg)):
temparr=[]
neg[i]=neg[i].replace('[',"")
neg[i] = neg[i].replace(']', "")
neg[i] = neg[i].replace("'", "")
temparr=neg[i].split(',')
negArr.append(temparr)
在正面标签里随机选30个做下平衡
posindex=np.where(data['手工标签'] == "正面")#查看正面标签的序号
# print(type(posindex[0]))#<class 'numpy.ndarray'>
randompos=random.sample(list(posindex[0]),30)#在正面中随机抽取30个
pos=data.loc[randompos]['clean_word'].tolist()
posArr=[]
for i in range(len(pos)):
temparr=[]
pos[i]=pos[i].replace('[',"")
pos[i] = pos[i].replace(']', "")
pos[i] = pos[i].replace("'", "")
temparr=pos[i].split(',')
posArr.append(temparr)
构造训练集
classVec=[0 if i<30 else 1 for i in range(30+22)]#创建label,1代表负面差评
posnegList=posArr[:]
posnegList.extend(negArr)#合并起来
def features(posnegList):
return dict([(word, True) for word in posnegList])
train=[]#构造训练集
for i in range(len(posnegList)):
train.append((features(posnegList[i]),classVec[i]))
用NLTK的贝叶斯训练——需要注意它的要求输入格式
classifier = NaiveBayesClassifier.train(train)
print(classifier.show_most_informative_features(10))