EDA

新闻推荐:task-02 数据分析

  • 数据分为训练集用户日志和测试机用户日志,新闻信息,文章词向量。
  • 数据分析的价值:熟悉整个数据集的基本情况,即每个文件中有哪些数据,具体的文件中每个字段所表示的实际含义,数据集特征之间的相关性。
  • 针对于新闻推荐来说,主要需要分析的有用户自身的一个状态,用户与文章的关系,文章与文章之间的相关性,文章本身的基本属性,分析这些属性有助于后面召回策略的选择及特征工程的具体方向。

导入函数库

%matplotlib inline
import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns

plt.rc('font', family = 'SimHei', size = 13) #设置画板显示格式

import os, re, os, sys, warnings
warnings.filterwarnings('ignore')   #隐藏程序运行警告

读取数据集

path = r'D:/新闻推荐/'

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'})
item_emb_df = pd.read_csv(path + 'articles_emb.csv')

tst_click = pd.read_csv(path + 'testA_click_log.csv')

检视已导入数据,寻找特征之间显然的联系

trn_click.head(3)
user_idclick_article_idclick_timestampclick_environmentclick_deviceGroupclick_osclick_countryclick_regionclick_referrer_type
0199999160417150702957019041171131
11999995408150702957147841171131
219999950823150702960147841171131
item_df.head(3)
click_article_idcategory_idcreated_at_tswords_count
0001513144419000168
1111405341936000189
2211408667706000250
item_emb_df.head(3)
article_idemb_0emb_1emb_2emb_3emb_4emb_5emb_6emb_7emb_8...emb_240emb_241emb_242emb_243emb_244emb_245emb_246emb_247emb_248emb_249
00-0.161183-0.957233-0.1379440.0508550.8300550.901365-0.335148-0.559561-0.500603...0.3212480.3139990.6364120.1691790.540524-0.8131820.286870-0.2316860.5974160.409623
11-0.523216-0.9740580.7386080.1552340.6262940.485297-0.715657-0.897996-0.359747...-0.4878430.8231240.412688-0.3386540.3207860.588643-0.5941370.1828280.397090-0.834364
22-0.619619-0.972960-0.207360-0.1288610.044748-0.387535-0.730477-0.066126-0.754899...0.4547560.4731840.377866-0.863887-0.3833650.137721-0.810877-0.4475800.805932-0.285284

3 rows × 251 columns

将用户日志中时间戳特征转化为更易于理解分析的排序特征

注意点:

  • 使用groupby函数以user_id作为主键建立透视表。
  • 对透视表中click_timestamp特征使用rank()函数,使用时注意因为时间戳值越大表示发生时间越晚,因此使用排序时需要使用降序排名以保证rank()特征不发生歧义。
  • 使用rank()函数后需要注意将其数据类型强制转换成整型,避免因排名出现浮点数导致歧义
  • transform()函数使用时传入参数为待使用的函数。
  • merge()函数参数‘data’为被合并表,参数‘on’为两表拼接方式,参数‘how’为两表拼接时所依靠的主要键。
  • describe()函数为显示数据本身所包含的基本信息。
  • info()函数为显示DataFrame数据存储的本身属性信息。
  • nunique()函数为获取数据所具有的不同种类的总共个数。
  • unique()函数为获取数据所具有的全部总类。
  • count()函数为获取数据中非空元素的总共个数。
  • value_counts()函数为获取数据所有种类及对应种类对应统计个数。
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)
trn_click['click_cnts'] = trn_click.groupby(['user_id'])['click_timestamp'].transform('count')
trn_click.head(2)
user_idclick_article_idclick_timestampclick_environmentclick_deviceGroupclick_osclick_countryclick_regionclick_referrer_typerankclick_cnts
01999991604171507029570190411711311111
119999954081507029571478411711311011
trn_click = trn_click.merge(item_df, how = 'left', on = ['click_article_id'])
trn_click.head(2)
user_idclick_article_idclick_timestampclick_environmentclick_deviceGroupclick_osclick_countryclick_regionclick_referrer_typerankclick_cntscategory_idcreated_at_tswords_count
019999916041715070295701904117113111112811506942089000173
11999995408150702957147841171131101141506994257000118
trn_click.sort_values(by = 'user_id')
user_idclick_article_idclick_timestampclick_environmentclick_deviceGroupclick_osclick_countryclick_regionclick_referrer_typerankclick_cntscategory_idcreated_at_tswords_count
11126200157507150821170252041171252122811508236945000370
111261903076015082116725204117125222261508185091000162
1112602163746150821134688941171256121331508142585000162
11126011289197150821131688941171256224181508179909000176
11126002168401150821146869543201252122971507663321000215
.............................................
10818951999992183551508176867088411711311113521508155745000202
6607311999991611911507665351186411711316112811507646579000285
66073219999942223150766538118641171131511671507648195000186
2110411999991239091507226987864411711318112501507198955000240
019999916041715070295701904117113111112811506942089000173

