第八章 分类 SVM案例:中文商品评论情感判定

案例4:中文商品评论情感判定

案例背景

本案例将基于电商平台的商品评论数据,利用SVM对评论的情感倾向进行预测。任何行业领域,用户对产品的评价都显得尤为重要。通过用户评论,可以对用户情感倾向进行判定。例如目前最为普遍的网购行为,对于用户来说,参考评论可以做出更优的购买决策;对于商家来说,对商品评论按照情感倾向进行分类,并通过文本聚类得到普遍提及的商品优缺点,可以进一步改良产品。本案例主要讨论如何对商品评论进行情感倾向判定。

本案例中,我们从互联网某电商平台抓取手机的中文评论内容。然后对中文评论进行分词处理。为了区分评论中的好评和差评,我们使用支持向量机模型,并分析模型的输出结果。这份某款手机的商品评论信息数据集,共计8186个样本,数据集包括两个属性。其中,Comment字段是用户对该款手机的评论,类型为String;Class代表标注好的该评论的情感倾向,-1代表差评,0代表中评,1代表好评。

数据读取与划分

这份某款手机的商品评论信息数据集,包含2个属性,共计8186个样本。

列名 说明 类型 示例
Comment 对该款手机的评论 String 客服特别不负责,明明备注了也不看,发错了东西。
Class 该评论的情感倾向: -1 ----- 差评 0 ----- 中评 1 ------ 好评 Int -1

使用Pandas中的read_excel函数读取xls格式的数据集文件,注意文件的编码设置为gb18030

python 复制代码
import pandas as pd

#读入数据集
data = pd.read_excel("./data.xls")
data = data.dropna(subset=["Comment"])
data.head()

| | Comment | Class |
| 0 | 快就是手感满意也好喜欢也流畅很服务态度实用超快挺快用着速度礼品也不错非常好挺好感觉才来还行好... | 1 |
| 1 | 差评,说好的返现返现都是骗人。东西很差 很垃圾 | -1 |
| 2 | 售后真是差 买了不到15天锁屏键出现故障,申请换货过了审核说上门取件了 等了几天没人来 ... | -1 |
| 3 | 郁闷啊多等2天多无线充 充电宝和贴膜 和京东沟通没补发 心里那个郁闷啊不摆了 失败 ... | -1 |

4 今天去贴膜时才看到在卡槽右面有一处很小的刻痕,很是郁闷 -1

查看数据集的相关信息,包括行列数,列名,以及各个类别的样本数。

python 复制代码
# 数据集的大小
data.shape
复制代码
(8185, 2)
python 复制代码
# 数据集的列名
data.columns.values
复制代码
array(['Comment', 'Class'], dtype=object)
python 复制代码
# 不同类别数据记录的统计
data['Class'].value_counts()
复制代码
 1    3042
-1    2657
 0    2486
Name: Class, dtype: int64

现在,我们要将Comment列的文本信息,转化成数值矩阵表示,也就是将文本映射到特征空间。首先,通过jieba对文本进行中文分词。

python 复制代码
# 导入中文分词库jieba
import jieba
import numpy as np
python 复制代码
# 对数据集的每个样本的文本进行中文分词
cutted = []
for row in data.values:
    raw_words = (" ".join(jieba.cut(row[0])))
    cutted.append(raw_words)

# 生成新DataFrame,Comment字段为分词后的内容
data_cutted = pd.DataFrame({
    'Comment': cutted,
    'Class': data['Class']
})
data_cutted.head(5)
复制代码
Building prefix dict from the default dictionary ...


(8185, 2)


Dumping model to file cache C:\Users\ggq\AppData\Local\Temp\jieba.cache
Loading model cost 0.514 seconds.
Prefix dict has been built successfully.

| | Comment | Class |
| 0 | 快 就是 手感 满意 也好 喜欢 也 流畅 很 服务态度 实用 超快 挺快 用 着 速度 礼... | 1 |
| 1 | 差评 , 说好 的 返现 返现 都 是 骗人 。 东西 很差 很 垃圾 | -1 |
| 2 | 售后 真是 差 买 了 不到 15 天锁 屏键 出现 故障 , 申请 换货 过 了 审核... | -1 |
| 3 | 郁闷 啊 多 等 2 天多 无线 充 充电 宝 和 贴膜 和 京东 沟通 没 补发 ... | -1 |

4 今天 去 贴膜 时才 看到 在 卡槽 右面 有 一处 很小 的 刻痕 , 很 是 郁闷 -1

绘制词云图

为了更直观地观察词频高的词语,我们使用第三方库wordcloud进行文本的可视化。

python 复制代码
# 导入第三方库wordcloud

from wordcloud import WordCloud

针对好评,中评和差评的文本,建立WordCloud对象,绘制词云。

python 复制代码
# 好评
wc = WordCloud(font_path='msyh.ttf')
wc.generate(''.join(data_cutted['Comment'][data_cutted['Class'] == 1])) #取出好评文本
wc.to_image()
python 复制代码
# 中评
wc = WordCloud(font_path='msyh.ttf')
wc.generate(''.join(data_cutted['Comment'][data_cutted['Class'] == 0])) #取出中评文本
wc.to_image()
python 复制代码
# 差评
wc = WordCloud(font_path='msyh.ttf')
wc.generate(''.join(data_cutted['Comment'][data_cutted['Class'] == -1]))
wc.to_image()

文本向量化

从词云展现的词频统计图来看,"手机","就是","屏幕","收到"等词对于区分毫无帮助而且会造成偏差。因此,需要把这些对区分类没有意义的词语筛选出来,放到停用词文件stopwords.txt中。

python 复制代码
# 写入停用词文件
import codecs

