编程语言
首页 > 编程语言> > Python 爬完评论只会做词云?情感分析了解一下

Python 爬完评论只会做词云?情感分析了解一下

作者:互联网

一、SnowNLP 简介

SnowNLP是一个python写的类库,可以方便的处理中文文本内容,是受到了TextBlob的启发而写的,由于现在大部分的自然语言处理库基本都是针对英文的,于是写了一个方便处理中文的类库,并且和TextBlob不同的是,这里没有用NLTK,所有的算法都是自己实现的,并且自带了一些训练好的字典。注意本程序都是处理的unicode编码,所以使用时请自行decode成unicode编码。

SnowNLP github地址:https://github.com/isnowfy/SnowNLP

# 安装
pip install SnowNLP

当然,我们也可以采用豆瓣源加速

pip install SnowNLP -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

二、SnowNLP 特性

简单说一下SnowNLP 的特性

三、SnowNLP库的基本使用

from SnowNLP import SnowNLP

word = u'这个姑娘真好看'
s = SnowNLP(word)
print(s.words)        # 分词
print(list(s.tags))   # 词性标注
print(s.sentiments)   # 情感分数
print(s.pinyin)       # 拼音
print(SnowNLP(u'蒹葭蒼蒼,白露為霜。所謂伊人,在水一方。').han)  # 繁体字转简体

运行结果如下:

['这个', '姑娘', '真', '好看']
[('这个', 'r'), ('姑娘', 'n'), ('真', 'd'), ('好看', 'a')]
0.9002381975487243
['zhe', 'ge', 'gu', 'niang', 'zhen', 'hao', 'kan']
蒹葭苍苍,白露为霜。所谓伊人,在水一方。
from SnowNLP import SnowNLP

text = u'''
自然语言处理是计算机科学领域与人工智能领域中的一个重要方向。
它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。
自然语言处理是一门融语言学、计算机科学、数学于一体的科学。
因此,这一领域的研究将涉及自然语言,即人们日常使用的语言,
所以它与语言学的研究有着密切的联系,但又有重要的区别。
自然语言处理并不是一般地研究自然语言,
而在于研制能有效地实现自然语言通信的计算机系统,
特别是其中的软件系统。因而它是计算机科学的一部分。
'''

s = SnowNLP(text)

print(s.keywords(limit=3))        # 关键词提取
print('--------------------------------')
summary = s.summary(limit=4)      # 文本概括
for i in summary:
    print(i)

print('--------------------------------')

print(s.sentences)        # 句子

运行结果如下:

['语言', '自然', '计算机']
--------------------------------
因而它是计算机科学的一部分
自然语言处理是计算机科学领域与人工智能领域中的一个重要方向
自然语言处理是一门融语言学、计算机科学、数学于一体的科学
所以它与语言学的研究有着密切的联系
--------------------------------
['自然语言处理是计算机科学领域与人工智能领域中的一个重要方向', '它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法', '自然语言处理是一门融语言学、计算机科学、数学于一体的科学', '因此', '这一领域的研究将涉及自然语言', '即人们日常使用的语言', '所以它与语言学的研究有着密切的联系', '但又有重要的区别', '自然语言处理并不是一般地研究自然语言', '而在于研制能有效地实现自然语言通信的计算机系统', '特别是其中的软件系统', '因而它是计算机科学的一部分']

Process finished with exit code 0
# 评价词语对文本的重要程度
# TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。
# TF词频越大越重要,但是文中会的“的”,“你”等无意义词频很大,却信息量几乎为0,这种情况导致单纯看词频评价词语重要性是不准确的。因此加入了idf
# IDF的主要思想是:如果包含词条t的文档越少,也就是n越小,IDF越大,则说明词条t越重要
# TF-IDF综合起来,才能准确的综合的评价一词对文本的重要性。

from SnowNLP import SnowNLP


s = SnowNLP([[u'这篇', u'文章', u'写得', u'不错'],
             [u'那篇', u'论文', u'好'],
             [u'这个', u'东西', u'好吃']])
print(s.tf)     # tf 意思是词频(Term Frequency)
print('---------------------------------------------------')
print(s.idf)    # idf 意思是逆文本频率指数(Inverse Document Frequency)
print('-----------------------------------------------------')
# 文本相似度
print(s.sim([u'文章']))
print(s.sim([u'好']))

运行结果如下:

[{'这篇': 1, '文章': 1, '写得': 1, '不错': 1}, {'那篇': 1, '论文': 1, '好': 1}, {'这个': 1, '东西': 1, '好吃': 1}]
---------------------------------------------------
{'这篇': 0.5108256237659907, '文章': 0.5108256237659907, '写得': 0.5108256237659907, '不错': 0.5108256237659907, '那篇': 0.5108256237659907, '论文': 0.5108256237659907, '好': 0.5108256237659907, '这个': 0.5108256237659907, '东西': 0.5108256237659907, '好吃': 0.5108256237659907}
-----------------------------------------------------
[0.4686473612532025, 0, 0]
[0, 0.5348959411162205, 0]

# 关于训练
# 现在提供训练的包括分词,词性标注,情感分析,都是用的SnowNLP库自带的原始文件 以分词为例 分词在SnowNLP/seg目录下

from SnowNLP import seg

sentiment.train('neg.txt', 'pos.txt')
seg.save('seg.marshal')

# 这样训练好的文件就保存为seg.marshal了,之后修改SnowNLP/seg/__init__.py里的data_path指向刚训练好的文件即可

四、NLP测试

1. 获取数据

URL:https://item.jd.com/100000499657.html#none

