130在线民宿 UGC 数据挖掘实战--集成模型在情感分析中的应用

集成模型在情感分析中的应用

数据准备

本次实验将加载两个数据,一个是已经标注好的用户评论数据,另外一个是用户评价主题句,通过标注过的用户评论数据进行基于集成模型的情感极性模型训练,然后利用模型对主题句进行情感极性推理,最后通过数据聚合可视化得出主题情感极性。
使用 Pandas 加载在线数据表格,并查看数据维度和前 5 行数据。

import pandas as pd
data = pd.read_csv(
    'https://labfile.oss.aliyuncs.com/courses/2628/hotel_comment.csv')
print(data.shape)
data.head()

数据属性如下表所示


image.png

加载我们之前通过主题词典提取出来的主题句。

comment_topic_split = pd.read_csv(
    'https://labfile.oss.aliyuncs.com/courses/2628/8-1.csv')
print(comment_topic_split.shape)
comment_topic_split.head()

数据属性如下表所示

image.png

数据清洗
打印评论情感标注数据集上的标签统计。

data['label'].groupby(data['label']).count()

用户评论分词
jieba 分词器预热,第一次使用需要加载字典和缓存,通过结果看出返回的是分词的列表。

import jieba

' '.join(jieba.lcut(str('使用分词器进行分词')))

批量对用户评价进行分词,需要一些时间,并打印第一行情感极性训练集的分词结果。

%time data['text_cut'] = data['text'].apply(lambda x: " ".join(jieba.lcut(str(x))))
data.head(1)

批量对用户评价主题句进行分词,并打印第一句用户主题句分词结果。

%time comment_topic_split['text_cut'] = comment_topic_split['comment_cut'].apply(lambda x: " ".join(jieba.lcut(str(x))))
comment_topic_split.head(1)

情感分析模型训练

依据统计学模型假设,假设用户评论中的词语之间相互独立,用户评价中的每一个词语都是一个特征,我们直接使用 TF-IDF 对用户评价提取特征,并对提取特征后的用户评价输入分类模型进行分类,将类别输出为积极的概率作为用户极性映射即可。
用户评论向量化
TF-IDF 是一种用于信息检索与数据挖掘的常用加权技术,当某个词在文章中的TF-IDF越大,那么一般而言这个词在这篇文章的重要性会越高,比较适合对用户评论中的关键词进行量化。

# 使用 TF-IDF 的方式对用户评论特征提取
from sklearn.feature_extraction.text import TfidfVectorizer

# 设置字典中词语的数量
max_dict_number = 5000
# 对评论进行向量化
vectorizer = TfidfVectorizer(max_features=max_dict_number)

# 直接对分词后的用户评论进行特征提取
vectorizer.fit_transform(data['text_cut'])

数据集合划分
按照训练集 8 成和测试集 2 成的比例对数据集进行划分,并检查划分之后的数据集数量。

# 对测试集和训练集进行划分
from sklearn.model_selection import train_test_split

# 将 random_state 随机种子进行固定,设置为 1,每次数据划分不进行随机划分
x_train_, y_train_, x_test, y_test = train_test_split(data['text_cut'],
                                                      data['label'],
                                                      test_size=0.2,
                                                      random_state=1)

# 通过建立起来的词典,开始对训练集和测试集合进行向量化
x_train = vectorizer.transform(x_train_)
y_train = vectorizer.transform(y_train_)

模型训练

我们在系列实验的开始使用朴素贝叶斯模型来训练情感分析模型,下面我们新增逻辑回归模型作为对比模型。逻辑回归(Logistic Regression)是一种用于解决二分类问题的机器学习方法,在线性回归的基础上,套用了一个 sigmod 函数,这个函数将线性结果映射到一个概率区间,并且通常以 0.5 分界线,这就使得数据的分类结果都趋向于在 0 和 1 两端,将用户评论进行向量化之后也可以用此方式预测用户情感。本实验直接对标注过的用户情感数据进行训练,并验证单一模型和集成模型在情感分析性能上的差异。
模型加载

# 加载贝叶斯模型分类模型
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import MultinomialNB
nb = MultinomialNB()

# 加载逻辑回归分类模型
lr = LogisticRegression()

# 制作分类器字典
model_dict = {
    'lr': lr,
    'nb': nb, }

通过传入原始的标签和预测的标签可以直接将分类器性能进行度量,利用常用的分类模型评价指标对训练好的模型进行模型评价,accuracy_score 评价被正确预测的样本占总样本的比例,Precision 是衡量模型精确率的指标,它是指模型识别出的文档数与识别的文档总数的比率,衡量的是模型的查准率。Recall 召回率也称为敏感度,它是指模型识别出的相关文档数和文档库中所有的相关文档数的比率,衡量的是检索系统的查全率,表示正样本在被正确划分样本中所占的比例,f1_score 值是精确率与召回率的调和平均数,是一个综合性的指数。

from sklearn import metrics

# 使用列表收集测试结果
method, acc_list, f1_list = [], [], []

我们分别对不同模型使用相同的数据集进行训练和测试,以此来比较单模型之间的差异,并打印模型运行时间供大家参考,批量处理不同的模型需要一些时间进行计算,清耐心等待。

# 对训练进度进行可视化
from tqdm.notebook import tqdm

