• 天池新闻推荐比赛2:数据分析


    导入相关包

    import pandas as pd
    import numpy as np
    
    import matplotlib.pyplot as plt
    import seaborn as sns
    plt.rc('font', family='SimHei', size=13)
    
    import os,gc,re,warnings,sys
    warnings.filterwarnings("ignore")
    

    读取数据

    path = './data/'
    
    #####train
    trn_click = pd.read_csv(path+'train_click_log.csv')
    item_df = pd.read_csv(path+'articles.csv')
    item_df = item_df.rename(columns={'article_id': 'click_article_id'})  #重命名,方便后续match
    item_emb_df = pd.read_csv(path+'articles_emb.csv')
    
    #####test
    tst_click = pd.read_csv(path+'testA_click_log.csv')
    

    数据预处理

    rank函数设置ascending=False则按从大到小排序,即最后一次点击的排名为1

    # 对每个用户的点击时间戳进行排序
    trn_click['rank'] = trn_click.groupby(['user_id'])['click_timestamp'].rank(ascending=False).astype(int)
    tst_click['rank'] = tst_click.groupby(['user_id'])['click_timestamp'].rank(ascending=False).astype(int)
    
    #计算用户点击文章的次数,并添加新的一列count
    trn_click['click_cnts'] = trn_click.groupby(['user_id'])['click_timestamp'].transform('count')
    tst_click['click_cnts'] = tst_click.groupby(['user_id'])['click_timestamp'].transform('count')
    
    #将文章信息合并到点击日志中,得到最终的训练集
    trn_click = trn_click.merge(item_df, how='left', on=['click_article_id'])
    

    注:rank函数用法

    按从小到大排序,输出对应的排名,若有多个相同的值,排名取平均值。

    例如:

    import pandas as pd
    obj = pd.Series([7,-5,7,4,2,0,4])
    print(obj.rank())
    

    从小到大排序为[-5,0,2,4,4,7,7],-5最小,对应的排名为1。因为有两个相同的7(分别排名为6,7),所以7排名为(6+7)/2 = 6.5

    输出:

    0    6.5
    1    1.0
    2    6.5
    3    4.5
    4    3.0
    5    2.0
    6    4.5
    dtype: float64
    

    总体数据浏览

    # 查看前5行数据
    trn_clicl.head()
    

    image-20201119112706647

    #获取各个特征的基本属性
    trn_click.describe()
    

    image-20201119112649376

    #查看各个特征的分布情况,纵坐标为百分比
    plt.figure()
    plt.figure(figsize=(15, 20))
    i = 1
    for col in ['click_article_id', 'click_environment', 'click_deviceGroup', 'click_os', 'click_country', 
                'click_region', 'click_referrer_type', 'rank', 'click_cnts']:
        plot_envs = plt.subplot(5, 2, i)
        i += 1
        v = trn_click[col].value_counts().reset_index()[:10]
        fig = sns.barplot(x=v['index'], y=v[col]/trn_click.shape[0]*100)
        plt.title(col)
    plt.tight_layout()
    plt.show()
    

    image-20201126230732825

    ​ 对于新闻id而言,阅读最多的占了总文章数目的1%,点击环境最多的是4(90+%),其他的分析就不一一叙述了,我们可以从这些图片可视化各个特征的分布情况,为下一步的分析提供参考。

    文章信息查看

    1. 文章类型分布
    print(item_df['category_id'].nunique())     # 461个文章主题
    plt.plot(sorted(item_df['category_id'].value_counts()))
    

    image-20201126214840487

    不同类别的文章数目分布差异较大,绝大多数类型的文章数目少于1000

    1. 文章字数分布

      item_df['words_count'].value_counts()
      
      176     3485
      182     3480
      179     3463
      178     3458
      174     3456
      ...
      845        1
      710        1
      965        1
      847        1
      1535       1
      Name: words_count, Length: 866, dtype: int64
      

      文章的字数大多在100-200之间

    2. 文章被点击次数统计

    item_click_count = sorted(user_click_merge.groupby('click_article_id')['user_id'].count(), reverse=True)
    plt.plot(item_click_count)
    

    image-20201126215935916

    ​ 点击量大于1000的文章可以认为是热门文章

    用户信息查看

    1. 点击次数
    #画出点击次数在前50的用户
    user_click_merge = trn_click.append(tst_click)
    user_click_item_count = sorted(user_click_merge.groupby('user_id')['click_article_id'].count(), reverse=True)
    plt.plot(user_click_item_count[:50])
    

    image-20201126223958815

    ​ 可以看见前50名的点击次数都大于100,一种思路是把点击次数大于100的作为活跃用户。

    1. 点击文章类型查看
    plt.plot(sorted(user_click_merge.groupby('user_id')['category_id'].nunique(), reverse=True))
    

    image-20201126212011508

    ​ 由图可见大部分人的点击次数在10次以下,只有少部分人的点击次数比较广泛

    1. 点击文章长度查看

      plt.plot(sorted(user_click_merge.groupby('user_id')['words_count'].mean(), reverse=True))
      

      image-20201126212315054

      大多数人都在200-300之间,说明大家对短文更感兴趣。

    总结

    经过分析可以得出如下的结论:

    1. 可以通过数据查看确定热门文章和热门用户
    2. 不同文章的长度和文章类型被点击的次数不一样
    3. 文章本身分布差异也很大,不同类型的和不同字数的文章数目本身也不一样,所以可能导致2.的情况出现
  • 相关阅读:
    POJ3171 线段树优化dp
    Codeforces Round #590 (Div. 3)
    POJ2777 线段树区间染色问题
    POJ2182 Lost Cows 树状数组,二分
    P1908 逆序对 树状数组
    2019 Multi-University Training Contest 3
    主席树板子题区间第k小
    权值线段树板子题
    KMP板子题
    稀疏贝叶斯
  • 原文地址:https://www.cnblogs.com/zwrAI/p/14045244.html
Copyright © 2020-2023  润新知