【项目实战】Python实现循环神经网络SimpleRNN、LSTM进行淘宝商品评论情感分析(含爬虫程序)

2023-11-01

说明:这是一个机器学习实战项目(附带数据+代码),如需数据+完整代码可以直接到文章最后获取。

 

1.项目背景

      随着信息化社会的发展,互联网成为方便、快捷的信息获取渠道之一。在电子商务和社会网站中,大量非结构化的评论文本作为最直观的用户体验数据被保存下来。如何利用这些文字信息归纳出用户对某一事、物的观点态度成为自然语言(NLP)领域一项重要任务。

      文本情感分析又称文本意见挖掘,是自然语言处理领域最优吸引力的研究方向之一。文本情感分析通过计算语言学知识量化处理得到一段文字的观点态度和情感倾向。

      淘宝作为一个电子商务平台,越来越受欢迎,2020年天猫双十一营业额超过3000多亿。商家销售的商品更是不计其数,每个商品的评论更是非常之多,本项目就是针对商品的评论数据通过建立循环神经网络模型进行情感倾向的分析。

2.数据采集

通过Python撰写爬虫程序,爬取天猫华为手机商品的评论数据。

爬取的数据集如下:

数据集:data_comment.xlsx

数据字段包括:nickname、ratedate、auctionSku、ratecontent

在实际应用中,根据自己的数据进行替换即可。

特征数据:评论文本

标签数据:情感倾向(好评(2)、中评(1)、差评(0))

作为演示,我只弄了75条特征、标签数据,所以最后模型评估的时候,测试集再100次训练下出现了过拟合。

爬虫代码详见:爬虫.py

def GetInfo(num):
    # 定义需要的字段
    nickname = []
    auctionSku = []
    ratecontent = []
    ratedate = []
    # 循环获取每一页评论
    for i in range(num):
        # 头文件,没有头文件会返回错误的js
        headers = {
            'cookie': 'cna=qMU/EQh0JGoCAW5QEUJ1/zZm; enc=DUb9Egln3%2Fi4NrDfzfMsGHcMim6HWdN%2Bb4ljtnJs6MOO3H3xZsVcAs0nFao0I2uau%2FbmB031ZJRvrul7DmICSw%3D%3D; lid=%E5%90%91%E6%97%A5%E8%91%B5%E7%9B%9B%E5%BC%80%E7%9A%84%E5%A4%8F%E5%A4%A9941020; otherx=e%3D1%26p%3D*%26s%3D0%26c%3D0%26f%3D0%26g%3D0%26t%3D0; hng=CN%7Czh-CN%7CCNY%7C156; x=__ll%3D-1%26_ato%3D0; t=2c579f9538646ca269e2128bced5672a; _m_h5_tk=86d64a702eea3035e5d5a6024012bd40_1551170172203; _m_h5_tk_enc=c10fd504aded0dc94f111b0e77781314; uc1=cookie16=V32FPkk%2FxXMk5UvIbNtImtMfJQ%3D%3D&cookie21=U%2BGCWk%2F7p4mBoUyS4E9C&cookie15=UtASsssmOIJ0bQ%3D%3D&existShop=false&pas=0&cookie14=UoTZ5bI3949Xhg%3D%3D&tag=8&lng=zh_CN; uc3=vt3=F8dByEzZ1MVSremcx%2BQ%3D&id2=UNcPuUTqrGd03w%3D%3D&nk2=F5RAQ19thpZO8A%3D%3D&lg2=U%2BGCWk%2F75gdr5Q%3D%3D; tracknick=tb51552614; _l_g_=Ug%3D%3D; ck1=""; unb=3778730506; lgc=tb51552614; cookie1=UUBZRT7oNe6%2BVDtyYKPVM4xfPcfYgF87KLfWMNP70Sc%3D; login=true; cookie17=UNcPuUTqrGd03w%3D%3D; cookie2=1843a4afaaa91d93ab0ab37c3b769be9; _nk_=tb51552614; uss=""; csg=b1ecc171; skt=503cb41f4134d19c; _tb_token_=e13935353f76e; x5sec=7b22726174656d616e616765723b32223a22393031623565643538663331616465613937336130636238633935313935363043493362302b4d46454e76646c7243692b34364c54426f4d4d7a63334f44637a4d4455774e6a7378227d; l=bBIHrB-nvFBuM0pFBOCNVQhjb_QOSIRYjuSJco3Wi_5Bp1T1Zv7OlzBs4e96Vj5R_xYB4KzBhYe9-etui; isg=BDY2WCV-dvURoAZdBw3uwj0Oh2yUQwE5YzQQ9qAfIpm149Z9COfKoZwV-_8q0HKp',
            'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
            'referer': 'https://detail.tmall.com/item.htm?spm=a1z10.5-b-s.w4011-17205939323.51.30156440Aer569&id=41212119204&rn=06f66c024f3726f8520bb678398053d8&abbucket=19&on_comment=1&sku_properties=134942334:3226348',
            'accept': '*/*',
            'accept-encoding': 'gzip, deflate, br',
            'accept-language': 'zh-CN,zh;q=0.9'
        }
        # 解析JS文件内容
        content = requests.get(COMMENT_PAGE_URL[i], headers=headers).text
        print(content)
        nk = re.findall('"displayUserNick":"(.*?)"', content)
        nickname.extend(nk)
        # print(nk)
        auctionSku.extend(re.findall('"auctionSku":"(.*?)"', content))
        ratecontent.extend(re.findall('"rateContent":"(.*?)"', content))
        ratedate.extend(re.findall('"rateDate":"(.*?)"', content))

    data = pd.DataFrame(columns=['nickname', 'ratedate', 'auctionSku', 'ratecontent'])
    data['nickname'] = nickname
    data['ratedate'] = ratedate
    data['auctionSku'] = auctionSku
    data['ratecontent'] = ratecontent
    print(data.head())
    data.to_excel('data_comment_zcy.xlsx', index=False, encoding='utf-8')

