零基础天池新人赛:新闻推荐-Phase Two-数据分析

特征含义

user_id 用户id
click_article_id 点击文章id
click_timestamp 点击时间戳
click_environment 点击环境
click_deviceGroup 点击设备组
click_os 点击操作系统
click_country 点击城市
click_region 点击地区
click_referrer_type 点击来源类型
article_id 文章id,与click_article_id相对应
category_id 文章类型id
created_at_ts 文章创建时间戳
words_count 文章字数
emb_1,emb_2,…,emb_249 文章embedding向量表示

提交结果

user_id,article_1,article_2,article_3,article_4,article_5。
其中user_id为用户id, article_1,article_2,article_3,article_4,article_5为预测用户点击新闻文章Top5的article_id依概率从高到低排序。

数据分析源代码

导包

%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")
12345678910

数据读取

path = 'C:/ml_data/news/'

#####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')
12345678910

计算用户点击rank和点击次数

# 对每个用户的点击时间戳进行排序
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)
123
#计算用户点击文章的次数,并添加新的一列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')
123

将文章细节和点击的表格拼接起来,方便数据分析。

trn_click = trn_click.merge(item_df, how='left', on=['click_article_id'])
1

训练集中包含20W个用户。

trn_click.user_id.nunique()
1

每个用户至少点击了两次。

trn_click.groupby('user_id')['click_article_id'].count().min()
1

在这里插入图片描述

从点击时间clik_timestamp来看,分布较为平均,可不做特殊处理。由于时间戳是13位的,后续将时间格式转换成10位方便计算。

从点击环境click_environment来看,仅有1922次(占0.1%)点击环境为1;仅有24617次(占2.3%)点击环境为2;剩余(占97.6%)点击环境为4。

从点击设备组click_deviceGroup来看,设备1占大部分(60.4%),设备3占36%。
查看测试集文章详细信息

tst_click = tst_click.merge(item_df, how='left', on=['click_article_id'])
1

查看文章重复点击次数

user_click_merge = trn_click.append(tst_click)
user_click_count.loc[:,'count'].value_counts() 
12

大约有99.2%的用户没有重复点击文章。
用户点击环境变化分析

def plot_envs(df, cols, r, c):
    plt.figure()
    plt.figure(figsize=(10, 5))
    i = 1
    for col in cols:
        plt.subplot(r, c, i)
        i += 1
        v = df[col].value_counts().reset_index()
        fig = sns.barplot(x=v['index'], y=v[col])
        for item in fig.get_xticklabels():
            item.set_rotation(90)
        plt.title(col)
    plt.tight_layout()
    plt.show()
1234567891011121314
sample_user_ids = np.random.choice(tst_click['user_id'].unique(), size=5, replace=False)
sample_users = user_click_merge[user_click_merge['user_id'].isin(sample_user_ids)]
cols = ['click_environment','click_deviceGroup', 'click_os', 'click_country', 'click_region','click_referrer_type']
for _, user_df in sample_users.groupby('user_id'):
    plot_envs(user_df, cols, 2, 3)
12345

在这里插入图片描述
可以看出绝大多数数的用户的点击环境是比较固定的。思路:可以基于这些环境的统计特征来代表该用户本身的属性。更多的图片没有放上来。

用户点击新闻数量的分布

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

查看点击次数在前50的用户

plt.plot(user_click_item_count[:50])
1

点击次数排前50的用户的点击次数都在100次以上。思路:我们可以定义点击次数大于等于100次(或者自定义阈值)的用户为活跃用户,这是一种简单的处理思路, 判断用户活跃度,更加全面的是再结合上点击时间,后面我们会基于点击次数和点击时间两个方面来判断用户活跃度。
新闻点击次数分析

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

可以看出点击次数最多的前100篇新闻,点击次数大于1000次。做特征工程时,可以定义热点新闻。
新闻共现频次:两篇新闻连续出现的次数

tmp = user_click_merge.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()
1234

由统计数据可以看出,平均共现次数2.88,最高为1687。说明用户看的新闻,相关性是比较强的。在做推荐算法时,可以根据用户之前看过的新闻,做联合推荐。
新闻文章信息

plt.plot(user_click_merge['category_id'].value_counts().values)
1

用户点击的新闻类型的偏好

plt.plot(sorted(user_click_merge.groupby('user_id')['category_id'].nunique(), reverse=True))
1

有一小部分用户阅读类型是极其广泛的,大部分人都处在20个新闻类型以下。可以给这类人推荐兴趣类型内的新闻。
用户查看文章的长度的分布

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

可以发现有一小部分人看的文章平均词数非常高,也有一小部分人看的平均文章次数非常低。
大多数人偏好于阅读字数在200-400字之间的新闻。
用户点击新闻的时间分析

from sklearn.preprocessing import MinMaxScaler
mm = MinMaxScaler()
user_click_merge['click_timestamp'] = mm.fit_transform(user_click_merge[['click_timestamp']])
user_click_merge['created_at_ts'] = mm.fit_transform(user_click_merge[['created_at_ts']])

user_click_merge = user_click_merge.sort_values('click_timestamp')
123456

可以发现不同用户点击文章的时间差是有差异的。看出有些用户前后看的商品的相似度波动比较大,有些波动比较小,也是有一定的区分度的。

最终总结

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

1.训练集和测试集的用户id没有重复,也就是测试集里面的用户模型是没有见过的。
2.训练集中用户最少的点击文章数是2, 而测试集里面用户最少的点击文章数是1。测试集和训练集还是存在一些差异性的。
3.用户对于文章存在重复点击的情况, 但这个都存在于训练集里面。
4.同一用户的点击环境存在不唯一的情况,后面做这部分特征的时候可以采用统计特征,大部分用户的设备是唯一的。
4.用户点击文章的次数有很大的区分度,后面可以根据这个制作衡量用户活跃度的特征。
5.文章被用户点击的次数也有很大的区分度,后面可以根据这个制作衡量文章热度的特征。
6.用户看的新闻,相关性是比较强的,所以往往我们判断用户是否对某篇文章感兴趣的时候, 在很大程度上会和他历史点击过的文章有关。既是itemCF可能会有很大作为。
7.用户点击的文章字数有比较大的区别, 这个可以反映用户对于文章字数的区别,长文并不受用户喜欢,所以推荐长文要小心。
8.用户点击过的文章主题也有很大的区别, 这个可以反映用户的主题偏好,多推荐用户偏好内的文章。
9.不同用户点击文章的时间差也会有所区别, 这个可以反映用户对于文章时效性的偏好。
所以根据上面的一些分析,可以更好的帮助我们后面做好特征工程, 充分挖掘数据的隐含信息。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值