for model_label, model in tqdm(model_dict.items()):
    # 打印模型名字
    print(model_label)
    # 使用同一个训练集进行模型训练
    %time model.fit(x_train, x_test)

    # 对测试集预测
    model_ros_result = model.predict(y_train)

    # 收集训练标签
    method.append(model_label)

    # 收集 accuracy_score 分数
    acc_list.append(metrics.accuracy_score(y_test, model_ros_result))

    # 收集 f1 分数
    f1_list.append(metrics.f1_score(y_test, model_ros_result))

通过求得的指标进行模型评价,我们发现使用相同的数据进行模型训练,朴素贝叶斯模型和逻辑回归模型性能基本持平,相差很微弱,逻辑回归稍稍占一些优势。

result_analysis = pd.DataFrame({
    'method': method,
    'acc_list': acc_list,
    'f1_list': f1_list, })

result_analysis.head()

Stacking 堆栈模型训练
集成学习是地结合来自两个或多个基本机器学习算法的优势,学习如何最好地结合来自多个性能良好的机器学习模型的预测结果,并作出比集成中的任何一个模型更好的预测。主要分为 Bagging, Boosting 和 Stacking,Stacking 堆栈模型是集成机器学习模型的一种,具体是将训练好的所有基模型对整个训练集进行预测,然后将每个模型输出的预测结果合并为新的特征,并加以训练。主要能降低模型的过拟合风险,提高模型的准确度。

# 加载堆栈模型
from sklearn.ensemble import StackingClassifier

开始对两个模型进行集成训练,训练的时间要比单一模型时间久一些,清耐心等待。

# 集成模型
models_list = [('lr', lr), ('nb', nb)]
stacking_model = StackingClassifier(estimators=models_list)

# 开始训练
%time stacking_model.fit(x_train, x_test)

# 批量对测试集预测
model_stacking_result = stacking_model.predict(y_train)

评测结果收集。

# 收集训练标签
method.append('model_stacking')

# 收集 accuracy_score 分数
acc_list.append(metrics.accuracy_score(y_test, model_stacking_result))

# 收集 f1 分数
f1_list.append(metrics.f1_score(y_test, model_stacking_result))

结果分析
将结果存入 Dataframe 进行结果分析,lr 表示逻辑回归,nb 表示朴素贝叶斯,model_stacking 将两个单模型集成后的模型。从结果来看集成模型准确度和 f1 值都是最高的,结合两个模型的优势,整体预测性能更好,鲁棒性更好。

result_analysis = pd.DataFrame({
    'method': method,
    'acc_list': acc_list,
    'f1_list': f1_list, })

result_analysis.head()

样例测试
通过测试样例发现,分类器对正常的积极和消极判断比较好。但是当我们改变语义信息,情感模型则不能进行识别,模型鲁棒性较差。作为早期的文本分类模型,我们使用 TFIDF 的特征提取方式并不能很好的解决语义问题,自然语言是带有语序和语义的关联,其词语之间的关联关系影响整句话的情感极性,后续我们继续试验深度情感分析模型研究解决此类问题。

# 使用两个测试用例进行测试
predict_text = [
    '这家民宿环境可以的',
    '这家民宿环境真垃圾',
    '这家民宿环境我不喜欢',
    '这家民宿环境我喜欢不', ]

# 对用户评论进行向量化
test_text = vectorizer.transform(
    [" ".join(jieba.lcut(i)) for i in predict_text])

# 输出标签的概率
result = stacking_model.predict_proba(test_text)

# 直接输出用户评论对应的积极情感对应的概率值作为用户情感极性映射
[i[1] for i in result]

主题情感极性可视化

加载民宿主题数据。

comment_topic_split.head(1)

模型预测

# 对用户评论进行向量化
test_text = vectorizer.transform(comment_topic_split['text_cut'].tolist())

# 批量用户情感极性预测
%time stacking_model_result = stacking_model.predict_proba(test_text)

# 输出用户评论对应的积极情感对应的概率值作为用户情感极性映射
comment_topic_split['stacking_model_result'] = [
    i[1] for i in stacking_model_result]

将情感分析模型推理的结果写入 DataFrame 中进行聚合。

topics_list = comment_topic_split['comment_topic'].unique().tolist()
topics_list

单主题聚合分析
挑选一个主题进行主题情感分析。

topic_select = topics_list[1]

# 选取其中一主题的 topic_select 的对应的情感极性
model_score = comment_topic_split[comment_topic_split['comment_topic'] ==
                                  topic_select]['stacking_model_result']
topic_select

对民宿“设施”进行描述统计,此次我们使用主题词典的出来的用户关于民宿“设施”主体的讨论条数为 4628 条,平均用户情感极性为 0.40 表示为整体呈现不满意的情况,有超过一半的关于“设施”的民宿评论中表现用户不满意的情况,重庆民宿需要在“设施”进行改善,以此提高用户满意度。

model_score.describe()

单主题情感极性可视化
我们开始进行“设置”主题下的用户主题情感进行可视化,首先加载画图模块。

import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

# 定义画布大小
plt.rcParams['figure.figsize'] = (8.0, 8.0)

对“设施”主题下的用户情感极性进行可视化,我们利用集成模型对主题句进行情感极性预测,如下所示。

# 定义数据间隔
plt.hist(model_score, bins=np.arange(0, 1, 0.01))

# 横坐标标题为用户情感极性
plt.xlabel("topic_sa_score")

# 纵坐标标题为用户评论统计量
plt.ylabel("count")

# 定义图像标题
plt.title('Topic_Satisfaction_Analysis')
plt.show()

你可能感兴趣的:(130在线民宿 UGC 数据挖掘实战--集成模型在情感分析中的应用)