各位集美兄得看过来! 利用AI给青春有你2的选手们做数据分析挖掘(一):爬虫选手信息
各位集美兄得看过来! 利用AI给青春有你2的选手们做数据分析挖掘(二):统计并展示数据
各位集美兄得看过来! 利用AI给青春有你2的选手们做数据分析挖掘(三):看图像识选手
各位集美兄得看过来! 利用AI给青春有你2的选手们做数据分析挖掘(四):AI分析谁最容易出道
到了现在比赛白热化阶段,不少选手已经初见锋芒,接下来,我们将基于爱奇艺视频的评论去做数据分析,哪位选手现在最受关注,最具备出道几率!看看你pick的小姐姐的路人缘怎样!
实践主要涉及的技术包括爬虫,NLP(自然语言处理),机器学习等内容,主要使用百度提供的PaddleHub进行开发,实践中间会带一点基础知识说明,问题不大,大家放心看~
我们的目标是通过<<青春有你2>>的视频评论获取数据,然后经过数据处理清洗后,对评论进行分词以及词频统计,绘制出词云,直观的展示现在观众的对选手的看法以及通过文本审核模型,对评论进行内容审核.
事不宜迟,我们马上开始吧!
配置准备
- 中文分词需要jieba
- 词云绘制需要wordcloud
- 可视化展示中需要的中文字体
- 网上公开资源中找一个中文停用词表
- 根据分词结果自己制作新增词表
- 准备一张词云背景图
- paddlehub配置
!pip install jieba
!pip install wordcloud
# Linux系统默认字体文件路径
!ls /usr/share/fonts/
# 查看系统可用的ttf格式中文字体
!fc-list :lang=zh | grep ".ttf"
!wget https://mydueros.cdn.bcebos.com/font/simhei.ttf # 下载中文字体
# #创建字体目录fonts
!mkdir .fonts
# # 复制字体文件到该路径
!cp simhei.ttf .fonts/
#安装模型
!hub install porn_detection_lstm==1.1.0
!pip install --upgrade 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
爬取评论
评论的来源主要是<<青春有你2>>正片的评论
分析页面
我们打开页面,我们需要爬取的评论区就是下面框框框住的部分。
我们**“F12”**打开页面源码,指出相应区域如下
那是不是只需要使用样式爬取所有的评论就行了呢?
然而实际上评论是不断下滑加载的,并不是一次加载完毕,因此我们需要拿到加载评论的接口
通过捕获,可以得到请求评论的接口如下
- 主要使用参数:
last_id: 上次加载最后一条评论id,当last_id为空的时候,就是第一页,第一页加载10个
page_size:加载评论条数
将page_size调到200请求,返回错误提示如下
意思是单页加载量不能超过40个,那我们后面就愉快得一次加载40个吧。
- 返回值:
具体思路
1.用爬取第一页所有的评论
2.以第一页最后的评论的id为last_id,循环请求评论接口每页加载40个评论,然后爬下来
基于requests与正则实现爬取
#请求爱奇艺评论接口,返回response信息
def getMovieinfo(last_id):
'''
请求爱奇艺评论接口,返回response信息
参数 url: 评论的url
:return: response信息
'''
if last_id=='':
page_size=10
else:
page_size=40
url = 'https://sns-comment.iqiyi.com/v3/comment/get_comments.action?agent_type=118&agent_version=9.11.5&authcookie=null&business_type=17&content_id=15068699100&hot_size=0&page=&page_size='+str(page_size)+'&types=time&callback=jsonp&&last_id='+str(last_id)
response = requests.get(url, timeout=10)
# print(result.text)
return response
#解析json数据,获取评论
def saveMovieInfoToFile(text):
'''
解析json数据,获取评论
参数 lastId:最后一条评论ID arr:存放文本的list
:return: 新的lastId
'''
pattern = re.compile('.*?jsonp[(](.*?)[)] }catch', re.S)
items = re.findall(pattern, text)
if len(items)==0:
return ''
data_json=json.loads(items[0])
# print(data_json)
comments=data_json['data']['comments']
f_comments=open('work/comments.txt','a')
for comment in comments:
if 'content' not in comment:
continue
f_comments.write(comment['content']+'\n')
last_id=comment['id']
f_comments.close
crawl_num=len(comments)
return last_id,crawl_num
调用方式,由于是分页的,需要循环调用接口,具体实现如下:
response=getMovieinfo('')
cur_last_id,total_crawl=saveMovieInfoToFile(response.text)
num=0
while cur_last_id !='' :
if num >30:
break
cur_last_id,total=saveMovieInfoToFile(getMovieinfo(cur_last_id).text)
total_crawl+=total
num+=1
print('总共爬取评论:%d条'%(total_crawl))
输出comments.txt
如下:
数据清洗
我们爬了一波评论之后,由于评论里面有点特殊的字符比如shaking加油♥♥♥♥♥♥♥♥♥♥♥♥
,我们需要把这些♥
特殊字符处理了.
具体实现:
#去除文本中特殊字符
def clear_special_char(content):
'''
正则处理特殊字符
参数 content:原文本
return: 清除后的文本
'''
f_clear = open('work/clear_comments.txt','a')
clear_content = re.findall('[\u4e00-\u9fa5a-zA-Z0-9]+',content,re.S) #只要字符串中的中文,字母,数字
str=','.join(clear_content)
f_clear.write(str+'\n')
f_clear.close
return str
输出clear_comments.txt就是清洗完成的评论如下:
词频统计
因为我们要看小姐姐的路人缘,因此我们对评论进行词频统计,看看观众对青春有你的关注点.因此需要对评论进行分词,然后去除停用词比如"尽管,如此"这些,然后对词频进行统计,统计评论中出现词最多top10,以柱状图形式显示.
分词
分词我们主要使用Jieba分词,主要使用 jieba.cut
def fenci(content):
'''
利用jieba进行分词
参数 content:需要分词的句子或文本
return:分词结果
'''
# 加载本地词库
jieba.load_userdict(r"dic/user_dic.txt")
seg_list = jieba.cut(content)
return seg_list
分词案例:
分词前:征战 四海 只 为 今日 一胜 , 我 不会 再败 了 。
分词后:['征战', '四海', '只', '为', '今日', '一胜', ',', '我', '不会', '再败', '了', '。']
创建停用词表
从网上下载中文停用词表到本地,通过停用词文件加载停用词
def stopwordslist():
'''
创建停用词表
参数 file_path:停用词文本路径
return:停用词list
'''
stopwords = [line.strip() for line in open('work/stopwords.txt',encoding='UTF-8').readlines()]
acstopwords=['哦','因此','不然','也好','但是']
stopwords.extend(acstopwords)
return stopwords
去除停用词
基于停用词表,去除清洗后的评论的停用词,返回最终评论词数组
def movestopwords(sentence_depart,stopwords):
'''
去除停用词,统计词频
参数 file_path:停用词文本路径 stopwords:停用词list counts: 词频统计结果
return:None
'''
segments = []
# 去停用词
for word in sentence_depart:
if word not in stopwords:
if word != '\t':
# outstr += word
# outstr += " "
segments.append(word)
return segments
绘制top10词频统计表
根据上面返回的词数组,统计每个词的数量返回结果,并绘制柱状图,绘图主要使用matplotlib
import collections
def drawcounts(segments):
'''
绘制词频统计表
参数 counts: 词频统计结果 num:绘制topN
return:none
'''
# 词频统计
word_counts = collections.Counter(segments) # 对分词做词频统计
word_counts_top10 = word_counts.most_common(10) # 获取前10最高频的词
print (word_counts_top10)
dic=dict(word_counts_top10)
print(dic)
x_values=[]
y_values=[]
for k in dic:
x_values.append(k)
y_values.append(dic[k])
# 设置显示中文
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
plt.figure(figsize=(20,15))
plt.bar(range(len(y_values)), y_values,color='r',tick_label=x_values,facecolor='#9999ff',edgecolor='white')
# 这里是调节横坐标的倾斜度,rotation是度数,以及设置刻度字体大小
plt.xticks(rotation=45,fontsize=20)
plt.yticks(fontsize=20)
plt.legend()
plt.title('''《青春有你2》高频评论词统计''',fontsize = 24)
plt.savefig('highwords.jpg')
plt.show()
return word_counts
输出结果如下:
绘制词云
接下来,将基于wordcloud 制作词云
抠图
听说,hub有个牛逼的抠图能力,让我试试!反正词云需要背景
首先我们下载一张有形状的图
编写以下代码:
import sys
import os
import paddlehub as hub
# 加载模型
humanseg = hub.Module(name = "deeplabv3p_xception65_humanseg")
# 抠图
results = humanseg.segmentation(data = {"image":['sendpix0.jpg']})
for result in results:
print(result['origin'])
print(result['processed'])
看看抠图结果:
可以看到除了边缘有点不规整之外,还是扣得挺漂亮的,但是由于我们词云需要的背景图是白底,所有最好选择黑色的图作为主图
绘制词云
基于wordcloud绘制词云
def drawcloud(word_counts):
'''
根据词频绘制词云图
参数 word_f:统计出的词频结果
return:none
'''
# 词频展示
# 关键一步
font=r'fonts/SimHei.ttf'
shape=np.array(Image.open(r'humanseg_output/sendpix0.png'))
my_wordcloud = WordCloud(font_path=font,stopwords=stopwords,background_color='white',mask=shape,width=800,height=600,
max_words=200,max_font_size = 100,random_state=20).generate_from_frequencies(word_counts)
#显示生成的词云
plt.imshow(my_wordcloud)
plt.axis("off")
plt.show()
my_wordcloud.to_file('pic.png')
我们看看我们绘制出来的结果:
工具人看到之后表示:
评论审核
基于PaddlePaddle的porn_detection_lstm预训练模型,可自动判别文本是否涉黄并给出相应的置信度,对文本中的色情描述、低俗交友、污秽文爱进行识别。porn_detection_lstm采用LSTM网络结构并按字粒度进行切词,具有较高的分类精度。该模型最大句子长度为256字,仅支持预测。
导入模型
porn_detection_lstm = hub.Module(name="porn_detection_lstm")
使用模型对评论进行分析
import six
def text_detection():
'''
使用hub对评论进行内容分析
return:分析结果
'''
comment_text = [line.strip() for line in open('work/clear_comments.txt',encoding='UTF-8').readlines()]
input_dict = {"text": comment_text}
results = porn_detection_lstm.detection(data=input_dict,use_gpu=True, batch_size=1)
f_dect=open('work/text_detection.txt','w')
for index, text in enumerate(comment_text):
results[index]["text"] = text
for index, result in enumerate(results):
if six.PY2:
detection= json.dumps(results[index], encoding="utf8", ensure_ascii=False)
else:
detection=results[index]
# print(detection)
print("检测句子:%s,检测结果not_porn_probs:%f\n"%(detection['text'],detection['not_porn_probs']))
f_dect.write("检测句子:%s,检测结果not_porn_probs:%f\n"%(detection['text'],detection['not_porn_probs']))
f_dect.close
输出结果:
not_porn_probs越接近1越正经
MAIN实现
#评论是多分页的,得多次请求爱奇艺的评论接口才能获取多页评论,有些评论含有表情、特殊字符之类的
#num 是页数,一页10条评论,假如爬取1000条评论,设置num=100
if __name__ == "__main__":
response=getMovieinfo('')
cur_last_id,total_crawl=saveMovieInfoToFile(response.text)
num=0
while cur_last_id !='' :
if num >30:
break
cur_last_id,total=saveMovieInfoToFile(getMovieinfo(cur_last_id).text)
total_crawl+=total
num+=1
print('总共爬取评论:%d条'%(total_crawl))
stopwords=stopwordslist()
f = open(r"work/comments.txt")
line = f.readline()
segments=[]
while line:
line = f.readline()
clear_line=clear_special_char(line)
seg_list= fenci(clear_line)
segments_list=movestopwords(seg_list,stopwords)
segments.extend(segments_list)
f.close()
drawcloud(drawcounts(segments))
text_detection()
结语
通过hub提供的预训练模型进行预测,实现对青春有你2选手的数据分析,给我这个0基础的工具人学习了很多,起码掌握了具体一个采集清洗分析训练预测的流程,实在是获益良多!
然后谈谈技术吧,无论用什么语言什么技术,根本上都是要实现价值的,无论是大还是小,将技术应用到你生活中工作中,才能说明你掌握了这项技术,在你遇到场景的时候,想到应用什么样的技术能最有效率的解决问题并且实现出来,这就是能力,我个人是希望自己向着这个目标前进的!
最后~
shaking冲鸭!!!
安崎冲鸭!!!