这次要做的就是分四步完成爬取评论数据并进行可视化的评论内容分析。先展示一下预期效果
第一步:爱奇艺《青春有你2》评论数据爬取(参考链接:https://www.iqiyi.com/v_19ryfkiv8w.html#curid=15068699100_9f9bab7e0d1e30c494622af777f4ba39)
爬取任意一期正片视频下评论
第二步:词频统计并可视化展示
数据预处理:清理清洗评论中特殊字符,清洗后结果存储为txt文档
中文分词:添加新增词(如:青你、奥利给、冲鸭),去除停用词(如:哦、因此、不然、也好、但是)
统计top10高频词
可视化展示高频词
第三步:绘制词云
根据词频生成词云
可选项-添加背景图片,根据背景图片轮廓生成词云
第四步:结合PaddleHub,对评论进行内容审核
from __future__ import print_function
import requests
import json
import re #正则匹配
import time #时间处理模块
import jieba #中文分词
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.font_manager as font_manager
from PIL import Image
from wordcloud import WordCloud #绘制词云模块
import paddlehub as hub
以下函数都是属于评论数据爬取的内容:
#请求爱奇艺评论接口,返回response信息
def getMoveinfo(url):
'''
请求爱奇艺评论接口,返回response信息
参数 url: 评论的url
:return: response信息
'''
session = requests.Session()
headers = {
"User-Agent": "Mozilla/5.0",
"Accept": "application/json",
"Referer": "https://www.iqiyi.com/v_19ryi45hd8.html#curid=15535092800_6b5b1d91de0f5119cd0903a677eea466",
"Origin": "http://www.iqiyi.com",
"Host": "sns-comment.iqiyi.com",
"Connection": "keep-alive",
"Accept-Language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,zh-TW;q=0.6",
"Accept-Encoding": "gzip, deflate"
}
response = session.get(url, headers=headers)
if response.status_code == 200:
return response.text
return None
#解析json数据,获取评论
'''
解析json数据,获取评论
参数 lastId:最后一条评论ID arr:存放文本的list
:return: 新的lastId
'''
def saveMovieInfoToFile(lastId, arr):
url='https://sns-comment.iqiyi.com/v3/comment/get_comments.action?agent_type=118&agent_version=9.11.5&authcookie=b2ShOCQjHdya5wNk5SiSxeQo67BUSJFJcfoFm2U5DLFqxVp1m3S8bnOm3Q1nm19tFHom1CA2f&business_type=17&content_id=15535092800&hot_size=0&last_id='
url+=str(lastId)
responseTxt = getMoveinfo(url)
responseJson=json.loads(responseTxt)
comments=responseJson['data']['comments']
for val in comments:
# print(val.keys())
if 'content' in val.keys():
print(val['content'])
arr.append(val['content'])
lastId = str(val['id'])
return lastId
数据预处理:清理清洗评论中特殊字符
#去除文本中特殊字符
def clear_special_char(content):
'''
正则处理特殊字符
参数 content:原文本
return: 清除后的文本
'''
comp = re.compile('[^A-Z^a-z^0-9^\u4e00-\u9fa5]')
return comp.sub('', content)
中文分词
def fenci(text):
'''
利用jieba进行分词
参数 text:需要分词的句子或文本
return:分词结果
'''
jieba.load_userdict('add_words.txt')#添加自定义字典
seg=jieba.lcut(text)
return seg
上面add_words.txt
这个自定义字典主要是增加一些选手人名和昵称,以及一些网络用语(如:青你、奥利给、冲鸭)。
def stopwordslist(file_path):
'''
创建停用词表
参数 file_path:停用词文本路径
return:停用词list
'''
stopwords= [line.strip() for line in open(file_path,encoding='UTF-8').readline()]
return stopwords
使用的停用词表可以自己创建(如:哦、因此、不然、也好、但是),也可以直接网上下载一个。另外还有一个字体问题,可以直接使用已经下载好的字体文件。打了包,有需要的可以于此下载
。
def movestopwords(sentence, stopwords, counts):
'''
去除停用词,统计词频
参数 file_path:停用词文本路径 stopwords:停用词list counts: 词频统计结果
return:None
'''
# out=[]
for word in sentence:
if word not in stopwords:
if len(word) !=1:
counts[word]=counts.get(word,0)+1
return None
def drawcounts(counts, num):
'''
绘制词频统计表
参数 counts: 词频统计结果 num:绘制topN
return:none
'''
x_aixs=[]
y_aixs=[]
c_order=sorted(counts.items(), key=lambda x:x[1],reverse=True)
for c in c_order[:num]:
x_aixs.append(c[0])
y_aixs.append(c[1])
matplotlib.rcParams['font.sans-serif']=['SimHei']
matplotlib.rcParams['axes.unicode_minus']=False
plt.bar(x_aixs, y_aixs)
plt.title('词频统计结果')
plt.show()
选用的底图最好纯黑白的,最后结果会比较清晰。这里有一篇可供参考的内容Windows环境下Python中wordcloud的使用——自己踩过的坑
def drawcloud(word_f):
'''
根据词频绘制词云图
参数 word_f:统计出的词频结果
return:none
'''
cloud_mask=np.array(Image.open('cloud.png'))
st=set(['东西', '这是'])
wc=WordCloud(background_color='white',
mask=cloud_mask,
max_words=150,
font_path='simhei.ttf',
min_font_size=10,
max_font_size=100,
width=400,
relative_scaling=0.3,
stopwords=st)
wc.fit_words(word_f)
wc.to_file('pic.png')
如果没有GPU的话需要注意修改results=porn_detection_lstm.detection(data=input_dict,use_gpu=True,batch_size=1)
参数:
def text_detection(text, file_path):
'''
使用hub对评论进行内容分析
return:分析结果
'''
porn_detection_lstm=hub.Module(name='porn_detection_lstm')
f=open('aqy.txt', 'r', encoding='utf-8')
for line in f:
if len(line.strip())==1:
continue
else:
test_text.append(line)
f.close()
input_dict={
'text':test_text}
results=porn_detection_lstm.detection(data=input_dict,use_gpu=True,batch_size=1)
for index, item in enumerate(results):
if item['porn_detection_key'] =='porn':
print(item['text'],':', item['porn_probs'])
num就是换页次数,每一页上面有几十条评论,要多次请求读取所有评论(指定页数的所有评论)。
#评论是多分页的,得多次请求爱奇艺的评论接口才能获取多页评论,有些评论含有表情、特殊字符之类的
## 转换数据
if __name__ == '__main__':
num=60
lastId='0'
arr=[]
with open('aqy.txt', 'a', encoding='utf-8') as f:
for i in range(num):
lastId=saveMovieInfoToFile(lastId, arr)
time.sleep(0.5)
for item in arr:
item=clear_special_char(item)
if item.strip()!='':
try:
f.write(item+'\n')
except e:
print('含有特殊字符')
print("共获取评论:", len(arr))
f=open('aqy.txt', 'r', encoding='utf-8')
counts={
}
for line in f:
words=fenci(line)
stopwords=stopwordslist('cn_stopwords.txt')
movestopwords(words, stopwords, counts)
drawcounts(counts, 10)
drawcloud(counts)
f.close()
file_path='aqy.txt'
test_text=[]
text_detection(test_text, file_path)
之前已经这一介绍了份各函数的主要功能,接下来说一下作业中几个重难点以及一些心得。
首先是,爬虫的时候需要寻找评论对应的那个链接lastid:
其次是正则化部分。在文章最后分享了几篇可供参考的内容,可以深入了解。再是词云部分。wordcloud库,可以说是python非常优秀的词云展示第三方库。词云以词语为基本单位更加直观和艺术的展示文本,利用词云的可视化功能根据词语出现次数决定它的字体大小,如此可以很直观看到该词出现频率。而jieba是优秀的中文分词第三方库,在此也起到了很大的作用。此爬取、分析与基于飞桨的PaddleHub内容审核均为百度深度学习7日打卡第六期飞桨深度学习学院课程内容。课程只有短短一周时间,不过浓缩了很多精华——由浅入深,可以帮助学习者建立系统的知识体系,但是不建议纯纯纯小白参加。虽然一开始两天会有介绍基础,但是时间太短了,没有自己码代码的基础后续就很吃力,而且几天时间就涉及了好几块内容(爬虫、数据分析、图像分类、可视化balabala)——浓缩的精华。建议先自学一下基础(python基础学习推荐MOOC上的Python语言程序设计),然后再学习这个七天课程会有很多收获的。课程每晚8点在b站直播,直播的时候小哥哥小姐姐还会根据弹幕来调整讲解速度和内容。录播也很及时会挂上课程平台,同时微信群还会有答疑(除了助教答疑,大家也会互相讨论,还有隐藏大佬潜水hh),学习氛围还是很好的。还有就是这次学习了解了百度的神奇——飞桨平台及百度AI技术、应用真是应有尽有,只有没想到的惊喜!可以利用PaddleHub提供的预训练模型进行具体任务的Fine-tune,如此便只需要对自定义数据进行相应的预处理,随后输入预训练模型中,即可得到相应的结果!!!省时省力!!!福音!!PaddleHub适配自定义数据完成finetune链接在此,具体使用可以了解一下。比如使用PaddleHub进行图像分类任务不超过百行代码即可实现:
import paddlehub as hub
#在PaddleHub中选择合适的预训练模型来Finetune,由于是图像分类任务,这里使用经典的ResNet-50作为预训练模型
module = hub.Module(name="resnet_v2_50_imagenet")
#接着需要加载图片数据集
from paddlehub.dataset.base_cv_dataset import BaseCVDataset
class DemoDataset(BaseCVDataset):
def __init__(self):
# 数据集存放位置
self.dataset_dir = "dataset"
super(DemoDataset, self).__init__(
base_path=self.dataset_dir,
train_list_file="train_list.txt",
validate_list_file="validate_list.txt",
test_list_file="test_list.txt",
label_list_file="label_list.txt",
)
dataset = DemoDataset()
#接着生成一个图像分类的reader,reader负责将dataset的数据进行预处理,接着以特定格式组织并输入给模型进行训练
data_reader = hub.reader.ImageClassificationReader(
image_width=module.get_expected_image_width(),
image_height=module.get_expected_image_height(),
images_mean=module.get_pretrained_images_mean(),
images_std=module.get_pretrained_images_std(),
dataset=dataset)
#在进行Finetune前,简单设置一些运行时的配置
config = hub.RunConfig(
use_cuda=True, #是否使用GPU训练,默认为False;
num_epoch=3, #Fine-tune的轮数;
checkpoint_dir="cv_finetune_turtorial_demo",#模型checkpoint保存路径, 若用户没有指定,程序会自动生成;
batch_size=3, #训练的批大小,如果使用GPU,请根据实际情况调整batch_size;
eval_interval=10, #模型评估的间隔,默认每100个step评估一次验证集;
strategy=hub.finetune.strategy.DefaultFinetuneStrategy()) #Fine-tune优化策略;
#组建Finetune Task
input_dict, output_dict, program = module.context(trainable=True)
img = input_dict["image"]
feature_map = output_dict["feature_map"]
feed_list = [img.name]
task = hub.ImageClassifierTask(
data_reader=data_reader,
feed_list=feed_list,
feature=feature_map,
num_classes=dataset.num_labels,
config=config)
#选择finetune_and_eval接口来进行模型训练,这个接口在finetune的过程中,会周期性的进行模型效果的评估,以便了解整个训练过程的性能变化
run_states = task.finetune_and_eval()
#当Finetune完成后,使用模型来进行预测
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
with open("dataset/test_list.txt","r") as f:
filepath = f.readlines()
data = [filepath[0].split(" ")[0],filepath[1].split(" ")[0],filepath[2].split(" ")[0],filepath[3].split(" ")[0],filepath[4].split(" ")[0]]
label_map = dataset.label_dict()
index = 0
run_states = task.predict(data=data)
results = [run_state.run_results for run_state in run_states]
for batch_result in results:
print(batch_result)
batch_result = np.argmax(batch_result, axis=2)[0]
print(batch_result)
for result in batch_result:
index += 1
result = label_map[result]
print("input %i is %s, and the predict result is %s" %
(index, data[index - 1], result))
另外再推荐一下良心之作——AI Studio(AI Studio是基于百度深度学习平台飞桨的一站式AI开发平台,提供在线编程环境、免费GPU算力、海量开源算法和开放数据,帮助开发者快速创建和部署模型)。GPU算力超级强,远强于阿里和谷歌同类免费产品平台,需要跑模型的话可以选择ta噢。我已经用了两个月了。
参考内容:
Python 正则表达式
史上最全的正则表达式-匹配中英文、字母和数字
Python数据可视化之Wordcloud
Python大数据:jieba分词,词频统计
Python jieba库的使用说明
Python语言程序设计
Windows环境下Python中wordcloud的使用——自己踩过的坑