3.数据预处理

爬虫爬取下来的数据格式如下:

用户户没有意义,直接去掉;日期转换为以天为单位;auctionSku字段以分号进行分割拆分为网络类型、机身颜色、套餐类型、存储容量4个数据项,方便后续进行数据分析,清洗后的数据如下:

 4.探索性数据分析

1)按月统计订单完成交易时间的订单个数:

通过上图可以看到,2021年8月份完成订单交易最多,其次是2021年6月份。

data_group = df_data.groupby('月份').count()

data_group['ratecontent'].plot(kind='pie', title='按月统计订单完成交易时间的订单个数')
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
plt.show()

2)按机型类型进行统计分析:

上图可以看到,SA/NSA双模(5G)、亮黑色、套餐一、8+256GB最多。

data_group = df_data.groupby(['网络类型', '机身颜色', '套餐类型', '存储容量']).count()

data_group['ratecontent'].plot(kind='bar', title='按机型类型进行统计分析')
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
plt.show()

3)按机身颜色进行统计分析:

从上图可以看出,亮黑色最受欢迎。

data_group = df_data.groupby(['机身颜色']).count()

data_group['ratecontent'].plot(kind='barh', title='按机身颜色进行统计分析')
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
plt.show()

3)按存储容量进行统计分析:

从上图可以看出,大部分人都喜欢大容量的。

data_group = df_data.groupby(['存储容量']).count()

data_group['ratecontent'].plot(kind='pie', title='按存储容量进行统计分析')
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
plt.show()

4)制作评论数据词云图

分词:

 

def SegText():
    import jieba

    # 待分词的文本路径
    sourceTxt = 'source.txt'
    # 分好词后的文本路径
    targetTxt = 'target.txt'

    # 对文本进行操作
    with open(sourceTxt, 'r', encoding='utf-8') as sourceFile, open(targetTxt, 'a+', encoding='utf-8') as targetFile:
        for line in sourceFile:
            seg = jieba.cut(line.strip(), cut_all=False)
            # 分好词之后之间用/隔断
            output = '/'.join(seg)
            targetFile.write(output)
            targetFile.write('\n')
        print('写入成功!')
        sourceFile.close()
        targetFile.close()

词频统计:

词云图:

def Word_Cloud():  # 输出词频前N的词语并且以str的形式返回
    txt = open("shuchu.txt", "r", encoding='utf-8').read()  # 打开txt文件,要和python在同一文件夹
    words = jieba.lcut(txt)  # 精确模式,返回一个列表
    counts = {}  # 创建字典
    for word in words:
        if len(word) == 1:  # 把意义相同的词语归一
            continue
        elif word == "三炮" or  word == "#" or word== "##" or word=="24" or word=="RAP" or word=="video":
            rword = " "
        else:
            rword = word
        counts[rword] = counts.get(rword, 0) + 1  # 字典的运用,统计词频
    items = list(counts.items())  # 返回所有键值对P168
    items.sort(key=lambda x: x[1], reverse=True)  # 降序排序
    N = eval(input("请输入N:代表输出的数字个数")) # 这里输入300就行,因为shuchu01.txt里面的数据有限
    wordlist = list() # 创建列表并赋值
    for i in range(N):
        word, count = items[i]
        #   print("{0:<10}{1:<5}".format(word, count))  # 输出前N个词频的词语
        wordlist.append(word)  # 把词语word放进一个列表
    a = ' '.join(wordlist)  # 把列表转换成str wl为str类型,所以需要转换
    return a