1112623 rows × 14 columns

trn_click.describe()
user_idclick_article_idclick_timestampclick_environmentclick_deviceGroupclick_osclick_countryclick_regionclick_referrer_typerankclick_cntscategory_idcreated_at_tswords_count
count1.112623e+061.112623e+061.112623e+061.112623e+061.112623e+061.112623e+061.112623e+061.112623e+061.112623e+061.112623e+061.112623e+061.112623e+061.112623e+061.112623e+06
mean1.221198e+051.951541e+051.507588e+123.947786e+001.815981e+001.301976e+011.310776e+001.813587e+011.910063e+007.118518e+001.323704e+013.056176e+021.506598e+122.011981e+02
std5.540349e+049.292286e+043.363466e+083.276715e-011.035170e+006.967844e+001.618264e+007.105832e+001.220012e+001.016095e+011.631503e+011.155791e+028.343066e+095.223881e+01
min0.000000e+003.000000e+001.507030e+121.000000e+001.000000e+002.000000e+001.000000e+001.000000e+001.000000e+001.000000e+002.000000e+001.000000e+001.166573e+120.000000e+00
25%7.934700e+041.239090e+051.507297e+124.000000e+001.000000e+002.000000e+001.000000e+001.300000e+011.000000e+002.000000e+004.000000e+002.500000e+021.507220e+121.700000e+02
50%1.309670e+052.038900e+051.507596e+124.000000e+001.000000e+001.700000e+011.000000e+002.100000e+012.000000e+004.000000e+008.000000e+003.280000e+021.507553e+121.970000e+02
75%1.704010e+052.777120e+051.507841e+124.000000e+003.000000e+001.700000e+011.000000e+002.500000e+012.000000e+008.000000e+001.600000e+014.100000e+021.507756e+122.280000e+02
max1.999990e+053.640460e+051.510603e+124.000000e+005.000000e+002.000000e+011.100000e+012.800000e+017.000000e+002.410000e+022.410000e+024.600000e+021.510666e+126.690000e+03
trn_click.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 1112623 entries, 0 to 1112622
Data columns (total 14 columns):
 #   Column               Non-Null Count    Dtype
---  ------               --------------    -----
 0   user_id              1112623 non-null  int64
 1   click_article_id     1112623 non-null  int64
 2   click_timestamp      1112623 non-null  int64
 3   click_environment    1112623 non-null  int64
 4   click_deviceGroup    1112623 non-null  int64
 5   click_os             1112623 non-null  int64
 6   click_country        1112623 non-null  int64
 7   click_region         1112623 non-null  int64
 8   click_referrer_type  1112623 non-null  int64
 9   rank                 1112623 non-null  int32
 10  click_cnts           1112623 non-null  int64
 11  category_id          1112623 non-null  int64
 12  created_at_ts        1112623 non-null  int64
 13  words_count          1112623 non-null  int64
dtypes: int32(1), int64(13)
memory usage: 123.1 MB
trn_click['user_id'].nunique()
200000
trn_click.groupby(['user_id'])['click_article_id'].count().min()
2

plt.subplot()函数为画板格局分布函数

plt.figure(figsize = (15,20))
base_cols = [ 'click_article_id', 'click_timestamp', 'click_environment',
       'click_deviceGroup', 'click_os', 'click_country', 'click_region',
       'click_referrer_type', 'rank', 'click_cnts']