with codecs.open('./stopwords.txt', 'a', encoding='utf-8') as f:
    for items in ['ain', 'al', 'couldn', 'didn', 'doesn', 'don', 'hadn', 'hasn', 'haven', 'isn', 'll', 'mon', 'shouldn', 've', 'wasn', 'weren', 'won', 'wouldn', '几天', '上去', '手机', '就是', '屏幕', '收到', '感觉', '机子']:
        f.write(items+'\n')
    f.close()

使用jieba库的extract_tags函数,统计好评,中评,差评文本中的top 20关键词

python 复制代码
#设定停用词文件,在统计关键词的时候,过滤停用词
import jieba.analyse

jieba.analyse.set_stop_words('./stopwords.txt') 
python 复制代码
# 好评关键词
# extract_tags是用tf-idf做的
keywords_pos = jieba.analyse.extract_tags(''.join(data_cutted['Comment'][data_cutted['Class'] == 1]), topK=20)
for item in keywords_pos:
    print (item, end=' ')
复制代码
不错 正品 赠品 发货 五分 东西 很漂亮 喜欢 满意 评价 好评 很快 速度 充电 卖家 物流 漂亮 快递 流畅 手感 

经过以上步骤的处理,整个数据集的预处理工作"告一段落"。在中文文本分析和情感分析的工作中,数据预处理的内容主要是分词。只有经过分词处理后的文本数据集才可以进行下一步的向量化操作,满足输入模型的条件。

模型搭建与训练

经过分词之后的文本数据集要先进行向量化之后才能输入到分类模型中进行运算。

我们使用sklearn库实现向量化方法,去掉停用词,并将其映射到特征空间。

我们使用sklearn库中的函数直接实现SVM算法(SVC)。

为了方便,创建文本情感分析类CommentClassifier,来实现建模过程:

  • __init__为类的初始化函数。

  • fit()函数,来实现向量化与模型建立的过程。

python 复制代码
# 实现向量化方法
from sklearn.feature_extraction.text import CountVectorizer

#实现svm模型
from sklearn.svm import SVC

# 实现交叉验证
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score

# 实现评价指标
from sklearn import metrics
with open("./stopwords.txt",encoding="utf-8") as f:
    stopwords = f.read().split("\n")
python 复制代码
# 文本情感分类的类:CommentClassifier
class CommentClassifier:
    def __init__(self):
        pass

    def fit(self, train_x, train_y, max_df):
        list_text = list(train_x)
        
        self.vectorizer = CountVectorizer(max_df=max_df, stop_words = stopwords, ngram_range=(1, 3)).fit(list_text)

        self.array_trainx = self.vectorizer.transform(list_text)
        self.array_trainy = train_y

        self.model = SVC(kernel='linear', gamma=10 ** -5, C=1,class_weight="balanced").fit(self.array_trainx, self.array_trainy)
        
    def predict_value(self, test_x):
        list_text = list(test_x)
        self.array_testx = self.vectorizer.transform(list_text)
        array_predict = self.model.predict(self.array_testx)
        return array_predict
  • 使用train_test_split()函数划分训练集和测试集。训练集:80%;测试集:20%。

  • 输出分类评价结果,内容包括混淆矩阵以及含PrecisionRecallF1-score三个指标的评分矩阵

python 复制代码
#划分训练集,测试集
train_x, test_x, train_y, test_y = train_test_split(data_cutted['Comment'].ravel().astype('U'), data_cutted['Class'].ravel(),
                                                        test_size=0.2, random_state=4)

commentCls = CommentClassifier()
#max_df 设置为0.98
commentCls.fit(train_x, train_y, 0.98)
value_result = commentCls.predict_value(test_x)
print ('classification report')
print (metrics.classification_report(test_y, value_result, labels=[-1, 0, 1]))
print ('confusion matrix')
print (metrics.confusion_matrix(test_y, value_result, labels=[-1, 0, 1]))
复制代码
c:\environment\python38\lib\site-packages\sklearn\feature_extraction\text.py:409: UserWarning: Your stop_words may be inconsistent with your preprocessing. Tokenizing the stop words generated tokens ['zz'] not in stop_words.
  warnings.warn(


classification report
              precision    recall  f1-score   support

          -1       0.63      0.57      0.60       519
           0       0.51      0.46      0.48       489
           1       0.72      0.84      0.78       629

    accuracy                           0.64      1637
   macro avg       0.62      0.62      0.62      1637
weighted avg       0.63      0.64      0.63      1637

confusion matrix
[[297 139  83]
 [147 223 119]
 [ 27  75 527]]
相关推荐
weelinking1 天前
【产品】00_产品经理用Claude实现产品系列介绍
数据库·人工智能·sql·数据挖掘·github·产品经理
Godspeed Zhao1 天前
从零开始学AI16——SVM
算法·机器学习·支持向量机
哈伦20191 天前
第八章 分类 决策树案例:成年人群体收入预测
决策树·分类·数据挖掘
Hali_Botebie1 天前
岭回归(Ridge Regression),也称为L2正则化回归
数据挖掘·回归·kotlin
YangYang9YangYan1 天前
2026运营专员职场能力提升:数据分析的价值与应用
数据挖掘·数据分析
动物园猫1 天前
棉花病害图像分类数据集分享(适用于YOLO系列深度学习分类检测任务)
深度学习·yolo·分类
哈伦20191 天前
第八章 分类 朴素贝叶斯案例:P2P平台个人信用评估
分类·p2p·朴素贝叶斯
安迁岚1 天前
基于珠三角城市热岛热点核心中心点的等级化点格局分析
人工智能·arcgis·信息可视化·数据挖掘·数据分析·地统计
枫叶林FYL2 天前
【机器学习与智慧医疗】T2DM-EWS: 2型糖尿病早期预警系统(多参数集成分类模型)完整实现
人工智能·机器学习·分类