def create_word_cloud():
    wl = Word_Cloud()  # 调用函数获取str!!
    # 图片名字 需一致
    cloud_mask = np.array(Image.open("love.jpg"))  # 词云的背景图,需要颜色区分度高

    wc = WordCloud(
        background_color="black",  # 背景颜色
        mask=cloud_mask,  # 背景图cloud_mask
        max_words=100,  # 最大词语数目
        font_path='simsun.ttf',  # 调用font里的simsun.tff字体,需要提前安装
        height=1200,  # 设置高度
        width=1600,  # 设置宽度
        max_font_size=1000,  # 最大字体号
        random_state=1000,  # 设置随机生成状态,即有多少种配色方案

5.特征工程

1)用Tokenizer给文本分词

评论句子已经被分解为单词

每个单词已经被分配一个唯一的词典索引

分词后输出的值是列表类型的数据:

 

2)通过直方图显示各条评论中单词个数的分布情况

上图中的评论长度分布情况表明多数评论的词数在5以内,所以我们只需要处理前5个词,就能够判定绝大多数评论的类型。如果这个数目太大,那么将来构造出的词嵌入张量就达不到密集矩阵的效果。

word_per_comment = [len(comment) for comment in X_train_tokenized_lst]
plt.hist(word_per_comment, bins=np.arange(0, 5, 0.2))  # 显示评论长度分布
plt.show()

6.LSTM建模

1)建立LSTM分类模型,模型参数如下:

编号

参数

1

loss=' sparse_categorical_crossentropy '

2

optimizer='adam'

3

metrics=['acc']

其它参数根据具体数据,具体设置。

2)神经网络概要

可以看到每层网络的类型、形状和参数。

一些其它的神经元图可以自行画。

3)训练过程展示

lstm = Sequential()  # 贯序模型
lstm.add(Embedding(dictionary_size, embedding_vecor_length,
                   input_length=max_comment_length))  # 加入词嵌入层
lstm.add(LSTM(100))  # 加入LSTM层
lstm.add(Dense(10, activation='relu'))  # 加入全连接层
lstm.add(Dense(3, activation='softmax'))  # 加入分类输出层
lstm.compile(loss='sparse_categorical_crossentropy',  # 损失函数
             optimizer='adam',  # 优化器
             metrics=['acc'])  # 评估指标
history = lstm.fit(X_train, y,
                   validation_split=0.3,
                   epochs=100,
                   batch_size=64)

7.模型评估  

 1)损失和准确率图

通过上图可以看到,针对测试集 训练100次有些过拟合了,主要原因是总共我只做了75条数据,训练集数据太少。实际操作中,数据集是远远大于这个的。

其它一些评估方法,大家可以自行选择。

def show_history(history):
    loss = history.history['loss']
    val_loss = history.history['val_loss']
    epochs = range(1, len(loss) + 1)
    plt.figure(figsize=(12, 4))
    plt.subplot(1, 2, 1)
    plt.plot(epochs, loss, 'r', label='Training loss')
    plt.plot(epochs, val_loss, 'b', label='Test loss')
    plt.title('Training and Test loss')
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.legend()
    acc = history.history['acc']
    val_acc = history.history['val_acc']
    plt.subplot(1, 2, 2)
    plt.plot(epochs, acc, 'r', label='Training acc')
    plt.plot(epochs, val_acc, 'b', label='Test acc')
    plt.title('Training and Test accuracy')
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy')
    plt.legend()
    plt.show()

8.实际应用

 在日常电子商务运营中,会出现新的评价数据,然后就可以运用此模型进行预测,准确定位客户对产品的评价,然后针对不同的客户要求来进行优化产品以及针对性营销。

本次机器学习项目实战所需的资料,项目资源如下:https://download.csdn.net/download/weixin_42163563/21987564

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【项目实战】Python实现循环神经网络SimpleRNN、LSTM进行淘宝商品评论情感分析(含爬虫程序) 的相关文章