i = 1
for col in base_cols:
    plot_envs = plt.subplot(5,2,i)
    i = i + 1
    v = trn_click[col].value_counts().reset_index()[:10]
    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()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R9IAwTID-1606498367958)(output_20_0.png)]

trn_click.columns
Index(['user_id', 'click_article_id', 'click_timestamp', 'click_environment',
       'click_deviceGroup', 'click_os', 'click_country', 'click_region',
       'click_referrer_type', 'rank', 'click_cnts', 'category_id',
       'created_at_ts', 'words_count'],
      dtype='object')
tst_click = tst_click.merge(item_df, how='left', on=['click_article_id'])
tst_click.head()
user_idclick_article_idclick_timestampclick_environmentclick_deviceGroupclick_osclick_countryclick_regionclick_referrer_typerankcategory_idcreated_at_tswords_count
0249999160974150695914282041171132192811506912747000259
1249999160417150695917282041171132182811506942089000173
224999816097415069590560664112113252811506912747000259
324999820255715069590860664112113243271506938401000219
424999718366515069590886134117115573011500895686000256
tst_click.describe()
user_idclick_article_idclick_timestampclick_environmentclick_deviceGroupclick_osclick_countryclick_regionclick_referrer_typerankcategory_idcreated_at_tswords_count
count518010.000000518010.0000005.180100e+05518010.000000518010.000000518010.000000518010.000000518010.000000518010.000000518010.000000518010.0000005.180100e+05518010.000000
mean227342.428169193803.7925501.507387e+123.9473001.73828513.6284671.34820918.2502501.81961415.521785305.3249611.506883e+12210.966331
std14613.90718888279.3881773.706127e+080.3239161.0208586.6255641.7035247.0607981.08265733.957702110.4115135.816668e+0983.040065
min200000.000000137.0000001.506959e+121.0000001.0000002.0000001.0000001.0000001.0000001.0000001.0000001.265812e+120.000000
25%214926.000000128551.0000001.507026e+124.0000001.00000012.0000001.00000013.0000001.0000004.000000252.0000001.506970e+12176.000000
50%229109.000000199197.0000001.507308e+124.0000001.00000017.0000001.00000021.0000002.0000008.000000323.0000001.507249e+12199.000000
75%240182.000000272143.0000001.507666e+124.0000003.00000017.0000001.00000025.0000002.00000018.000000399.0000001.507630e+12232.000000
max249999.000000364043.0000001.508832e+124.0000005.00000020.00000011.00000028.0000007.000000938.000000460.0000001.509949e+123082.000000
tst_click['user_id'].nunique()
50000
tst_click.groupby(['user_id'])['click_article_id'].count().min()
1
item_df.head().append(item_df.tail())
click_article_idcategory_idcreated_at_tswords_count
0001513144419000168
1111405341936000189
2211408667706000250
3311408468313000230
4411407071171000162
3640423640424601434034118000144
3640433640434601434148472000463
3640443640444601457974279000177
3640453640454601515964737000126
3640463640464601505811330000479
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
print(item_df['category_id'].nunique())
item_df['category_id'].hist()
461





<matplotlib.axes._subplots.AxesSubplot at 0x17f256f2a90>

在这里插入图片描述

item_df.head()
click_article_idcategory_idcreated_at_tswords_count
0001513144419000168
1111405341936000189
2211408667706000250
3311408468313000230
4411407071171000162
item_df.shape
(364047, 4)
item_emb_df.head()
article_idemb_0emb_1emb_2emb_3emb_4emb_5emb_6emb_7emb_8...emb_240emb_241emb_242emb_243emb_244emb_245emb_246emb_247emb_248emb_249
00-0.161183-0.957233-0.1379440.0508550.8300550.901365-0.335148-0.559561-0.500603...0.3212480.3139990.6364120.1691790.540524-0.8131820.286870-0.2316860.5974160.409623
11-0.523216-0.9740580.7386080.1552340.6262940.485297-0.715657-0.897996-0.359747...-0.4878430.8231240.412688-0.3386540.3207860.588643-0.5941370.1828280.397090-0.834364
22-0.619619-0.972960-0.207360-0.1288610.044748-0.387535-0.730477-0.066126-0.754899...0.4547560.4731840.377866-0.863887-0.3833650.137721-0.810877-0.4475800.805932-0.285284
33-0.740843-0.9757490.3916980.641738-0.2686450.191745-0.825593-0.710591-0.040099...0.2715350.0360400.480029-0.7631730.0226270.565165-0.910286-0.5378380.243541-0.885329
44-0.279052-0.9723150.6853740.1130560.2383150.271913-0.5688160.341194-0.600554...0.2382860.8092680.427521-0.615932-0.5036970.614450-0.917760-0.4240610.185484-0.580292

