天池新闻推荐比赛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.的情况出现
原文地址:https://www.cnblogs.com/zwrAI/p/14045244.html