数据分析实战(三) 因子分析模型挖掘CSDN优质博主

前情回顾:爬取CSDN博主信息——Selenium VS Webscraper,来看看你写的博客各项数据达标了没~

一、数据介绍

数据来源:从CSDN首页Python、Java等十个栏目共爬取7868条数据
数据字段

字段名含义
blog_name博主名
code_time码龄
blog_num博客数
view_num访问量
fans_num粉丝数
like_num点赞数
comments_num评论数
collections_num收藏数

二、数据预处理

  • 首先,我们来预览下数居
import pandas as pd
df = pd.read_csv('csdn_user.csv',encoding='gb18030')
df.info()

在这里插入图片描述
从结果来看,除博客数外,其他均为字符型变量。code_time(码龄)存在一条缺失值,删除即可。

df = df.dropna(how='any',axis=0)
  • 由于不同栏目下会有同一作者发布的博客,所以需要依据博主名进行去重处理
df1 = df.drop_duplicates(subset='blog_name',keep='last',ignore_index=True)
print('重复数据共{}条,现有数据{}条'.format(len(df)-len(df1),len(df1)))

在这里插入图片描述
从结果来看,共2680条重复数据,现有5187条博主信息数据。

  • 为后续分析方便,这里将所有的"万+"都转化为对应的数字,如1万+转化为10000(所有的博主的博客数尚未达到一万,故不用转化)。此外,为了解同层次博主排名,加入我自己的博客信息。
variable=['view_num','fans_num','likes_num','collections_num']
for var in variable:
    df1[var]=df1[var].map(lambda x:int(x.replace('万+','0000') if '万+' in x else x))
df1 = df1.append([{'blog_name':'皖渝','code_time':'码龄2年','blog_num':43,'view_num':40000,
                   'fans_num':113,'likes_num':82,'comments_num':99,'collections_num':258}],ignore_index=True)

三、探索数据分析

(1) 各类码龄博主分布及平均水平

def sns_bar(data,column,ylab,title,adjust_num):
	import numpy as np
	import matplotlib.pyplot as plt
	import seaborn as sns
    plt.rcParams['axes.unicode_minus']=False
	sns.set(font='kaiti')
    index=np.arange(len(data))
    plt.figure(figsize=(10,6))
    g=sns.barplot(data.index,data[column],
                  palette='Set3',alpha=0.8)
    for name,count in zip(index,data[column]):
        g.text(name,count+adjust_num,int(count),
        ha='center',va='bottom')
    plt.title(title)
    plt.ylabel(ylab)
    plt.xticks(rotation=90)
    plt.show()

bloger_code=df1['code_time'].value_counts().to_frame()
sns_bar(bloger_code,'code_time','人数','CSDN博主码龄分布',2)

在这里插入图片描述

从上图来看,在本次爬取的样本中,码龄2年的博主最多,共1124人;其次是码龄1年和3年的,总体来看"年轻"的博主占多数呀。此外,码龄超过15年(包括)的共28人,最长竟达到了20年!(respect)

顺便来计算下,各个码龄层次的博主数据的平均分布情况

num_variable=['blog_num','view_num','fans_num','likes_num','comments_num','collections_num']
bloger_data = df1.groupby('code_time')[num_variable].mean()
bloger_data

在这里插入图片描述
从上表来看,码龄2年的博主平均发博75篇平均访问量为47043次平均粉丝数为92个平均点赞数为81次平均评论数为36条平均收藏数为182条。(哈哈哈,除了发博数和访问量,我都达标了,看来达到平均水平了呀,未来继续努力~)


(2) 构建博主影响力模型

用因子分析法构建影响力模型,如下所示:
s c o r e = λ 1 F 1 + λ 2 F 2 + λ 3 F 3 + . . λ k F k score=\lambda_1 F_1+\lambda_2F_2+\lambda_3F_3+..\lambda_kF_k score=λ1F1+λ2F2+λ3F3+..λkFk
其中, s c o r e score score为单个博主的影响力综合值, λ \lambda λ为各因子的方差贡献率,F为各个公共因子

这里使用的则是Python自带因子分析库FactorAnalyzer(默认公共因子的数量为3)

1.变量标准化

from sklearn import preprocessing
num_variable=['blog_num','view_num','fans_num','likes_num','comments_num','collections_num']
df2=pd.concat([df1[['blog_name','code_time']],
              pd.DataFrame(preprocessing.scale(df1[num_variable]),columns=num_variable)],axis=1)

2.确定公共因子个数