5 rows × 251 columns

item_emb_df.shape
(364047, 251)
user_click_merge = trn_click.append(tst_click)
user_click_count = user_click_merge.groupby(['user_id', 'click_article_id'])['click_timestamp'].agg({'count'}).reset_index()
user_click_count[:10]
user_idclick_article_idcount
00307601
101575071
21637461
312891971
42361621
521684011
63361621
73506441
84398941
94425671
user_click_count[user_click_count['count'] > 7]
user_idclick_article_idcount
311242862957425410
311243862957626810
39376110323720594810
39376310323723568910
5769021348506946313
user_click_count['count'].unique()
array([ 1,  2,  4,  3,  6,  5, 10,  7, 13], dtype=int64)
user_click_count.loc[:, 'count'].value_counts()
1     1605541
2       11621
3         422
4          77
5          26
6          12
10          4
7           3
13          1
Name: count, dtype: int64
def plot_envs(df, cols, r, c):
    plt.figure(figsize = (10, 5))
    i = 1
    for col in cols:
        plt.subplot(r,c,i)
        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()
        

从测试集中随机选取五个不同的用户,分别将其不同的日志绘制成图表示出来,检查单个用户的点击新闻环境变换是否稳定。

sample_user_ids = np.random.choice(tst_click['user_id'].unique(), size = 5, replace = False)
sample_users = tst_click[tst_click['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)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

sample_users.head()
user_idclick_article_idclick_timestampclick_environmentclick_deviceGroupclick_osclick_countryclick_regionclick_referrer_typerankcategory_idcreated_at_tswords_count
5183623043916265515069749990464117113242811506949610000245
5183723043916658115069756264494117113232891506963755000210
5183823043922505515069757093134117113223541506953474000245
5183923043919919815069758471674117113213231506958823000221
5249023023116097415069752196714321162102811506912747000259
tst_click.columns
Index(['user_id', 'click_article_id', 'click_timestamp', 'click_environment',
       'click_deviceGroup', 'click_os', 'click_country', 'click_region',
       'click_referrer_type', 'rank', 'category_id', 'created_at_ts',
       'words_count'],
      dtype='object')

统计每位用户点击文章的个数,并检视所有用户与点击文章个数的分布。

user_click_item_count = sorted(user_click_merge.groupby(['user_id'])['click_article_id'].count(), reverse = True)
plt.plot(user_click_item_count)
[<matplotlib.lines.Line2D at 0x17f2eabd198>]

在这里插入图片描述

plt.plot(user_click_item_count[:50])
[<matplotlib.lines.Line2D at 0x17f2c0f9048>]

在这里插入图片描述

plt.plot(user_click_item_count[25000: 50000])
[<matplotlib.lines.Line2D at 0x17f2e9a5080>]

在这里插入图片描述

统计每篇文章的阅读量,并检视数据集中所有文章的阅读量分布。

item_click_count = sorted(user_click_merge.groupby(['click_article_id'])['user_id'].count(), reverse = True)
plt.plot(item_click_count)
[<matplotlib.lines.Line2D at 0x17f2c084e10>]

在这里插入图片描述

plt.plot(item_click_count[:100])
[<matplotlib.lines.Line2D at 0x17f256c6cf8>]

在这里插入图片描述

plt.plot(item_click_count[:20])
[<matplotlib.lines.Line2D at 0x17f2ea1f588>]

在这里插入图片描述

plt.plot(item_click_count[3500:])
[<matplotlib.lines.Line2D at 0x17f2b67ae10>]

在这里插入图片描述

plt.plot(item_click_count[:1000])
[<matplotlib.lines.Line2D at 0x17f2e9d3b70>]

在这里插入图片描述

求新闻共现频率:两篇文章连续出现的次数

  1. 将数据按时间戳进行排序。
  2. 将排好序的数据通过用户ID为主键获取文章ID数组,使用shift函数获取下一文章ID,使用transform单独对需要进行操作的列进行处理,处理时需要注意每位用户最后点击的一篇的下一篇不存在,处理时若不考虑则将导致NAN值,因此需要使用fillna()函数将缺失值统一替换为某一约定。
  3. 使用当前文章ID与下一文章ID为主键,获取该两篇文章连续出现的次数, 使用的时候对groupby所建立的透视表使用agg()函数来执行count()函数获取次数,然后将获得到的连续文章对应的次数数组重新建立索引表,再对count特征对应的出现次数进行排序。
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()
count
count433597.000000
mean3.184139
std18.851753
min1.000000
25%1.000000
50%1.000000
75%2.000000
max2202.000000
x = union_item['click_article_id']
y = union_item['count']
plt.scatter(x, y)
<matplotlib.collections.PathCollection at 0x17fe9eb2ac8>

在这里插入图片描述

plt.plot(union_item['count'].values[40000:])
[<matplotlib.lines.Line2D at 0x17fe9f842e8>]

在这里插入图片描述

检视整体数据中文章多样性的一个体现

plt.plot(user_click_merge['category_id'].value_counts().values)
[<matplotlib.lines.Line2D at 0x17fea035320>]

在这里插入图片描述

plt.plot(user_click_merge['category_id'].value_counts().values[150:])
[<matplotlib.lines.Line2D at 0x17fea0dc8d0>]

在这里插入图片描述

检视全体数据中文章篇幅的分布信息

user_click_merge['words_count'].describe()
count    1.630633e+06
mean     2.043012e+02
std      6.382198e+01
min      0.000000e+00
25%      1.720000e+02
50%      1.970000e+02
75%      2.290000e+02
max      6.690000e+03
Name: words_count, dtype: float64
plt.plot(user_click_merge['words_count'].values)
[<matplotlib.lines.Line2D at 0x17fea18e710>]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dyrKcCpC-1606498368000)(output_61_1.png)]

