• 零基础天池新闻推荐初学-02-数据分析


    01 数据分析作用和关注点

    主要作用:在于熟悉了解整个数据集的基本情况,包括每个文件里有哪些数据,具体每个文件中的每个字段表示什么实际含义,以及数据集中特征中之间的相似性;

    rs的数据分析的主要关注点:

    • 用户本身的基本属性
    • 文章基本属性
    • 用户和文章交互的一些分布
    • 召回策略的选择
    • 考虑特征工程方面做一下准备

    02 使用用pandas_profiling来做数据分析

    #%% 01 导包
    
    %matplotlib inline
    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")
    
    #%% 02 读取数据
    
    path = 'E:\阿里云开发者-天池比赛\06_天池新闻APP推荐\'
    save_path = 'E:\PycharmProjects\TianChiProject\00_山枫叶纷飞\competitions\006_dw_RecommandNews\'
    
    #####train
    # 训练集用户点击日志
    train_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
    # 测试集用户点击日志
    test_click = pd.read_csv(path+'testA_click_log.csv')
    
    #####合并 (数据格式一致)
    tt_click = pd.concat([train_click, test_click], axis=0)
    
    #%% 03 数据预处理
    dfs = [train_click, test_click, tt_click]
    names = ['train_click', 'test_click', 'tt_click']
    # 3.1 计算用户点击的时间戳进行逆序排序
    # for df in dfs:
    #     df['rank'] = df.groupby(['user_id'])['click_timestamp'].rank(ascending=False).astype(int)
    
    # 3.2 计算用户点击文章的次数, 并添加新的一列count
    # for df, name in zip(dfs, names):
    #     df['count'] = df.groupby(['user_id'])['click_timestamp'].transform('count')
    
    #%% 04 用pandas_profiling生成三分数据报告
    import pandas_profiling
    for df, name in zip(dfs, names):
        df = df.merge(item_df, how='left', on=['click_article_id'])
        pfr = pandas_profiling.ProfileReport(df)
        pfr.to_file(save_path + "profiling\{}_pandas_profiling.html".format(name))
    

    03 数据浏览(以train+test合并后数据为例,train和test的数据格式基本一致)

    -1. 由分别的Profiling Report可以得出:训练集的用户ID由0 ~ 199999,而测试集A的用户ID由200000 ~ 249999。

    1. 总数据行数为163K
    2. user_id 总数为250K,训练集200K,测试集50K
    3. 点击时间click_timestamp ,分布均匀,几乎没有重复值 (受pandas-profiling的分桶bin影响看着有些起伏)
    4. 点击环境click_environment
      从点击环境click_environment来看,仅有2499 次(占0.2%)点击环境为1;仅有38948次(占2.4%)点击环境为2;剩余(占97.5%)点击环境为4。
    5. 点击设备组click_deviceGroup
      可以看出设备1和设备3的占比分别为62.2%和34.2%。

    04 用pandas_profiling生成三份数据报告

    import pandas_profiling
    for df, name in zip(dfs, names):
        df = df.merge(item_df, how='left', on=['click_article_id'])
        pfr = pandas_profiling.ProfileReport(df)
        pfr.to_file(save_path + "profiling\{}_pandas_profiling.html".format(name))
    

    05 数据分析(以train+test合并后数据为例,train和test的数据格式基本一致)

    为后续构建新的特征做准备。

    5.1 用户重复点击

    user_click_count = tt_click.groupby(['user_id', 'click_article_id'])['click_timestamp'].agg({'count'}).reset_index()
    # print(user_click_count)
    user_click_count.sort_values(by='count', inplace=True)
    print('打印前10个和后10个:')
    print(user_click_count[:10])
    print(user_click_count[-10:])
    
    #%% 5.1.2 分析重复的数量类型
    
    user_click_count['count'].unique()
    
    #%% 5.1.3 用户点击新闻次数分布
    
    user_click_count.loc[:,'count'].value_counts()
    """
    可以看出:有1605541(约占99.2%)的用户未重复阅读过文章,仅有极少数用户重复点击过某篇文章。 
    这个也可以单独制作成特征.
    """
    

    5.2 用户点击环境变化分析

    这个看着没啥意义,跳过

    5.3 用户点击新闻数量的分布

    tt_ucc = tt_click.groupby('user_id')['click_article_id'].count()
    user_click_item_count = sorted(tt_ucc, reverse=True)
    plt.plot(user_click_item_count)
    

    5.4 取前50看看

    plt.plot(user_click_item_count[0:50])
    """
    点击次数排前50的用户的点击次数都在100次以上。思路:我们可以定义点击次数大于等于100次的用户为活跃用户,这是一种简单的处理思路, 判断用户活跃度,更加全面的是再结合上点击时间,后面我们会基于点击次数和点击时间两个方面来判断用户活跃度。
    """
    

    5.5 由上上面的图得出, 点击次数排名在25000之后.点击次数就变得特别低,具体分析; 可以看出点击次数小于等于两次的用户非常的多,这些用户可以认为是非活跃用户

    plt.plot(user_click_item_count[25000:])
    

    5.6 新闻点击次数分析:新闻的冷热门分类

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

    5.6.2 取热门新闻前100看看

    plt.plot(item_click_count[:100])
    """
    可以看出点击次数最多的前100篇新闻,点击次数大于1000次;
    点击次数最多的前20篇新闻,点击次数大于2500。思路:可以定义这些新闻为热门新闻, 这个也是简单的处理方式,后面我们也是根据点击次数和时间进行文章热度的一个划分。
    """
    

    5.6.3 取冷门新闻热度排名3000以后的新闻看看

    plt.plot(item_click_count[3000:])
    """
    可以发现很多新闻只被点击过几次。
    思路:可以定义这些新闻是冷门新闻。
    """
    

    5.7 新闻共现频次:两篇新闻连续出现的次数

    tmp = tt_click.sort_values('click_timestamp')
    tmp['next_item'] = tmp.groupby(['user_id'])['click_article_id'].transform(lambda x:x.shift(-1))
    union_item = tmp.groupby(['click_article_id','next_item'])['click_timestamp'].agg({'count'}).reset_index().sort_values('count', ascending=False)
    union_item[['count']].describe()
    

    tmp.sort_values('排序一下,发现shift是反转传播方向')

    5.7.2 新闻共现频次 画个图 直观地看一看

    x = union_item['click_article_id']
    y = union_item['count']
    plt.scatter(x, y)
    

    5.7.3 至少共现一次的统计

    plt.plot(union_item['count'].values[40000:])
    """
    由图可知:大概有70000+个pair至少共现一次。
    """
    

    5.8 新闻文章类型的分类信息

    #不同类型的新闻出现的次数
    print(tt_click.columns)
    plt.plot(tt_click['category_id'].value_counts().values)
    
    #%% 5.9. 用户点击的新闻类型的偏好(兴趣的广泛程度)
    tt_click.groupby('user_id')['category_id'].nunique().reset_index().describe()
    plt.plot(sorted(tt_click.groupby('user_id')['category_id'].nunique(), reverse=True))
    """
    从上图中可以看出有一小部分用户阅读类型是极其广泛的,大部分人都处在20个新闻类型以下。
    """
    

    5.10. 用户查看文章的长度的分布

    """
    通过统计不同用户点击新闻的平均字数,这个可以反映用户是对长文更感兴趣还是对短文更感兴趣。
    结论:
    从上图中可以发现有一小部分人看的文章平均词数非常高,也有一小部分人看的平均文章次数非常低。
    
    大多数人偏好于阅读字数在200-400字之间的新闻。
    
    """
    plt.plot(sorted(tt_click.groupby('user_id')['words_count'].mean(), reverse=True) )
    #挑出大多数人的区间仔细看看
    plt.plot(sorted(tt_click.groupby('user_id')['words_count'].mean(), reverse=True)[1000:45000])
    

    5.11. 用户点击新闻的时间分析

    #为了更好的可视化,这里把时间进行归一化操作
    from sklearn.preprocessing import MinMaxScaler
    mm = MinMaxScaler()
    tt_click['click_timestamp'] = mm.fit_transform(tt_click[['click_timestamp']])
    tt_click['created_at_ts'] = mm.fit_transform(tt_click[['created_at_ts']])
    
    user_click_merge = tt_click.sort_values('click_timestamp')
    def mean_diff_time_func(df, col):
        df = pd.DataFrame(df, columns={col})
        df['time_shift1'] = df[col].shift(1).fillna(0)
        df['diff_time'] = abs(df[col] - df['time_shift1'])
        return df['diff_time'].mean()
        ```
    # 点击时间差的平均值
    ``` python
    mean_diff_click_time = user_click_merge.groupby('user_id')['click_timestamp', 'created_at_ts'].apply(lambda x: mean_diff_time_func(x, 'click_timestamp'))
    plt.plot(sorted(mean_diff_click_time.values, reverse=True))
    

    06 总结 (复制粘贴)

    通过数据分析的过程, 我们目前可以得到以下几点重要的信息, 这个对于我们进行后面的特征制作和分析非常有帮助:

    1. 训练集和测试集的用户id没有重复,也就是测试集里面的用户没有模型是没有见过的
    2. 训练集中用户最少的点击文章数是2, 而测试集里面用户最少的点击文章数是1
    3. 用户对于文章存在重复点击的情况, 但这个都存在于训练集里面
    4. 同一用户的点击环境存在不唯一的情况,后面做这部分特征的时候可以采用统计特征 (这点在自己尝试做分析的时候没有考虑到,给忽略了)
    5. 用户点击文章的次数有很大的区分度,后面可以根据这个制作衡量用户活跃度的特征
    6. 文章被用户点击的次数也有很大的区分度,后面可以根据这个制作衡量文章热度的特征
    7. 用户看的新闻,相关性是比较强的,所以往往我们判断用户是否对某篇文章感兴趣的时候, 在很大程度上会和他历史点击过的文章有关
    8. 用户点击的文章字数有比较大的区别, 这个可以反映用户对于文章字数的区别
    9. 用户点击过的文章主题也有很大的区别, 这个可以反映用户的主题偏好
    10. 不同用户点击文章的时间差也会有所区别, 这个可以反映用户对于文章时效性的偏好

    所以根据上面的一些分析,可以更好的帮助我们后面做好特征工程, 充分挖掘数据的隐含信息。

    07 pandas语法复习笔记

    • apply(),会将待处理的对象拆分成多个片段,然后对各片段调用传入的函数,最后尝试将各片段组合到一起。
    • transform(),形变、改变,会将一个函数应用到各个分组;举例count()会聚合对应的分组,transform('count')会把分组后的函数应用到每一行数据上——保持总数据行数不变。
    • agg,pandas的数据聚合方法,可以对一列或者多列使用函数,将一个函数使用在一个数列上,然后返回一个标量的值。内置函数名需要用引号。

    08 引用链接

  • 相关阅读:
    nginx 服务企业应用
    3D模型展示以及体积、表面积计算
    php实现MySQL读写分离
    three.js实现3D模型展示
    thinkphp5.1+think-queue
    GIT记住远端仓库地址密码
    php实现采集(仅做参考)
    phpStudy集成环境apche+openssl配置本地https
    HTTP与HTTPS区别
    在父页面用Iframe加载子页面时,将父页面的title替换成子页面title
  • 原文地址:https://www.cnblogs.com/zhazhaacmer/p/14064135.html
Copyright © 2020-2023  润新知