本文的文字及圖片來源于網路,僅供學習、交流使用,不具有任何商業用途,如有問題請及時聯系我們以作處理,
以下文章來源于菜J學Python ,作者J哥
剛接觸Python的新手、小白,可以復制下面的鏈接去免費觀看Python的基礎入門教學視頻
https://v.douyu.com/author/y6AZ4jn9jwKW
前言
綜藝,是我們勞累了一天的放松方式,也是我們飯后的談資,看著自己喜歡的綜藝,時光足夠美,而《令人心動的offer》,就是一個不錯的綜藝選擇,
《令人心動的offer》目前為止已經播出了兩季,第一季在豆瓣為8.3分,共有5萬余人評分,第二季目前評分低于第一季,評分僅7.1分,
本文通過爬取《令人心動的offer》第二季13萬+彈幕,進行可視化分析和情感分析,完整代碼后臺回復「offer」即可免費獲取,
資料獲取
《令人心動的offer》第二季在騰訊視頻獨家播出,目前已播出四期(含面試篇),本文采取分集爬取,彈幕資料爬蟲在往期原創文章中已詳細講解,本文不做贅述,感興趣的朋友可點擊:視頻彈幕爬蟲,看這一篇就夠了,以下以爬取面試篇彈幕為例,并給出完整代碼:
#-*- coding = uft-8 -*- #@Time : 2020/11/30 21:35 #@File : tengxun_danmu.py import requests import json import time import pandas as pd target_id = "6130942571%26"#面試篇的target_id vid = "%3Dt0034o74jpr"#面試篇的vid df = pd.DataFrame() for page in range(15, 3214, 30): #視頻時長共3214秒 headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'} url = 'https://mfm.video.qq.com/danmu?otype=json×tamp={0}&target_id={1}vid{2}&count=80'.format(page,target_id,vid) print("正在提取第" + str(page) + "頁") html = requests.get(url,headers = headers) bs = json.loads(html.text,strict = False) #strict引數解區域分內容json格式決議報錯 time.sleep(1) #遍歷獲取目標欄位 for i in bs['comments']: content = i['content'] #彈幕 upcount = i['upcount'] #點贊數 user_degree =i['uservip_degree'] #會員等級 timepoint = i['timepoint'] #發布時間 comment_id = i['commentid'] #彈幕id cache = pd.DataFrame({'彈幕':[content],'會員等級':[user_degree],'發布時間':[timepoint],'彈幕點贊':[upcount],'彈幕id':[comment_id]}) df = pd.concat([df,cache]) df.to_csv('面試篇.csv',encoding = 'utf-8')
打開面試篇csv檔案,預覽如下:
資料清洗
合并彈幕資料
首先,將四個彈幕csv檔案進行資料合并,采用concat方法,
import pandas as pd import numpy as np df1 = pd.read_csv("/彈幕/騰訊/令人心動的offer/面試篇.csv") df1["期數"] = "面試篇" df2 = pd.read_csv("/彈幕/騰訊/令人心動的offer/第1期.csv") df2["期數"] = "第1期" df3 = pd.read_csv("/彈幕/騰訊/令人心動的offer/第2期.csv") df3["期數"] = "第2期" df4 = pd.read_csv("/彈幕/騰訊/令人心動的offer/第3期.csv") df4["期數"] = "第3期" df = pd.concat([df1,df2,df3,df4])
預覽下合并后的資料:
df.sample(10)
合并后資料
查看資料資訊
df.info() <class 'pandas.core.frame.DataFrame'> Int64Index:133627 entries, 0 to 34923 Data columns (total 8 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Unnamed: 0133627 non-null int64 1 用戶名 49040 non-null object 2 內容 133626 non-null object 3 會員等級 133627 non-null int64 4 評論時間點 133627 non-null int64 5 評論點贊 133627 non-null int64 6 評論id 133627 non-null int64 7 期數 133627 non-null object dtypes: int64(5), object(3) memory usage: 9.2+ MB
發現資料存在以下幾個問題:1.欄位名稱可調整(個人潔癖)2.Unnamed欄位多余 3.用戶名欄位有缺失值,可填充 4.內容和評論時間點欄位型別需要調整 5.評論id對分析無意義,可洗掉
重命名欄位
df = df.rename(columns={'用戶名':'用戶昵稱','內容':'彈幕內容','評論時間點':'發送時間','評論點贊':'彈幕點贊','期數':'所屬期數'})
過濾欄位
#選擇需要分析的欄位 df = df[["用戶昵稱","彈幕內容","會員等級","發送時間","彈幕點贊","所屬期數"]]
缺失值處理
df["用戶昵稱"] = df["用戶昵稱"].fillna("無名氏")
發送時間處理
發送時間欄位是秒數,需要改成時間,這里自定義一個time_change函式進行處理,
def time_change(seconds): m, s = divmod(seconds, 60) h, m = divmod(m, 60) ss_time = "%d:%02d:%02d" % (h, m, s) print(ss_time) return ss_time time_change(seconds=8888)
將time_change函式應用于發送時間欄位:
df["發送時間"] = df["發送時間"].apply(time_change)
設定為需要的時間格式:
df['發送時間'] = pd.to_datetime(df['發送時間']) df['發送時間'] = df['發送時間'].apply(lambda x : x.strftime('%H:%M:%S'))
彈幕內容處理
將object資料型別更改為str:
df["彈幕內容"] = df["彈幕內容"].astype("str")
機械壓縮去重:
#定義機械壓縮函式 def yasuo(st): for i in range(1,int(len(st)/2)+1): for j in range(len(st)): if st[j:j+i] == st[j+i:j+2*i]: k = j + i while st[k:k+i] == st[k+i:k+2*i] and k<len(st): k = k + i st = st[:j] + st[k:] return st yasuo(st="學Python真的真的真的很菜很菜") #呼叫機械壓縮函式 df["彈幕內容"] = df["彈幕內容"].apply(yasuo)
特殊字符過濾:
df['彈幕內容'] = df['彈幕內容'].str.extract(r"([\u4e00-\u9fa5]+)") #提取中文內容 df = df.dropna() #純表情彈幕直接洗掉
清洗后資料預覽如下:
資料分析
各期彈幕數量對比
《令人心動的offer》第二季已播出四期(含面試篇),第1期:規則升級,實習生面臨高壓考核彈幕數量最多,達到42422個,面試篇:實習生面試遭靈魂拷問彈幕數量最少,僅為17332個,
import pyecharts.options as opts from pyecharts.charts import * from pyecharts.globals import ThemeType df7 = df["所屬期數"].value_counts() print(df7.index.to_list()) print(df7.to_list()) c = ( Bar(init_opts=opts.InitOpts(theme=ThemeType.DARK)) .add_xaxis(df7.index.to_list()) .add_yaxis("",df7.to_list()) .set_global_opts(title_opts=opts.TitleOpts(title="各期彈幕數量",subtitle="資料來源:騰訊視屏 \t制圖:菜J學Python",pos_left = 'left'), xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(font_size=13)), #更改橫坐標字體大小 yaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(font_size=13)), #更改縱坐標字體大小 ) .set_series_opts(label_opts=opts.LabelOpts(font_size=16,position='top')) ) c.render_notebook()
各期彈幕數量
誰是彈幕發射機
用戶昵稱為想太多de貓幾期下來共發射彈幕227個,遙遙領先其他彈幕黨,名副其實的彈幕發射機,
df8 = df["用戶昵稱"].value_counts()[1:11] df8 = df8.sort_values(ascending=True) df8 = df8.tail(10) print(df8.index.to_list()) print(df8.to_list()) c = ( Bar(init_opts=opts.InitOpts(theme=ThemeType.DARK)) .add_xaxis(df8.index.to_list()) .add_yaxis("",df8.to_list()).reversal_axis() #X軸與y軸調換順序 .set_global_opts(title_opts=opts.TitleOpts(title="彈幕發送數量TOP10",subtitle="資料來源:騰訊視頻 \t制圖:菜J學Python",pos_left = 'left'), xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(font_size=13)), #更改橫坐標字體大小 yaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(font_size=13)), #更改縱坐標字體大小 ) .set_series_opts(label_opts=opts.LabelOpts(font_size=16,position='right')) ) c.render_notebook()
隨機抽取想太多de貓彈幕資訊,發現其對《令人心動的offer》第二季愛的深沉,彈幕內容透露出其觀看視頻還是相當之認真,幾乎每個彈幕都獲得了一定的點贊,
df[df["用戶昵稱"]=="想太多de貓"].sample(10)
彈幕發射機彈幕抽樣
會員等級分布
在觀看《令人心動的offer》第二季的觀眾中,高達74.31%的用戶和J哥一樣不是騰訊視頻的會員,占比第二的會員等級3占5.6%,共計7419人,占比第三的會員等級1占5.39%,共計7153人,
df2 = df["會員等級"].astype("str").value_counts() print(df2) df2 = df2.sort_values(ascending=False) regions = df2.index.to_list() values = df2.to_list() c = ( Pie(init_opts=opts.InitOpts(theme=ThemeType.DARK)) .add("", list(zip(regions,values))) .set_global_opts(legend_opts = opts.LegendOpts(is_show = False),title_opts=opts.TitleOpts(title="會員等級分布",subtitle="資料來源:騰訊視頻\t制圖:菜J學Python",pos_top="0.5%",pos_left = 'left')) .set_series_opts(label_opts=opts.LabelOpts(formatter="等級{b}占比:{d}%",font_size=14)) ) c.render_notebook()
會員等級分布
彈幕在討論些什么
通過對13+彈幕制作詞云圖,我們發現,彈幕中出現頻率較高的詞匯有「丁輝、律師、喜歡、加油、徐律、干飯、撒老師」等,丁輝作為8個實習生里本科學校最差、年齡最大的成員,從一開始就被觀眾所熱議,徐律作為第1季的帶教導師,其雷厲風行又知性溫柔的風范,早已贏得廣大觀眾的喜愛,干飯作為最近非常熱門的網路詞匯,出現在熱播綜藝中也不足為奇,而撒老師作為這一季的搞笑擔當和凡爾賽擔當,也被廣大觀眾所熱議,
# 定義分詞函式 def get_cut_words(content_series): # 讀入停用詞表 stop_words = [] with open("/菜J學Python/offer/stop_words.txt", 'r', encoding='utf-8') as f: lines = f.readlines() for line in lines: stop_words.append(line.strip()) # 添加關鍵詞 my_words = ['撒老師', '范丞丞','第一季'] for i in my_words: jieba.add_word(i) # 自定義停用詞 my_stop_words = ['好像', '真的','感覺'] stop_words.extend(my_stop_words) # 分詞 word_num = jieba.lcut(content_series.str.cat(sep=','), cut_all=False) # 條件篩選 word_num_selected = [i for i in word_num if i notin stop_words and len(i)>=2] return word_num_selected # 繪制詞云圖 text1 = get_cut_words(content_series=df['彈幕內容']) stylecloud.gen_stylecloud(text=' '.join(text1), max_words=100, collocations=False, font_path='字酷堂清楷體.ttf', icon_name='fas fa-square', size=653, #palette='matplotlib.Inferno_9', output_name='./offer.png') Image(filename='./offer.png')
整體彈幕詞云
大家如何評論8個實習生
我們首先看下8位實習生的照片:
在所有彈幕中,丁輝被觀眾提及次數遠超過另外7個實習生,共計9298次,其次是詹秋怡,被觀眾提及2455次,劉煜成被觀眾提及最少,僅有526次,
df8 = df["人物提及"].value_counts()[1:11] print(df8.index.to_list()) print(df8.to_list()) c = ( Bar(init_opts=opts.InitOpts(theme=ThemeType.DARK)) .add_xaxis(df8.index.to_list()) .add_yaxis("",df8.to_list()) .set_global_opts(title_opts=opts.TitleOpts(title="人物提及次數",subtitle="資料來源:騰訊視頻 \t制圖:菜J學Python",pos_left = 'left'), xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(font_size=13)), #更改橫坐標字體大小 yaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(font_size=13)), #更改縱坐標字體大小 ) .set_series_opts(label_opts=opts.LabelOpts(font_size=16,position='top')) ) c.render_notebook()
分別繪制8個實習生的彈幕詞云圖,我們發現,還是有很多觀眾認可「丁輝」的,「加油、喜歡、看好、支持」等詞出現頻率較高;對于性格較為內向的詹秋怡,觀眾也非常喜歡,從「漂亮、劉亦菲、好看」等高頻詞可看出,不少人喜歡她是基于顏值;作為來自頂級學府斯坦福的王驍來說,觀眾呈現兩邊倒的局勢,有人說「王驍好」,也有人認為他是「凡爾賽」;朱一暄也一樣,有人覺得她很「可愛」,也有人「討厭」她;瞿澤林則被表揚「情商高、可愛」;李晉曄的「帥氣」被觀眾贊不絕口,甚至有很多人認為他很像第1季的人氣實習生何運晨;人大畢業的王穎飛也被觀眾夸贊「好看、漂亮」;高分過司考的劉煜成被觀眾夸贊「專業知識不錯」,由于在第3期中被王驍搶話,受了委屈,觀眾紛紛表示「心疼」,
情感分析
通過運用百度開源NLP對彈幕內容進行情感分值計算,我們發現,《令人心動的offer》第二季整體情感分值高于0.5,觀眾表現出較高的積極傾向,會員等級較高的觀眾越能堅持觀看到最后,彈幕點贊量從視頻播放開始呈增長趨勢,在最后15分鐘時驟降,情感分值則表現為視頻播放首尾高,中間低,
import paddlehub as hub #這里使用了百度開源的成熟NLP模型來預測情感傾向 senta = hub.Module(name="senta_bilstm") texts = df['彈幕內容'].tolist() input_data = {'text':texts} res = senta.sentiment_classify(data=https://www.cnblogs.com/hhh188764/p/input_data) df['情感分值'] = [x['positive_probs'] for x in res] #重采樣至15分鐘 df.index = df['發送時間'] data = df.resample('15min').mean().reset_index() #給資料表添加調色板 import seaborn as sns color_map = sns.light_palette('orange', as_cmap=True) #light_palette調色板 data.style.background_gradient(color_map)
情感分值表
c = ( Line(init_opts=opts.InitOpts(theme=ThemeType.DARK)) .add_xaxis(data["發送時間"].to_list()) .add_yaxis('情感傾向', list(data["情感分值"].round(2)), is_smooth=True,is_connect_nones=True,areastyle_opts=opts.AreaStyleOpts(opacity=0.5)) .set_global_opts(title_opts=opts.TitleOpts(title="情感傾向",subtitle="資料來源:騰訊視頻 \t制圖:菜J學Python",pos_left = 'left')) ) c.render_notebook()
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/228405.html
標籤:Python