查看每位用户所点击文章的种类信息,即检视用户群体中每位用户的兴趣分散度。

plt.plot(sorted(user_click_merge.groupby('user_id')['category_id'].nunique(), reverse = True))
[<matplotlib.lines.Line2D at 0x17fea23ecc0>]

在这里插入图片描述

user_click_merge.groupby('user_id')['category_id'].nunique().reset_index().describe()
user_idcategory_id
count250000.000000250000.000000
mean124999.5000004.573188
std72168.9279864.419800
min0.0000001.000000
25%62499.7500002.000000
50%124999.5000003.000000
75%187499.2500006.000000
max249999.00000095.000000

检视用户喜欢的文章篇幅的大小分布。

plt.plot(sorted(user_click_merge.groupby('user_id')['words_count'].mean(), reverse = True))
[<matplotlib.lines.Line2D at 0x17f23595c18>]

在这里插入图片描述

plt.plot(sorted(user_click_merge.groupby('user_id')['words_count'].mean(), reverse = True)[1000:45000])
[<matplotlib.lines.Line2D at 0x17f25910c18>]

在这里插入图片描述

user_click_merge.groupby('user_id')['words_count'].mean().reset_index().describe()
user_idwords_count
count250000.000000250000.000000
mean124999.500000205.830189
std72168.92798647.174030
min0.0000008.000000
25%62499.750000187.500000
50%124999.500000202.000000
75%187499.250000217.750000
max249999.0000003434.500000

适当的将时间戳类型的数据转化为较易处理的数据格式以减少运算量。

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'])
user_click_merge.head(5)
user_idclick_article_idclick_timestampclick_environmentclick_deviceGroupclick_osclick_countryclick_regionclick_referrer_typerankclick_cntscategory_idcreated_at_tswords_count
182499901623000.000000432012525NaN2810.989186193
22499981609740.000002411211325NaN2810.989092259
302499851609740.00000341171828NaN2810.989092259
502499791623000.000004411712522NaN2810.989186193
252499881609740.0000044117121217NaN2810.989092259
使用列名直接索引时将得到Series类型的该列数据,由于索引后的数据较原数据格式发生变化会导致后续进行处理产生不必要的麻烦;使用数据类型的列名进行索引时,得到的索引后的数据将会保持与原数据相同的数据格式,较为安全。
user_click_merge[['click_timestamp']].head(5)
click_timestamp
180.000000
20.000002
300.000003
500.000004
250.000004

