實戰(zhàn) | Python模型分析B站優(yōu)質up主
作者 | 遠辰
來源 | 數(shù)據(jù)不吹牛
不管前浪還是后浪,能夠浪起來的才算是好浪。
相信大家最近都被號稱“浪里白條”的b站刷了不止一次屏。這次咱們先不談價值觀,主要從數(shù)據(jù)的角度,扒一扒讓b站能夠在浪里穿梭的資本——優(yōu)質UP主。
本文在RFM模型基礎上做了調(diào)整,嘗試用更符合b站特性的IFL模型,找到各分區(qū)優(yōu)質up主。整個過程以分析項目的形式展開,最終附上了完整源數(shù)據(jù)和代碼,方便感興趣的同學練手。

項目概覽
??分析目的
對2019年1月~2020年3月發(fā)布的視頻進行分析,挑選出視頻質量高,值得關注的up主。
??數(shù)據(jù)來源
分析數(shù)據(jù)基于 bilibili 網(wǎng)站上的公開信息,主要爬取了以下數(shù)據(jù)維度:
2019年1月~2020年3月,科技區(qū)播放量過5w視頻的分區(qū)名稱、作者名稱、作者id、發(fā)布時間、播放數(shù)、硬幣數(shù)、彈幕數(shù)、收藏數(shù)、點贊數(shù)、分享數(shù)、評論數(shù),共計50130行。
? 源數(shù)據(jù)下載鏈接
完整數(shù)據(jù)源和代碼鏈接:https://pan.baidu.com/s/1RIxOxh-TFMey9sGvZLVuJg 提取碼:bhh2

數(shù)據(jù)概覽
視頻信息表:

coins:投硬幣數(shù)
danmu:彈幕數(shù)
favorite:收藏數(shù)
likes:點贊數(shù)
replay:評論數(shù)
share:分享數(shù)
view:播放量
各字段數(shù)量:

缺失值數(shù)量:


數(shù)據(jù)清洗
??刪除空值
df = df.dropna()
df.info()共刪除了19行數(shù)據(jù),剩余50111行數(shù)據(jù)

df = df.drop_duplicates()
df.info()刪除了1312行重復的數(shù)據(jù),剩余數(shù)據(jù)量48799行

? 提取所需關鍵詞
df = df[['分區(qū)', 'author','date','coins','danmu','favorite','likes','replay','share','view']]
df.head()

構建模型
RFM模型是衡量客戶價值和創(chuàng)利能力的重要工具和手段。通過一個客戶近期購買行為、購買的總體頻率以及消費金額三項指標來描述客戶的價值狀況。
R:最近一次消費時間(最近一次消費到參考時間的間隔)
F:消費的頻率(消費了多少次)
M:消費的金額 (總消費金額)
但RFM模型并不能評價視頻的質量,所以在這里針對up主的視頻信息構建了IFL模型,以評估視頻的質量。
I(Interaction_rate):
I值反映的是平均每個視頻的互動率,互動率越高,表明其視頻更能產(chǎn)生用戶的共鳴,使其有話題感。

F值表示的是每個視頻的平均發(fā)布周期,每個視頻之間的發(fā)布周期越短,說明內(nèi)容生產(chǎn)者創(chuàng)作視頻的時間也就越短,創(chuàng)作時間太長,不是忠實粉絲的用戶可能將其遺忘。

L(Like_rate):
L值表示的是統(tǒng)計時間內(nèi)發(fā)布視頻的平均點贊率,越大表示視頻質量越穩(wěn)定,用戶對up主的認可度也就越高。

? 提取需要的信息
根據(jù)不同的分區(qū)進行IFL打分,這里以科普區(qū)為例
sc = df.loc[df['分區(qū)']=='科學科普']
so = df.loc[df['分區(qū)']=='社科人文']
ma = df.loc[df['分區(qū)']=='機械']
tec = df.loc[df['分區(qū)']=='野生技術協(xié)會']
mi = df.loc[df['分區(qū)']=='星海'] # 一般發(fā)布軍事內(nèi)容
car = df.loc[df['分區(qū)']=='汽車']
sc.info()
??關鍵詞構造
F值:首先,先篩選出發(fā)布視頻大于5的up主,視頻播放量在5W以上的視頻數(shù)少于5,說明可能是有些視頻標題取得好播放量才高,而不是視頻質量穩(wěn)定的up主。
# 計算發(fā)布視頻的次數(shù)
count = sc.groupby('author')['date'].count().reset_index()
count.columns =['author','times']
# 剔除掉發(fā)布視頻少于5的up主
com_m = count[count['times']>5]
#com_m = pd.merge(count,I,on='author',how='inner')
com_m.info()

篩選完只剩下208個up主的視頻數(shù)在5個以上:
last = sc.groupby('author')['date'].max()
late = sc.groupby('author')['date'].min()
# 最晚發(fā)布日期與最早之間的天數(shù)/發(fā)布次數(shù),保留整數(shù),用date重新命名列F =round((last-late).dt.days/sc.groupby('author')['date'].count()).reset_index()
F.columns =['author', 'F']
F = pd.merge(com_m, F,on='author', how='inner')
F.describe()
通過describe()方法發(fā)現(xiàn),最晚發(fā)布日期與最早發(fā)布日期為0的現(xiàn)象,猜測是在同一天內(nèi)發(fā)布了大量的視頻。
# 查找的一天內(nèi)發(fā)布視頻數(shù)大于5的人F.loc[F['F'].idxmin()]


