美文网首页计算机编程程序员Python学习资料整理
如何用python爬取美团点评数据并做情感分析

如何用python爬取美团点评数据并做情感分析

作者: 叶琛_ | 来源:发表于2019-03-14 14:54 被阅读114次

    自从18年10月底开始课余在导师的公司实习,不知不觉入坑机器学习和深度学习已经小半年时间。目前的主要方向是NLP和数据挖掘。

    这期间接触了许多新的知识,见识了火热的深度学习的魅力和实际应用,也认识了很多浙大的牛人,有很多感触。

    这篇文章,是对我近期做的情感分析demo的一个总结;但正因为它简单又内容丰富,相信会帮助即便外行的读者,也能对爬虫和深度学习有新的认识。

    全文共计3800余字,阅读时间预计10-20分钟不等。阅读完本文,你将学习到:

    01 如何安装使用python

    02 如何用python爬取数据

    03 如何使用pandas、numpy做简单的数据处理

    04 如何调用bert-as-service,快速得到中文词向量

    05 如何使用深度学习框架keras建模,做简单的情感分析

    01 如何安装使用Python

    安装python的方式很多,而Mac osUbuntu等操作系统甚至已经预装了python

    但是,我还是强烈推荐你安装Anaconda套装。它是一个开源的python发行版本,包含了180多个科学包及其依赖项,其中很多工具包对于后期机器学习的研究非常重要。所以第一次就安装它,可以“一劳永逸”。

    进入Anaconda官网的下载页面,可以根据你使用的系统下载最新版本的conda。如果你想下载历史版本的Anaconda,可以点击此链接

    此后,根据中文提示一步步安装即可,非常简单方便。

    image.png 安装完成后,进入终端(Windows下称“命令提示符”),我们使用conda创建一个虚拟环境,这样可以和系统中原有的python环境相隔离。

    如图,我们创建了一个python3.6版本的虚拟环境,使用conda env list可以查看我们当前所有虚拟环境(目前只有py36),然后source activate py36激活它。

    到此,python最基础的环境搭建全部完成啦。

    02 如何用python爬取数据

    学不学计算机,想必你都曾经听过“爬虫”这个词。说实话,我当初第一次听到这两个字,想到的是一群虫子在我身上爬,而起了一身鸡皮疙瘩....

    好!我们言归正传。在准备爬取数据前,我们得先对什么是爬虫有简单的了解:

    网络爬虫(Web crawler),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本,采集所有其能够访问到的页面内容(包括文本、图片、视频、音频等)

    简单的说,所谓爬虫就是用程序去自动采(爬)集(取)互联网上的公开内容。

    而爬虫之所以总是和python挂钩,是因为python这一脚本语言非常适合写爬虫代码。如果你问我有多简单?

    两行代码就完事了!

    import requests
    r = requests.get(url="http://www.baidu.com")
    

    requests库会自动向我们指定的url链接(百度)发起http请求,并将结果返回到r.content中。

    当然这只是最简单的一种情况,爬取到的内容也不过是百度首页的源码;但实际开发爬虫时的核心内容,已经在这两行代码里完美呈现了,可以说剩下的都是“点缀”。

    在我们的这个项目中,使用了一个比requests库稍复杂的框架Scrapy,它是python最火热的爬虫框架(可能没有之一),结构化的设计可以让开发人员非常方便的根据项目需求进行修改。

    如果对 Scrapy有兴趣的同学,我可以为你提供一些参考资料:

    01 Scrapy官方文档

    02 《Python爬虫开发与项目实战》

    03 构建单机千万级别的微博爬虫系统

    当然,我觉得最快的学习方式是先简单了解scrapy的理论基础(如5大组成部分),然后进行项目实战(参考微博爬虫项目,写的挺完善)。

    这里的美团点评爬虫,爬取的是杭州、上海、北京等5大城市各1000家餐馆的前200条点评(合计约100w+评论数据),通过构造访问api接口,提取json格式的数据。代码类似于长这样:

    由于本文的重点不是爬虫讲解,所以代码部分直接一带而过。

    在评论内容的筛选上,我只保留了4-5星和1-2星的评论,作为后期情感识别的训练/测试数据。

    最终爬取结果:

    我将评论数据存储到mongodb中,省去了建表的麻烦。

    如果嫌慢,我们还可以采取分布式的架构(如scrapy-redis),加快爬虫的爬取速度。

    耐心等待爬虫运行结束,去数据库中查看爬虫忠诚的为我们爬取的数据:


    爬取结果

    有了数据,接下来要做的就是数据预处理啦!

    03 使用pandas、numpy做简单的数据处理

    很多人把pandasnumpymatplotlib3个库称为python数据处理和可视化的三剑客,因为它们真的功能强大又好用。这里我们先介绍前两个,matplotlib留到第5小节。

    之前我们爬取的数据还保留在mongodb中,我们可以用mogoexport或借助数据库可视化软件将其导出到csv文件中。

    这里为了简化,我们分别导出评分5星和评分1星的评论(刚好对应正负两面情感)各6800条;在后续处理中,每种情感取6000条用作训练(包含验证集),剩余800条作为测试。

    我们分别导出的数据命名为10_star.csv50_star.csv,借助pandas库用一行代码导入,并查看前5行内容。

    import pandas as pd
    df1 = pd.read_csv('./10_star.csv')
    df2 = pd.read_csv('./10_star.csv')
    print(df1.head())
    print(df1.head())
    
    运行结果

    接下来,我们要遍历comment列的每一行,过滤其中的非中文字符;再将字数大于10的评论加入一个列表。

    数据过滤

    这是对其中的负面评论的数据处理,正面评论处理类似。最后将数据直接整合在一起:

    X_data = X_data1[:6000] + X_data2[:6000]              # 训练数据
    X_test_data = X_data1[6000:6800] + X_data2[6000:6800]      # 测试数据
    

    请注意,这里我们保证了X_data前6000条数据是负面的(来自X_data1),后6000条是正面的(来自X_data2)。X_test_data也同理。

    得到训练数据后,我们手工创建一个labels数组(训练标签),前6000个元素是0,后6000个元素是1;再通过numpy库转换为numpy数组,便于后期输入到神经网络中。

    import numpy as np
    y_data = [0 for i in range(6000)] + [1 for i in range(6000)]
    y_data = np.asarray(y_data, dtype=np.float32)
    y_test_data = [0 for i in range(800)] + [1 for i in range(800)]
    y_test_data = np.asarray(y_data, dtype=np.float32)
    

    现在,聪明的你可能发现一个问题:我们的数据太有规律啦,正负情感刚好前后各占了一半;假如我们输入了前3000条到模型中,机器“机智的”全判断为负面,能证明准确率就有100%了?

    为了避免数据分布不规律的现象,我们需要为数据进行“洗牌”(随机打乱)。

    还是借助numpy,我们可以轻松实现这一过程。

    X_train = []
    y_train = []
    X_test = []
    y_test = []
    
    nums = np.arange(12000)
    # 随机打乱12000个训练数据
    np.random.shuffle(nums)
    for i in nums:
        X_train.append(X_data[i])
        y_train.append(y_data[i])
    
    # 随机打乱1600个测试数据
    nums_ = np.arange(1600)
    np.random.shuffle(nums_)  # shuffle改变的是自身的内容
    for i in nums_:
        X_test.append(X_test_data [i])
        y_test.append(y_test_data [i])
    
    # list转Numpy数组
    X_train= np.asarray(X_train, dtype=np.float32)
    X_test= np.array(X_test, dtype=np.float32)
    

    到此为止,简单的数据预处理就结束了,是不是可以开始搭建我们的神经网络模型了?

    别急!这儿我们的数据还全都是中文,即便是英文字母,计算机也一概不认识。所以,一位重量级的选手马上就要登场和我们见面了。👏👏

    04 调用bert-as-service,快速得到中文词向量

    在自然语言处理任务中,首先需要考虑词如何在计算机中表示。常见的表示方法有两种

    01 one-hot representation (独热编码)

    02 distribution representation

    第一种是离散的表示方法,得到的是高维度的稀疏矩阵;第二种方法(Word Embedding)则是将词表示成定长的连续稠密向量。想深入的同学,请利用好您的搜索引擎(上网搜!)

    从头训练一个有效的语言模型是耗时又耗能的过程。学习NLP的同学,一定知道去年底Google发布的Bert模型。

    本例中,我们借助腾讯AI实验室发布的bert-as-service接口,让你能简单的通过两行代码,即可使用预训练好的bert模型生成句向量和ELMO风格的词向量。

    关于bert-as-service的官方介绍,可以点击查看作者:肖涵博士的Git仓库

    我们来看一看这两行代码是怎么实现的?

    from bert_serving.client import BertClient
    bc = BertClient
    # 将待训练的中文数据转换为(,768)维的句向量
    input_train = bc.encode(X_train)
    

    觉得上面的内容不能马上看懂?

    没关系,送上免费学习传送门:两行代码玩转Google BERT句向量词向量。写的很详细哦!

    bert-as-service将一个句子统一转换成768维的句向量;最终我们得到的就是12000 * 768维度的句向量矩阵,也就是我们将输入到神经网络模型的真正数据。

    05 使用Keras,实现简单的情感分析模型

    虽然我们这里跑的只是一个很小的demo,但是数据处理部分依然是整个工程中最耗时间的部分;实际开发中也往往如此。

    有了处理后的数据,后边的路一下畅通了许多,尤其是有keras这样容易上手的工具。

    Keras是一个高层神经网络API,由纯python编写并使用Tensorflow,Theano,CNTK作为后端,以简介、快速为设计原则。

    直接使用pip即可快速安装KerasTensorflow

    $ pip install keras
    $ pip install tensorflow
    

    典型的Keras工作流程大致可以分为四步:

    (1) 定义训练数据:输入张量和目标张量。
    (2) 定义层组成的网络(或模型),将输入映射到目标。
    (3) 配置学习过程:选择损失函数、优化器和需要监控的指标。
    (4) 调用模型的 fit 方法在训练数据上进行迭代

    我们直接使用使用Sequential类来定义模型(仅用于层的线性堆叠,是最常见的网络架构)。

    from keras.models import Sequential
    from keras.layers import Dense, Dropout
    import tensorflow as tf
    model = Sequential()
    # 搭建模型
    model.add(Dense(32, activation='relu', input_shape=(768,)))
    model.add(Dropout(0.3))
    model.add(Dense(32, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    

    对于简单的二分类问题,模型使用Dense全连接层拼接已经够用,最后的输出就是一个数,代表了正面/负面情感的概率。同时防止过拟合,在模型中加入了Dropout层,

    接下来,我们来指定模型使用的优化器和损失函数,以及训练过程中想要监控的指标。

    model.compile(
        loss='binary_crossentropy',
        optimizer=tf.train.AdamOptimizer(),
        metrics=['acc']
    )
    

    最后,通过fit方法将输入数据的Numpy数组传入模型;请注意,我们留出了20%的数据作为验证集:

    history = model.fit(
        X_train, y_train,
        epochs=30,
        batch_size=128,
        validation_split=0.2,
        verbose=1
    )
    

    我们的模型就开始愉快的迭代训练啦!

    训练过程可视化
    可以观察到,随着迭代次数增加,模型的损失loss逐渐下降,准确度acc逐渐上升,直到最终趋于稳定,与我们的预期完全一致。

    运行结束后,我们使用matplotlib库将结果可视化吧~

    import matplotlib.pyplot as plt
    history_dict = history.history
    epochs = range(1, len(history_dict['acc']) + 1)
    # 绘图部分
    plt.figure()
    plt.plot(epochs, history_dict['acc'], 'b', label='acc')
    plt.plot(epochs, history_dict['val_acc'], 'bo', label='val_acc')
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy')
    plt.legend()
    plt.show()
    

    分别画出训练过程中损失和精确度的变化,可以知道我们的模型确实从输入数据中有效“学习”到了情感识别的模式。

    image.png
    因为训练数据不算太少,又加入了dropout预防过拟合,同时任务本身不算复杂,保证了我们的模型对于美团点评数据是好评还是差评有了96%的准确率!通过调参和加大模型的复杂度,这一结果应该会更高。

    别忘了我们还有1600条数据被当作测试集还没使用,也就是说模型还没有“见过”这批数据。是时候派他们上场了!

    调用evaluate方法实验我们的测试数据:

    test_loss = model.evaluate(
        X_test,
        y_test,
        batch_size=63,
        verbose=1
    )
    print(test_loss)
    

    得到结果:
    [0.07956909381508012, 0.9731250016018749]

    它表示训练损失和准确率分别为0.0797%


    小结

    本文带你了解了如何安装使用python,如何使用python爬取数据(构造爬虫),如何处理数据以及使用Keras训练模型,让最后的结果可视化。

    可能涉及的内容比较多,又限于篇幅,对各个模块的内容只是管中窥豹,简要带过。

    其实,这里很多模块的内容远不是一篇文章,甚至一本书就能全面详细介绍的(如对于爬虫的反爬措施部分,就可以写一本书)。如果大家愿意看,笔者会持续更新本专题下的文章。对于本文谈论的内容,你有没有什么不同的意见或者更好的建议?欢迎留言!

    喜欢请不要吝啬于点赞哈。

    相关文章

      网友评论

        本文标题:如何用python爬取美团点评数据并做情感分析

        本文链接:https://www.haomeiwen.com/subject/bgfwpqtx.html