暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【数据分析】一个实战小案例

学之初 学之时 2021-07-30
667


撰文/Iris帆

排版/Iris帆
全文/3650字(包含代码)


导读


接着上期的数据分析究竟是分析什么?本期将由一个小案例,从代码和分析流程出发,介绍数据分析的思路,其实也是我最近做数据分析的总结。内容依旧不复杂,运用的是基本的数分知识。题外话:上期谈到我面试的一家英国媒体公司市场研究分析职位,写上期的时候还在等结果,刚得到反馈是「未拿到offer」。很可惜,也有些低落,但是学习依旧要坚持,还在等另一份工作的反馈。




本期重点话题


  • Python数据分析三大基本流程:数据概况分析、数据整理&清理、探索性分析&可视化

  • 数据分析思维总结、复盘



拿到数据之后,首要任务是对数据进行整体认知——包括有哪些数据集,各数据集都有什么变量,变量之间都有什么关系等等。具体地,用df.head()
df.info()
搭配使用,就可以查看数据集头5行的内容和数据集的整体结构(变量类型,样本行列数目等)。


为什么认识数据很重要呢?因为数据分析可以说是挖掘数据内部,变量之间关系的技能。要做到合格的数据分析,得先认清各变量的含义,甚至通过已知变量挖掘出新的变量。


先举几个简单的例子,一个”日期时间“变量,就可以提取出”年、月、周、时、分、秒“6个变量;又比如已知数据集中有”销售额“和”成本“,就可以通过销售额-成本 = 利润
来计算出”利润"这个新变量。前两个例子都是很直白简单的,复杂了说,有些变量可能包含的是字符串文本,如果字符串具有相似的格式,那么我们完全可以将有用信息提取出来,单独形成新的一列,也就是新的变量。


下面通过某网购平台案例来解释基本的数据分析思维流程(只包含重要代码部分),假定该网购平台希望了解用户复购情况。


通过对背景的理解,可以初步知道我们分析的目的是——分析具有哪些特征的用户有更高的复购率?


数据概况分析


首先来认识我们的数据。「认识数据」首先是一个观察的过程,这一步,我们需要用直接的描述性的语言,记录下数据集的特点。


比如数据集df_user_info
是用户基本信息,包含user_id
(用户id)、age_range
(用户年龄)、gender
(用户性别)。通过df_user_info.info()
(如图1)我们可以看到该数据集一共有424170行样本,其中3个变量的数据类型都是数值型变量,age_range和gender包含缺失值。


小提醒:性别中女性由数字0表示,男性由数字1表示,2
NULL
都表示未知;年龄也是由数字表示,用户年龄段 1
为<18,2
为[18,24],3
为[25,29],4
为[30,34],5
为[35,39],6
为[40,49],7
8
为≥50,0
NULL
表示未知。


图1


「样本数」、「数据类型」、「缺失值」就是我们使用df.info()
的关注点,也是需要我们记录下的数据集特点。其中,「缺失值」是我们需要重点处理的,通常的方法是直接删除包含缺失值的行,或者加以填充(因情况而定)。


查看了数据结构,可能会产生这样的疑问:“user_id有424170个,是否就是有这么多的用户呢?会不会有重复行?或者会不会相同的用户留了两份信息?”


我们可以通过sum(df_user_info.duplicated())
得到有多少个重复行。也可以用df_user_info['user_id'].nunique()
来确定有多少个唯一用户id,来判断与数据集行数是否一致,以此判断是否有重复值的情况。


另一个数据集是df_train_data
,包含user_id
(用户id)和label
(是否复购,0代表否,1代表是)。


最后一个数据集df_log_data
是用户在平台的交互信息,包含user_id
(用户id)、item_id
(商品id)、cat_id
(品类id)、seller_id
(商家id)、brand_id
(品牌id)、date
(用户与商品交互的日期)、action_type(用户行为类型)。


这里需要知道的就是action_type是类别型变量,于是自然地就会想知道action_type包含哪些类型?各类型的占比又是多少?这个时候我们可以使用df_log_data['action_type'].value_counts()
来看各个类型分别有多少数目,也可以使用df_log_data['action_type'].value_counts(1)
来看各类型的占比。


小提醒:action_type包含0
(单击)、1
(添加购物车)、2
(购买)和3
(添加到收藏夹)4个行为。下一个错别字


数据整理&清理


认识了数据之后,我们需要针对缺失值进行处理,也就是我们常说的——数据清理。


通常情况,如果缺失值占比小,那么直接删除;如果缺失值占比大,那就要进行多方考虑,比如“缺失的这部分信息可以从哪些地方获取?如果无法获取如何进行填充?等等”。


先来查看缺失值占比。前面有提到age_range
这个变量,7
8
均为≥50,0
NULL
都表示未知,也就是缺失值,gender
变量,2
NULL
都表示未知。所以,我们需要先进行「数据一致化」,具体做法是:


  • age_range
    中的8
    全部替换为7

  • age_range
    中的0
    全部替换为NULL

  • gender
    中的2全部替换为NULL