随机推荐

  • 详细讲解插入排序(JavaScript实现)

    function insertSort alist let preindex current for let i 1 i
  • webpack打包原理解析

    文章目录 webpack打包是如何运行的 webpack对CommonJS的模块化处理 webpack对es6 Module模块化的处理 webpack文件的按需加载 按需加载输出代码分析 总结 webpack打包是如何运行的 也可以称为
  • Nacos框架服务主动下线原理及源代码讲解

    原理 Nacos没有想eureka一样 在服务端提供API供调用进行服务下线 Nacos的实现方式是通过在客户端提供方法 我们自己封装API进行调用 然后客户端会进行2个步骤 1 如果是临时服务 客户端会把自己发送续约保活心跳的缓存实例给删
  • window.open对storage有没有影响?

    首先在浏览器开发者模式打印如下信息 设置storage存值 sessionStorage setItem aaa 111 localStorage setItem bbb 222 新开一个浏览器窗口 在开发者模式打印窗口获取上一个窗口存储的
  • JAVA算法(分糖果)

    题目描述 有n个小朋友围坐成一圈 老师给每个小朋友随机发偶数个糖果 然后进行下面的游戏 每个小朋友都把自己的糖果分一半给左手边的孩子 一轮分糖后 拥有奇数颗糖的孩子由老师补给1个糖果 从而变成偶数 反复进行这个游戏 直到所有小朋友的糖果数都
  • 版本记录总结

    对构建中使用的版本进行记录
  • 【vue】this.$router.replace跳转不起作用 Router push or replace not working

    项目场景 商城APP底部导航切换对应页面 问题描述 提示 这里描述项目中遇到的问题 Just sit there clicking the home btn watching log show me home but never getti
  • Git远程库代码回退

    一 首先认识两个回退过程中很重要的命令 1 git log 显示所有提交过的版本信息 不包括已经被删除的 commit 记录和 reset 的操作 空格向下翻页 b 向上翻页 q 退出 git log pretty oneline git
  • 华为od机试 C++ 【计算最少步数】

    题目 小明计划在周末去爬山 他有一份包含山峰高度的地图 其中 0 代表平地 而 1 到 9 表示不同的山峰高度 小明可以向上 下 左或右移动一步 但是 由于他不想爬得太累 他决定只在高度差不超过 k 的地方移动 现在他站在地图的左上角 你能
  • 做好五年不跳槽的准备

    入职半年了 我觉得这里可以长久发展 其一 工作能胜任 我感觉找回自信了 甚至有些傲娇了 说明osg确实比较对口 做擅长的工作 会越做越有信心 其二 老大靠谱 老大十几年经验 并且很有耐心 工作方式也对 比如 先给你代码 在这个基础上改 并且
  • 超长整数相加

    链接 https www nowcoder com questionTerminal 5821836e0ec140c1aa29510fd05f45fc orderByHotValue 1 mutiTagIds 640 643 page 6
  • Python数据挖掘 数据预处理案例(以航空公司数据为例)

    Python数据预处理 一 内容 1 数据清洗 2 数据集成 3 数据可视化 二 实验数据 根据航空公司系统内的客户基本信息 乘机信息以及积分信息等详细数据 依据末次飞行日期 LAST FLIGHT DATE 以2014年3月31日为结束时
  • go build遇见“module *** found, but does not contain package ***”

    在实际项目中编译版本时遇见以下问题 common middleware sentinel go 4 2 module github com alibaba sentinel golang latest found v1 0 2 but do
  • SSH项目所需jar包下载地址

    struts2下载地址 http pan baidu com s 1c0joXbi hibernate下载地址 http pan baidu com s 1c0ues1a spring下载地址 http pan baidu com s 1b
  • JS学习篇(一)—— 数据类型篇

    JS学习篇 一 数据类型篇 JS的有八种数据类型 七种基本类型 undefined null Boolean number string symbol bigint 一种引用类型 object 七种基本类型 1 undefined 定义 通
  • (新)关于修改window.navigator.webdriver代码失效问题

    文章目录 前文回顾 溯源追根 解决方案 新登陆代码 写在最后 前文回顾 前面写过两篇关于sycm自动化爬取的文章 关于抓取代码的文章链接 出师未捷身先死的sycm数据自动化 关于chrome版本迭代后 代码失效问题解决方案的文章链接 关于修
  • mysql8.0一 服务启动

    声明 本文 禁止转载 本文所有观点和概念都系个人总结 难免存在疏漏之处 为不至于诱导初学者误入歧途 望各位以自己实践为准 特此声明 如有错误请告知 启动 流程 windows 7系统 创建data空目录 创建my ini文本文件 内容如下
  • Mac如何通过Xcode安装GCC编译器 How to install gcc on mac with xcode

    什么是GCC GCC GNU Compiler Collection 是由自由软件基金会 FSF Free Software Foundation Inc 研发的开源编译器集合 用一句话说 GCC就是除Windows以外的平台上使用最广的编
  • Java反射copy对象源到目标

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 使用反射机制 二 使用步骤 1 引入库 2 Copy数据 3 Fields 自定义注解 总结 前言 例如 随着很多流行的框架出现 反射也成了其中必不可少的
  • 【项目实战】Python实现循环神经网络SimpleRNN、LSTM进行淘宝商品评论情感分析(含爬虫程序)

    说明 这是一个机器学习实战项目 附带数据 代码 如需数据 完整代码可以直接到文章最后获取 1 项目背景 随着信息化社会的发展 互联网成为方便 快捷的信息获取渠道之一 在电子商务和社会网站中 大量非结构化的评论文本作为最直观的用户体验数据被保