定义求解两时间戳之间的间隔即用户在每篇文章上所花费的阅读时间的抽象体现,因为该处理表现为当前文章的时间戳与下一文章的时间戳的间隔,故存在最后一篇文章的下一篇文章不存在导致出现NAN值,可通过使用fillna()函数防止NAN值得产生;同时考虑到间隔,故正间隔与负间隔所体现意义相同,因此需要使用np.abs()函数保证间隔的统一。

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()
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))
[<matplotlib.lines.Line2D at 0x17f1e8d7ba8>]

在这里插入图片描述

mean_diff_creat_time = user_click_merge.groupby('user_id')['click_timestamp', 'created_at_ts'].apply(lambda x : mean_diff_time_func(x, 'created_at_ts'))
plt.plot(sorted(mean_diff_creat_time.values, reverse = True))
[<matplotlib.lines.Line2D at 0x17f258475c0>]

在这里插入图片描述

将文章词向量中文章ID与索引通过zip()函数构成列表后再使用dict()函数构建索引与文章ID的字典,之后将文章ID列删除以便后续对词向量的快捷使用。

item_idx_2_rawid_dict = dict(zip(item_emb_df['article_id'], item_emb_df.index))
del item_emb_df['article_id']

使用np.ascontiguousarray()函数将文章词向量数据转化为连续内存存储,并将数据格式转换为32位numpy浮点数

item_emb_np = np.ascontiguousarray(item_emb_df.values, dtype = np.float32)

在用户点击数据中随机抽取十五个不同的用户所包含的数据。

sub_user_ids = np.random.choice(user_click_merge['user_id'].unique(), size = 15, replace = False)
sub_user_info = user_click_merge[user_click_merge['user_id'].isin(sub_user_ids)]
sub_user_info.head()
user_idclick_article_idclick_timestampclick_environmentclick_deviceGroupclick_osclick_countryclick_regionclick_referrer_typerankclick_cntscategory_idcreated_at_tswords_count
243952403153004700.0020524117125511NaN4280.989182203
243962403151609740.0020604117125510NaN2810.989092259
1379292403152721430.019313411712559NaN3990.989235184
1379302403151986590.019322411712558NaN3230.989235191
1540692403151565600.025085411712517NaN2810.989222185

计算每位用户点击文章的词向量之间的相似度,具体步骤是循环所有已点击文章,通过用户点击日志中的文章ID在文章ID与词向量数据集索引所组成的字典中,使用词向量对应的索引获取该文章的词向量,使用相同方法获取下一文章的词向量,相似度计算时使用函数为 S i m i l a r i t y = ∣ A ∣ ⋅ ∣ B ∣ ∥ A ∥ 2 2 ⋅ ∥ B ∥ 2 2 Similarity =\frac{\begin{vmatrix} A \end{vmatrix} \cdot \begin{vmatrix} B \end{vmatrix}}{ \begin{Vmatrix} A \end{Vmatrix}_2^2 \cdot \begin{Vmatrix} B\end{Vmatrix}_2^2 } Similarity=A22B22AB

def get_item_sim_list(df):
    sim_list = []
    item_list = df['click_article_id'].values
    for i in range(0, len(item_list)-1):
        emb1 = item_emb_np[item_idx_2_rawid_dict[item_list[i]]]
        emb2 = item_emb_np[item_idx_2_rawid_dict[item_list[i + 1]]]
        sim_list.append(np.dot(emb1, emb2) / (np.linalg.norm(emb1) * (np.linalg.norm(emb2))))
    sim_list.append(0)
    return sim_list
for _, user_df in sub_user_info.groupby('user_id'):
    item_sim_list = get_item_sim_list(user_df)
    plt.plot(item_sim_list)

在这里插入图片描述

总结

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值