代码如下:


    #将age_range中的0替换为NA值(将0和NULL统一)
    df_user_info['age_range'] = df_user_info[
    'age_range'].replace(0,np.NaN)
    #将age_range中的8都统一为7,因为7和8都表示一个年龄段 ">=50"
    df_user_info['age_range'] = df_user_info[
    'age_range'].replace(8,7)
    #将gender中的20替换为NA值(将2和NULL统一)
    df_user_info['gender'] = df_user_info[
    'gender'].replace(2,np.NaN)


    一致化处理完后,我们就可以来查看缺失值的占比了,代码如下:


      #gender缺失值占比
      df_user_info['gender'].isna().sum()/
      df_user_info.shape[0]
      #age_range缺失值占比
      df_user_info['age_range'].isna().sum()/
      df_user_info.shape[0]


      结果中如果缺失值占比小,比如少于5%,可以使用df.dropna()
      直接删除包含缺失值的行;如果缺失值比例大,且无法获取缺失值这部分的真实数据,可以考虑以“0,平均值,中位数”进行填充。


      以本案例为例,代码如下:


        #删除gender中包含缺失值的行
        df_user_info.dropna(subset = [2])
        #以所有年龄段加起来的平均值填充age_range中的缺失值
        df_user_info['age_range'].fillna(
        df_user_info.age_range.mean())


        数据清理完之后,我们再次回到本案例的目的——分析具有哪些特征的用户有更高的复购率?回顾刚才的分析,我们只简单分析了用户的年龄和性别,也就是df_user_info
        这一个数据集的特征,那么df_log_data
        又该如何分析呢?这里就需要我们进一步思考「用户特征」的含义。


        年龄和性别很好理解,但要是与用户购买行为挂钩,就不得不与用户action_type联系起来,用户习惯购买的时间,以及用户喜欢的品牌、店铺和商品。综合来看,可以考虑以下几点:


        • 用户的性别:男性和女性,谁具有更高复购率?

        • 用户的年龄:哪个年龄段具有更高复购率?

        • 什么日期用户有更高复购率?

        • 什么样的交互行为体现更高复构率?


        为了解答上面几个要点,我们要对原本的3个数据集进行整理,从而生成出一个新的数据集。


        首先我们已经知道3个数据集都含有user_id,所以可以通过user_id将3个数据集聚合起来。其次,我们要把每个用户在不同action_type交互类型的次数,以及交互行为总次数分离出单独的列,即一共"购买"(2)了多少次,"加入购物车"(1)多少次等等。


        代码如下:


          #针对user_log_data统计各交互类型次数
          #行转列
          user_log_tmp= user_log_data.groupby(
          ['user_id','seller_id'])['action_type'
          ].value_counts().unstack()


          #添加求和列
          user_log_tmp['sum']= user_log_tmp.sum(axis= 1)


          #在所有列名前加一个“action"
          #reset_index()重置索引
          user_log_tmp= user_log_tmp.rename(
          columns=lambda x:f'action_{x}').reset_index()


          如果我们用user_log_tmp.head()来查看新建立的数据集的前5行,可以得到类似以下结果(如图2):


          图2


          这里的NaN
          是指没有进行任何交互行为,所以可以用0
          来进行填充user_log_tmp = user_log_tmp.fillna(0)

          最后,就是将各数据集合并为新的数据集df_final
          ,代码如下:


            #将df_train_data, df_user_info和user_log_tmp合并
            df_final= df_train_data.merge(df_user_info,  
            on= "user_id", how= "left")
            df_final = df_final.merge(
            user_log_tmp, on= "user_id", how = 'left' )


            探索性分析&可视化


            我们将用新数据集df_final
            进行可视化探索,可视化部分在数据分析中也是最直观表达结果的部分。


            联系刚才探讨的「用户特征」,可视化部分就很清晰了,那么下面就一个例子来解释可视化思维。


            首先我们依旧可以用统计的形式发现一些数据上的规律,比如:

              age_gender = train_data_with_user.groupby(
              ['age_range','gender'])['label'].mean().reset_index()
              age_gender


              上面这个代码做的事情是:按照年龄段和性别分类,平均复购率分别是多少。得到的结果如下(如图3):



              图3


              统计表的形式并不能有效地帮助我们理解数据,所以我们采用可视化的直观表达,,代码如下:


                sns.barplot(x= 'age_range', y= 'label', 
                hue= 'gender', data= age_gender)
                plt.axhline(y=df_final['label'].mean(),c='red')
                #红线为大盘的平均复购率


                可视化结果如下(如图4):


                图4


                通过图4,我们很容易发现以下特征(注:0为女性,1为男性):


                • 无论什么年龄段,女性的复购率都要比男性高;

                • 年龄段在4~7(≥ 30岁)的女性用户复购率均高于大盘。


                这里只是举出针对复购率与性别和年龄的关系可视化图,其实交互类型上,理论也是一样的。首先将df_final
                数据集按照不同action_type
                分类,平均复购率分别是多少。


                总结复盘


                最后总结一下上述数据分析思路:


                因为关注点是用户复购,朝着这个思路,可以联想到一个问题是:什么样的用户更容易产生“复购”?自然地,就会与用户的性别、年龄段和与商铺等交互信息特征联系起来。上面的分析未包括更细节的与商品和商品类别本身的交互行为联系,但在现实工作中是会深入进行探讨的(也是能力上的区分)。


                总而言之,数据概况、数据处理&清理、探索性分析&可视化,这3大块(理解含义即可,可自行分块,更名)的分析步骤是数据数据分析中的基础部分。初级数据分析师往往只要求这些部分,而不对特征工程、建模和模型评估等做出要求。


                在进行初级数据分析时,一定要关注核心目的。过程中间可以进行发散,对感兴趣的部分进行分析和可视化,同时要注意分析的内容是否和目的一致。


                今天的分享就到这里,感谢大家的阅读,我们下期见咯!

                期待您的关注——来自初识学习官Iris帆

                扫码关注我吧

                学之初 学之时
                我努力前行,想在停下来的时候,把人生分享给您
                文章转载自学之初 学之时,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                评论