各位集美兄得看过来! 利用AI给青春有你2的选手们做数据分析挖掘(四):AI分析谁最容易出道

各位集美兄得看过来! 利用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”**打开页面源码,指出相应区域如下
在这里插入图片描述

那是不是只需要使用样式爬取所有的评论就行了呢?

然而实际上评论是不断下滑加载的,并不是一次加载完毕,因此我们需要拿到加载评论的接口

在这里插入图片描述

通过捕获,可以得到请求评论的接口如下

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&last_id=240718226621&page=&page_size=20&types=time&callback=jsonp_1587905040415_94459

  • 主要使用参数:

last_id: 上次加载最后一条评论id,当last_id为空的时候,就是第一页,第一页加载10个

page_size:加载评论条数

将page_size调到200请求,返回错误提示如下
在这里插入图片描述

在这里插入图片描述意思是单页加载量不能超过40个,那我们后面就愉快得一次加载40个吧。

  • 返回值:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dYVMZH52-1587922926890)(C:\Users\lps\Documents\myblog\青春有你\情感分析.assets\image-20200426211044629.png)]

具体思路

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冲鸭!!!

安崎冲鸭!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章