图片爬取部分好评、中评和差评数据,分别保存到三个txt里。

import asyncio
import aiohttp
import re
import logging
import datetime

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s: %(message)s')
start = datetime.datetime.now()

class Spider(object):
    def __init__(self):
        # 设置最大信号量
        self.semaphore = asyncio.Semaphore(6)
        # 伪装请求头
        self.header = {
            "Host": "club.jd.com",
            "Cookie": "shshshfpa=c003ed54-a640-d73d-ba32-67b4db85fd3e-1594895561; shshshfpb=i5%20TzLvWAV56AeaK%20C9q5ew%3D%3D; __jdu=629096461; unpl=V2_ZzNtbUVRFkZ8DUddfRxcBGIEE1hKXhBGIQEVVnNLD1IwBkBeclRCFnQUR1JnGloUZwEZXkZcQxVFCEdkeR1ZAmYBEV1yZ0IXJQ4SXS9NVAZiChAJQAdGFnJfRFQrGlUAMFdACUtVcxZ1OEdkfBpUBG8EF1pCZ3MVfQ92ZDBMAGshQlBtQldEEXAKTlZyGGwEVwMTWUFXQxZ1DkFkMHddSGAAGlxKUEYSdThGVXoYXQVkBBVeclQ%3d; __jdv=122270672|baidu|-|organic|not set|1596847892017; areaId=0; ipLoc-djd=1-72-55653-0; PCSYCityID=CN_0_0_0; __jda=122270672.629096461.1595821561.1596847892.1597148792.3; __jdc=122270672; shshshfp=4866c0c0f31ebd5547336a334ca1ef1d; 3AB9D23F7A4B3C9B=DNFMQBTRNFJAYXVX2JODGAGXZBU3L2TIVL3I36BT56BKFQR3CNHE5ZTVA76S56HSJ2TX62VY7ZJ2TPKNIEQOE7RUGY; jwotest_product=99; shshshsID=ba4014acbd1aea969254534eef9cf0cc_5_1597149339335; __jdb=122270672.5.629096461|3.1597148792; JSESSIONID=99A8EA65B8D93A7F7E8DAEE494D345BE.s1",
            "Connection": "keep-alive",
            "Referer": "https://item.jd.com/4803334.html",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36"

        }

    async def scrape(self, url):
        async with self.semaphore:
            session = aiohttp.ClientSession(headers=self.header)
            response = await session.get(url)
            result = await response.text()
            await session.close()
            return result

    async def scrape_page(self, page):
        # 分别手动改变score参数 score=3 score=2 score=1  爬取好评 中评 差评数据
        url = f'https://club.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98&productId=100000499657&score=3&sortType=6&page={page}&pageSize=10&isShadowSku=0&fold=1'
        text = await self.scrape(url)
        await self.parse(text)

    async def parse(self, text):
        # 正则匹配提取数据
        content = re.findall('"guid":".*?","content":"(.*?)"', text)
        # 保存到txt
        with open('好评.txt', 'a+') as f:
            for con in content:
                f.write(con + '\n')
                logging.info(con)

    def main(self):
        # 爬取50页的数据
        scrape_index_tasks = [asyncio.ensure_future(self.scrape_page(page)) for page in range(0, 50)]
        loop = asyncio.get_event_loop()
        tasks = asyncio.gather(*scrape_index_tasks)
        loop.run_until_complete(tasks)


if __name__ == '__main__':
    spider = Spider()
    spider.main()
    delta = (datetime.datetime.now() - start).total_seconds()
    print("用时:{:.3f}s".format(delta))

2. 处理数据

from pathlib import Path
import pandas as pd

# 获取当前目录下 有好评 中评 差评数据的txt
p = Path(r'D:\python\pycharm2020\program\数据分析\中文情感分析')
review_txt = list(p.glob('**/*.txt'))
all_data = pd.DataFrame()
for item in review_txt:
    emotion = item.stem     # 获取文件名 除后缀的部分
    with Path(item).open(mode='r') as f:
        con = f.read().split('\n')
    data = pd.DataFrame({'评论内容': con, '标签': [emotion] * len(con)})
    all_data = all_data.append(data)

all_data.to_excel('评论数据.xlsx', index=False)

3. NLP测试

from SnowNLP import SnowNLP
import pandas as pd
import re

# 读取数据
df = pd.read_excel('评论数据.xlsx', encoding='utf-8')
# print(df.info())
# 去掉空值的列
df = df.dropna(axis=0)
content = df['评论内容']

# 去除一些无用的字符   只提取出中文出来
content = [' '.join(re.findall('[\u4e00-\u9fa5]+', item, re.S)) for item in content]
scores = [SnowNLP(i).sentiments for i in content]
emotions = []
for i in scores:
    if i >= 0.75:
        emotions.append('好评')
    elif 0.45 <= i < 0.75:
        emotions.append('中评')
    else:
        emotions.append('差评')

df['情感分数'] = scores
df['情感'] = emotions
df.to_excel('NLP测试后数据.xlsx')
import pandas as pd

df = pd.read_excel('NLP测试后数据.xlsx')
# 看准确率   通过SnowNLP情感打分 设置梯度得出的情感 好评 中评 差评 与实际标签相比较
data = df[df['标签'] == df['情感']]
print('准确率为:{:.2%}'.format(len(data) / len(df)))

运行结果

运行结果如下:
准确率为:71.56%

Process finished with exit code 0


标签:__,0.5108256237659907,只会,Python,self,SnowNLP,词云,print,自然语言
来源: https://blog.51cto.com/u_15127540/2698974