import numpy.linalg as nlg
C=df2.corr()
eig_value,eig_vector=nlg.eig(C)
eig=pd.DataFrame() #利用变量名和特征值建立一个数据框
eig['names']=df2.columns[2:]#列名
eig['eig_value']=eig_value#特征值

# 确定公共因子个数
for k in range(1,7):
    var_cum = eig['eig_value'][:k].sum()/eig['eig_value'].sum()
    print('累计方差贡献率为{}'.format(var_cum))
    if var_cum>=0.8:
        print('确定公共因子数为{}'.format(k))
        break

在这里插入图片描述
从输出结果来看,当公共因子数为4个时,累计方差率达到82%,即可解释原数据82%的信息。

3.比较旋转前后载荷矩阵

from factor_analyzer import FactorAnalyzer,Rotator
data = df2[num_variable]  #提取数值型变量
fa = FactorAnalyzer(4,rotation=None)
fa.fit(data)
print('未旋转前因子载荷矩阵:\n',fa.loadings_)

rotator = Rotator()
print("按正交旋转后的因子载荷矩阵:\n", rotator.fit_transform(fa.loadings_))

在这里插入图片描述

不难看出,旋转后载荷矩阵各列中的值差别较大。公共因子F1在评论数上的载荷较大,可命名为互动因子;公共因子F2在博客数上载荷较大,可命名为创作因子;公共因子F3在点赞数和收藏数上有着较大的载荷,可命名为认可因子;公共因子F4在粉丝数上有较大的载荷,可命名人气因子

4.计算综合得分

fa1 = FactorAnalyzer(4,rotation='varimax')  #使用正交旋转
fa1.fit(data)
def score(factors):
    return sum(factors*fa1.get_factor_variance()[1])
scores = []
for i in range(len(fa1.transform(data))):
    new = score(fa1.transform(data)[i])
    scores.append(new)
df2['scores']=scores

#综合影响力前10名博主可视化
outstaning_bloger = df2.sort_values(by='scores',ascending=False)[:10][['blog_name','scores']].set_index('blog_name')
sns_bar(outstaning_bloger,'scores','综合影响力','综合影响力排名前十位10位优质博主',0.02)

在这里插入图片描述

排名前三名的是沉默的王二,guolin,敖丙,向大佬们学习!

再来计算下,我的综合影响力在码龄2年的博主中的排名吧~

code_time2_group = df2[df2['code_time']=='码龄2年'].sort_values(by='scores',ascending=False,ignore_index=True)
my_rank = code_time2_group[code_time2_group['blog_name']=='皖渝'].index+1
print('码龄2年的博主共{}人,我的排名为第{}名,比例为{}'.format(len(code_time2_group),my_rank[0],my_rank[0]/len(code_time2_group)))             

在这里插入图片描述
在码龄2年的博主中,我的排名为149名,挤进了前15%呀~


(3) 探究影响力与码龄的相关关系

在得到所有博主的综合影响力后,我们可以思考一个问题:综合影响力是否和码龄的长短有关呢?

1、从纯数据角看,我们可以计算各类码龄博主的平均影响力,如下图所示:

code_score = df2.groupby('code_time')['scores'].mean().to_frame()
code_score = code_score.sort_values(by='scores',ascending=False)
sns_bar(code_score,'scores','平均影响力','各类码龄博主的平均影响力',0.0005)

在这里插入图片描述
从上图来看,明显看出综合影响力较高的博主大多为老博主,而影响力较低的博主大多为新博主。

2、从统计视角看,该问题可转化为不同码龄层次博主的影响力是否有显著性差异。此时,我们尝试使用单因素方差分析,但该方法使用前需要满足两个假定条件:方差齐性和正态性。正态性一般对方差分析结果影响不大,在此忽略。以下,就进行方差齐性的检验。

原假设 H 0 H_0 H0:各类码龄博主的影响力方差相等

from scipy import stats
code_time_list = ['码龄'+str(i)+'年' for i in range(19)]+['码龄20年'] 
total_df=[]
for code_time in code_time_list:
    total_df.append(df2[df2['code_time']==code_time]['scores'])
w,p = stats.levene(*total_df)
w,p

在这里插入图片描述
结果表示,在0.05显著性水平下,强烈拒绝原假设。故方差齐性的假设不满足,无法使用单因素方差分析进行探究。继而,我们可以转向非参数统计。在Python中Kruskal可以检验多样本均值差异,且无需假定各样本方差相等。

k,p = stats.kruskal(*total_df)
k,p

在这里插入图片描述

结果显示,在0.05显著性水平下,强烈拒绝原假设。故我们有充分理由认为不同码龄博主的影响力是具有显著差异的。

以上就是本次分享的全部内容~

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值