其視頻皆為轉載,將其剔除統(tǒng)計范圍內(nèi)。
F = F.loc[F['F']>0]
F.describe()
I值
# 構建I值danmu = sc.groupby('author')['danmu'].sum()
replay = sc.groupby('author')['replay'].sum()
view = sc.groupby('author')['view'].sum()
count = sc.groupby('author')['date'].count()
I =round((danmu+replay)/view/count*100,2).reset_index() #
I.columns=['author','I']
F_I = pd.merge(F,I,on='author',how='inner')
F_I.head()
L值
# 計算出點贊率計算出所有視頻的點贊率sc['L'] =(sc['likes']+sc['coins']*2+sc['favorite']*3)/sc['view']*100
sc.head()
# 構建L值L =(sc.groupby('author')['L'].sum()/sc.groupby('author')['date'].count()).reset_index()
L.columns =['author', 'L']
IFL = pd.merge(F_I, L, on='author',how='inner')
IFL = IFL[['author', 'I','F','L']]
IFL.head()
??維度打分
維度確認的核心是分值確定,按照設定的標準,我們給每個消費者的I/F/L值打分,分值的大小取決于我們的偏好,即我們越喜歡的行為,打的分數(shù)就越高:
I值,I代表了up主視頻的平均評論率,這個值越大,就說明其視頻越能使用戶有話題,當I值越大時,分值越大。
F值表示視頻的平均發(fā)布周期,我們當然想要經(jīng)常看到,所以這個值越大時,分值越小。
L值表示發(fā)布視頻的平均點贊率,S值越大時,質量越穩(wěn)定,分值也就越大。I/S值根據(jù)四分位數(shù)打分,F(xiàn)值根據(jù)更新周期打分。
IFL.describe()

I值打分:

L值打分:

F值根據(jù)發(fā)布周期打分:

??分值計算
# bins參數(shù)代表我們按照什么區(qū)間進行分組# labels和bins切分的數(shù)組前后呼應,給每個分組打標簽# right表示了右側區(qū)間是開還是閉,即包不包括右邊的數(shù)值,如果設置成False,就代表[0,30)IFL['I_SCORE'] = pd.cut(IFL['I'], bins=[0,0.03,0.06,0.11,1000],
labels=[1,2,3,4], right=False).astype(float)
IFL['F_SCORE'] = pd.cut(IFL['F'], bins=[0,7,15,30,90,1000],
labels=[5,4,3,2,1], right=False).astype(float)
IFL['L_SCORE'] = pd.cut(IFL['L'], bins=[0,5.39,9.07,15.58,1000],
labels=[1,2,3,4], right=False).astype(float)
IFL.head()
判斷用戶的分值是否大于平均值:
# 1為大于均值 0為小于均值IFL['I是否大于平均值'] =(IFL['I_SCORE'] > IFL['I_SCORE'].mean()) *1
IFL['F是否大于平均值'] =(IFL['F_SCORE'] > IFL['F_SCORE'].mean()) *1
IFL['L是否大于平均值'] =(IFL['L_SCORE'] > IFL['L_SCORE'].mean()) *1
IFL.head()
??客戶分層
RFM經(jīng)典的分層會按照R/F/M每一項指標是否高于平均值,把用戶劃分為8類,我們根據(jù)根據(jù)案例中的情況進行劃分,具體像下面表格這樣:

引入人群數(shù)值的輔助列,把之前判斷的I\F\S是否大于均值的三個值串聯(lián)起來:
IFL['人群數(shù)值'] =(IFL['I是否大于平均值'] *100) +(IFL['F是否大于平均值'] *10) +(IFL['L是否大于平均值'] *1)
IFL.head()
構建判斷函數(shù),通過判斷人群數(shù)值的值,來返回對應標簽:

將標簽分類函數(shù)應用到人群數(shù)值列:
IFL['人群類型'] = IFL['人群數(shù)值'].apply(transform_label)?
IFL.head()

??各類用戶占比
cat = IFL['人群類型'].value_counts().reset_index()
cat['人數(shù)占比'] = cat['人群類型'] / cat['人群類型'].sum()
cat


各分區(qū)up主排行top15
? 科學科普分區(qū)
high = IFL.loc[IFL['人群類型']=='高價值up主']
rank = high[['author','L','I','F']].sort_values('L',ascending=False)
rank.to_excel('rank.xlsx', sheet_name='科學科普',encoding='utf-8')

??社科人文分區(qū)

??機械分區(qū)

機械分區(qū)高價值up主只有5位,因為機械分區(qū)在科技區(qū)是個小分區(qū),發(fā)布視頻的up主僅有54位。

??野生技術協(xié)會分區(qū)

??星海

??汽車

參考文章:
1.數(shù)據(jù)不吹牛:《不到70行Python代碼,輕松玩轉RFM用戶分析模型》
2.Crossin:《B站用戶行為分析非官方報告》
3.https://github.com/Vespa314/bilibili-api/blob/master/api.md
今天為大家提供了一種數(shù)據(jù)分析的模型,用于發(fā)掘優(yōu)質up主,大家完全可以參照這種方式去發(fā)掘其他事物。
完整數(shù)據(jù)源和代碼鏈接:https://pan.baidu.com/s/1RIxOxh-TFMey9sGvZLVuJg?提取碼:bhh2
End
