文章目录

  • 1 目标
  • 2 数据集
  • 3 数据挖掘流程
  • 4 数据清洗
  • 4.1 数据集验证
  • 4.2 检查是否有重复记录
  • 4.3 检查是否存在注册时间在2016年-4月-15号之后的用户
  • 4.4 行为数据中的user_id为浮点型,进行INT类型转换
  • 4.5 年龄区间的处理
  • 5 构建 user_table
  • 6 构建 item_table
  • 7 数据清洗
  • 8 数据探索
  • 8.1 周一到周日每天的购买情况
  • 8.2 一个月中每天购买量
  • 8.3 商品类别销售统计

1 目标

使用京东多个品类下商品的历史销售数据,构建算法模型,预测用户在未来5天内,对某个目标品类下商品的购买意向。

2 数据集

这里涉及到的数据集是Kaggle上京东数据集:

  • JData_User.csv 用户数据集 105,321个用户
  • JData_Comment.csv 商品评论 558,552条记录
  • JData_Product.csv 预测商品集合 24,187条记录
  • JData_Action_201602.csv 2月份行为交互记录 11,485,424条记录
  • JData_Action_201603.csv 3月份行为交互记录 25,916,378条记录
  • JData_Action_201604.csv 4月份行为交互记录 13,199,934条记录



3 数据挖掘流程

(一).数据清洗

  1. 数据集完整性验证
  2. 数据集中是否存在缺失值
  3. 数据集中各特征数值应该如何处理
  4. 哪些数据是我们想要的,哪些是可以过滤掉的
  5. 将有价值数据信息做成新的数据源
  6. 去除无行为交互的商品和用户
  7. 去掉浏览量很大而购买量很少的用户(惰性用户或爬虫用户)

(二).数据理解与分析

  1. 掌握各个特征的含义
  2. 观察数据有哪些特点,是否可利用来建模
  3. 可视化展示便于分析
  4. 用户的购买意向是否随着时间等因素变化

(三).特征提取

  1. 基于清洗后的数据集哪些特征是有价值
  2. 分别对用户与商品以及其之间构成的行为进行特征提取
  3. 行为因素中哪些是核心?如何提取?
  4. 瞬时行为特征or累计行为特征?

(四).模型建立

  1. 使用机器学习算法进行预测
  2. 参数设置与调节
  3. 数据集切分?

4 数据清洗

4.1 数据集验证

首先检查JData_User中的用户和JData_Action中的用户是否一致
保证行为数据中的所产生的行为均由用户数据中的用户产生(但是可能存在用户在行为数据中无行为)

思路:利用pd.Merge连接sku 和 Action中的sku, 观察Action中的数据是否减少

def user_action_check():df_user = pd.read_csv('data/JData_User.csv',encoding='gbk')df_sku = df_user.loc[:,'user_id'].to_frame()df_month2 = pd.read_csv('data/JData_Action_201602.csv',encoding='gbk')print ('Is action of Feb. from User file? ', len(df_month2) == len(pd.merge(df_sku,df_month2)))df_month3 = pd.read_csv('data/JData_Action_201603.csv',encoding='gbk')print ('Is action of Mar. from User file? ', len(df_month3) == len(pd.merge(df_sku,df_month3)))df_month4 = pd.read_csv('data/JData_Action_201604.csv',encoding='gbk')print ('Is action of Apr. from User file? ', len(df_month4) == len(pd.merge(df_sku,df_month4)))user_action_check()

Is action of Feb. from User file? True
Is action of Mar. from User file? True
Is action of Apr. from User file? True

结论:

User数据集中的用户和交互行为数据集中的用户完全一致

根据merge前后的数据量比对,能保证Action中的用户ID是User中的ID的子集

4.2 检查是否有重复记录

除去各个数据文件中完全重复的记录,可能解释是重复数据是有意义的,比如用户同时购买多件商品,同时添加多个数量的商品到购物车等…

def deduplicate(filepath, filename, newpath):df_file = pd.read_csv(filepath,encoding='gbk')       before = df_file.shape[0]df_file.drop_duplicates(inplace=True)after = df_file.shape[0]n_dup = before-afterprint ('No. of duplicate records for ' + filename + ' is: ' + str(n_dup))if n_dup != 0:df_file.to_csv(newpath, index=None)else:print ('no duplicate records in ' + filename)
# deduplicate('data/JData_Action_201602.csv', 'Feb. action', 'data/JData_Action_201602_dedup.csv')
deduplicate('data/JData_Action_201603.csv', 'Mar. action', 'data/JData_Action_201603_dedup.csv')
deduplicate('data/JData_Action_201604.csv', 'Feb. action', 'data/JData_Action_201604_dedup.csv')
deduplicate('data/JData_Comment.csv', 'Comment', 'data/JData_Comment_dedup.csv')
deduplicate('data/JData_Product.csv', 'Product', 'data/JData_Product_dedup.csv')
deduplicate('data/JData_User.csv', 'User', 'data/JData_User_dedup.csv')

No. of duplicate records for Mar. action is: 7085038
No. of duplicate records for Feb. action is: 3672710
No. of duplicate records for Comment is: 0
no duplicate records in Comment
No. of duplicate records for Product is: 0
no duplicate records in Product
No. of duplicate records for User is: 0
no duplicate records in User

df_month2 = pd.read_csv('data/JData_Action_201602.csv',encoding='gbk')
IsDuplicated = df_month2.duplicated()  ##duplicated()得到重复值判断的布尔值,再选择布尔值为True的既为重复值
df_d=df_month2[IsDuplicated == True]
df_d.groupby('type').count()               #发现重复数据大多数都是由于浏览(1),或者点击(6)产生

4.3 检查是否存在注册时间在2016年-4月-15号之后的用户

import pandas as pd
df_user = pd.read_csv('data\JData_User.csv',encoding='gbk')
df_user['user_reg_tm']=pd.to_datetime(df_user['user_reg_tm'])
df_user.loc[df_user.user_reg_tm  >= '2016-4-15']


由于注册时间是京东系统错误造成,如果行为数据中没有在4月15号之后的数据的话,那么说明这些用户还是正常用户,并不需要删除。

df_month = pd.read_csv('data\JData_Action_201604.csv')
df_month['time'] = pd.to_datetime(df_month['time'])
df_month.loc[df_month.time >= '2016-4-16']


结论:说明用户没有异常操作数据,所以这一批用户不删除。

4.4 行为数据中的user_id为浮点型,进行INT类型转换

import pandas as pd
df_month = pd.read_csv('data/JData_Action_201602.csv',encoding='gbk')
df_month['user_id'] = df_month['user_id'].apply(lambda x:int(x))  #这个命名函数默认按照每行样本每行样本去操作,用for循环太Low
print (df_month['user_id'].dtype)
df_month.to_csv('data/JData_Action_201602.csv',index=None)
df_month = pd.read_csv('data/JData_Action_201603.csv',encoding='gbk')
df_month['user_id'] = df_month['user_id'].apply(lambda x:int(x))
print (df_month['user_id'].dtype)
df_month.to_csv('data/JData_Action_201603.csv',index=None)
df_month = pd.read_csv('data/JData_Action_201604.csv',encoding='gbk')
df_month['user_id'] = df_month['user_id'].apply(lambda x:int(x))
print (df_month['user_id'].dtype)
df_month.to_csv('data/JData_Action_201604.csv',index=None)

int64
int64
int64

4.5 年龄区间的处理

# 同样是构造一个命名函数
import pandas as pd
df_user = pd.read_csv('data/JData_User.csv',encoding='gbk')def tranAge(x):if x == u'15岁以下':x='1'elif x==u'16-25岁':x='2'elif x==u'26-35岁':x='3'elif x==u'36-45岁':x='4'elif x==u'46-55岁':x='5'elif x==u'56岁以上':x='6'return x
df_user['age']=df_user['age'].apply(tranAge)
print (df_user.groupby(df_user['age']).count())
df_user.to_csv('data/JData_User.csv',index=None)


为了能够进行上述清洗,在此首先构造了简单的用户(user)行为特征和商品(item)行为特征,对应于两张表user_table和item_table。
user_table特征包括:

  • user_id(用户id),age(年龄),sex(性别),
  • user_lv_cd(用户级别),browse_num(浏览数),
  • addcart_num(加购数),delcart_num(删购数),
  • buy_num(购买数),favor_num(收藏数),
  • click_num(点击数),buy_addcart_ratio(购买加购转化率),
  • buy_browse_ratio(购买浏览转化率),
  • buy_click_ratio(购买点击转化率),
  • buy_favor_ratio(购买收藏转化率)
    item_table特征包括:
  • sku_id(商品id),attr1,attr2,attr3,cate,brand,
  • browse_num,
  • addcart_num,delcart_num,
  • buy_num,favor_num,click_num,
  • buy_addcart_ratio,buy_browse_ratio,
  • buy_click_ratio,buy_favor_ratio,
  • comment_num(评论数),
  • has_bad_comment(是否有差评),
  • bad_comment_rate(差评率)

5 构建 user_table

#定义文件名
ACTION_201602_FILE = "data/JData_Action_201602.csv"
ACTION_201603_FILE = "data/JData_Action_201603.csv"
ACTION_201604_FILE = "data/JData_Action_201604.csv"
COMMENT_FILE = "data/JData_Comment.csv"
PRODUCT_FILE = "data/JData_Product.csv"
USER_FILE = "data/JData_User.csv"
USER_TABLE_FILE = "data/User_table.csv"
ITEM_TABLE_FILE = "data/Item_table.csv"
# 导入相关包
import pandas as pd
import numpy as np
from collections import Counter
# 功能函数: 对每一个user分组的数据进行统计
def add_type_count(group):behavior_type = group.type.astype(int)  #修改数据类型为int型# 用户行为类别type_cnt = Counter(behavior_type)  #统计数组中每个数字出现的次数# 1: 浏览 2: 加购 3: 删除# 4: 购买 5: 收藏 6: 点击group['browse_num'] = type_cnt[1]group['addcart_num'] = type_cnt[2]group['delcart_num'] = type_cnt[3]group['buy_num'] = type_cnt[4]group['favor_num'] = type_cnt[5]group['click_num'] = type_cnt[6]return group[['user_id', 'browse_num', 'addcart_num','delcart_num', 'buy_num', 'favor_num','click_num']]

由于用户行为数据量较大,一次性读入可能造成内存错误(Memory Error),因而使用pandas的分块(chunk)读取.

#对action数据进行统计
#根据自己调节chunk_size大小
def get_from_action_data(fname, chunk_size=50000):reader = pd.read_csv(fname, header=0, iterator=True,encoding='gbk')chunks = []loop = Truewhile loop:try:# 只读取user_id和type两个字段chunk = reader.get_chunk(chunk_size)[["user_id", "type"]]chunks.append(chunk)except StopIteration:loop = Falseprint("Iteration is stopped")# 将块拼接为pandas dataframe格式df_ac = pd.concat(chunks, ignore_index=True)# 按user_id分组,对每一组进行统计,as_index 表示无索引形式返回数据df_ac = df_ac.groupby(['user_id'], as_index=False).apply(add_type_count)# 将重复的行丢弃df_ac = df_ac.drop_duplicates('user_id')return df_ac
# 将各个action数据的统计量进行聚合
def merge_action_data():df_ac = []df_ac.append(get_from_action_data(fname=ACTION_201602_FILE))df_ac.append(get_from_action_data(fname=ACTION_201603_FILE))df_ac.append(get_from_action_data(fname=ACTION_201604_FILE))df_ac = pd.concat(df_ac, ignore_index=True)# 用户在不同action表中统计量求和。将连接起来的三个表以'user_id'进行分组,再将各统计量相加求和df_ac = df_ac.groupby(['user_id'], as_index=False).sum()# 构造转化率字段    df_ac['buy_addcart_ratio'] = df_ac['buy_num'] / df_ac['addcart_num']df_ac['buy_browse_ratio'] = df_ac['buy_num'] / df_ac['browse_num']df_ac['buy_click_ratio'] = df_ac['buy_num'] / df_ac['click_num']df_ac['buy_favor_ratio'] = df_ac['buy_num'] / df_ac['favor_num']# 将大于1的转化率字段置为1(100%)df_ac.loc[df_ac['buy_addcart_ratio'] > 1., 'buy_addcart_ratio'] = 1.df_ac.loc[df_ac['buy_browse_ratio'] > 1., 'buy_browse_ratio'] = 1.df_ac.loc[df_ac['buy_click_ratio'] > 1., 'buy_click_ratio'] = 1.df_ac.loc[df_ac['buy_favor_ratio'] > 1., 'buy_favor_ratio'] = 1.return df_ac
# 从FJData_User表中抽取需要的字段
def get_from_jdata_user():df_usr = pd.read_csv(USER_FILE, header=0)df_usr = df_usr[["user_id", "age", "sex", "user_lv_cd"]]return df_usr
user_base = get_from_jdata_user()
user_behavior = merge_action_data()
# 连接成一张表,类似于SQL的左连接(left join)
user_behavior = pd.merge(user_base, user_behavior, on=['user_id'], how='left')
# 保存为user_table.csv
user_behavior.to_csv(USER_TABLE_FILE, index=False)
user_table = pd.read_csv(USER_TABLE_FILE)
user_table.head()

6 构建 item_table

#定义文件名
ACTION_201602_FILE = "data/JData_Action_201602.csv"
ACTION_201603_FILE = "data/JData_Action_201603.csv"
ACTION_201604_FILE = "data/JData_Action_201604.csv"
COMMENT_FILE = "data/JData_Comment.csv"
PRODUCT_FILE = "data/JData_Product.csv"
USER_FILE = "data/JData_User.csv"
USER_TABLE_FILE = "data/User_table.csv"
ITEM_TABLE_FILE = "data/Item_table.csv"
# 读取Product中商品
def get_from_jdata_product():df_item = pd.read_csv(PRODUCT_FILE, header=0,encoding='gbk')return df_item
# 对每一个商品分组进行统计
def add_type_count(group):behavior_type = group.type.astype(int)type_cnt = Counter(behavior_type)group['browse_num'] = type_cnt[1]group['addcart_num'] = type_cnt[2]group['delcart_num'] = type_cnt[3]group['buy_num'] = type_cnt[4]group['favor_num'] = type_cnt[5]group['click_num'] = type_cnt[6]return group[['sku_id', 'browse_num', 'addcart_num','delcart_num', 'buy_num', 'favor_num','click_num']]
#对action中的数据进行统计
def get_from_action_data(fname, chunk_size=50000):reader = pd.read_csv(fname, header=0, iterator=True)chunks = []loop = Truewhile loop:try:chunk = reader.get_chunk(chunk_size)[["sku_id", "type"]]chunks.append(chunk)except StopIteration:loop = Falseprint("Iteration is stopped")df_ac = pd.concat(chunks, ignore_index=True)df_ac = df_ac.groupby(['sku_id'], as_index=False).apply(add_type_count)# Select unique rowdf_ac = df_ac.drop_duplicates('sku_id')return df_ac
# 获取评论中的商品数据,如果存在某一个商品有两个日期的评论,我们取最晚的那一个
def get_from_jdata_comment():df_cmt = pd.read_csv(COMMENT_FILE, header=0)df_cmt['dt'] = pd.to_datetime(df_cmt['dt'])# find latest comment index#transform区别于apply,里边只能跟内置方法,apply可以自定义方法idx = df_cmt.groupby(['sku_id'])['dt'].transform(max) == df_cmt['dt']df_cmt = df_cmt[idx]return df_cmt[['sku_id', 'comment_num','has_bad_comment', 'bad_comment_rate']]
def merge_action_data():df_ac = []df_ac.append(get_from_action_data(fname=ACTION_201602_FILE))df_ac.append(get_from_action_data(fname=ACTION_201603_FILE))df_ac.append(get_from_action_data(fname=ACTION_201604_FILE))df_ac = pd.concat(df_ac, ignore_index=True)df_ac = df_ac.groupby(['sku_id'], as_index=False).sum()df_ac['buy_addcart_ratio'] = df_ac['buy_num'] / df_ac['addcart_num']df_ac['buy_browse_ratio'] = df_ac['buy_num'] / df_ac['browse_num']df_ac['buy_click_ratio'] = df_ac['buy_num'] / df_ac['click_num']df_ac['buy_favor_ratio'] = df_ac['buy_num'] / df_ac['favor_num']df_ac.loc[df_ac['buy_addcart_ratio'] > 1., 'buy_addcart_ratio'] = 1.df_ac.loc[df_ac['buy_browse_ratio'] > 1., 'buy_browse_ratio'] = 1.df_ac.loc[df_ac['buy_click_ratio'] > 1., 'buy_click_ratio'] = 1.df_ac.loc[df_ac['buy_favor_ratio'] > 1., 'buy_favor_ratio'] = 1.return df_ac
item_base = get_from_jdata_product()
item_behavior = merge_action_data()
item_comment = get_from_jdata_comment()# SQL: left join
item_behavior = pd.merge(item_base, item_behavior, on=['sku_id'], how='left')
item_behavior = pd.merge(item_behavior, item_comment, on=['sku_id'], how='left')item_behavior.to_csv(ITEM_TABLE_FILE, index=False)
item_table = pd.read_csv(ITEM_TABLE_FILE)
item_table.head()

7 数据清洗

import pandas as pd
df_user = pd.read_csv('data/User_table.csv',header=0)
pd.options.display.float_format = '{:,.3f}'.format  #输出格式设置,保留三位小数
df_user.describe()


由上述统计信息发现: 第一行中根据User_id统计发现有105321个用户,发现有3个用户没有age,sex字段,而且根据浏览、加购、删购、购买等记录却只有105180条记录,说明存在用户无任何交互记录,因此可以删除上述用户。

删除没有age,sex字段的用户

df_user[df_user['age'].isnull()]

delete_list = df_user[df_user['age'].isnull()].index
df_user.drop(delete_list,axis=0,inplace=True)   #axis=0按行删除

删除无交互记录的用户

#删除无交互记录的用户
df_naction = df_user[(df_user['browse_num'].isnull()) & (df_user['addcart_num'].isnull()) & (df_user['delcart_num'].isnull()) & (df_user['buy_num'].isnull()) & (df_user['favor_num'].isnull()) & (df_user['click_num'].isnull())]
df_user.drop(df_naction.index,axis=0,inplace=True)

统计并删除无购买记录的用户

#统计无购买记录的用户
df_bzero = df_user[df_user['buy_num']==0]
df_user = df_user[df_user['buy_num']!=0]
df_user.describe()


删除爬虫及惰性用户
由上表所知,浏览购买转换比和点击购买转换比均值为0.018,0.030,因此这里认为浏览购买转换比和点击购买转换比小于0.0005的用户为惰性用户

bindex = df_user[df_user['buy_browse_ratio']<0.0005].index
print (len(bindex))
df_user.drop(bindex,axis=0,inplace=True)
cindex = df_user[df_user['buy_click_ratio']<0.0005].index
print (len(cindex))
df_user.drop(cindex,axis=0,inplace=True)

8 数据探索

# 导入相关包
%matplotlib inline
# 绘图包
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
#定义文件名
ACTION_201602_FILE = "data/JData_Action_201602.csv"
ACTION_201603_FILE = "data/JData_Action_201603.csv"
ACTION_201604_FILE = "data/JData_Action_201604.csv"
COMMENT_FILE = "data/JData_Comment.csv"
PRODUCT_FILE = "data/JData_Product.csv"
USER_FILE = "data/JData_User.csv"
USER_TABLE_FILE = "data/User_table.csv"
ITEM_TABLE_FILE = "data/Item_table.csv"

8.1 周一到周日每天的购买情况

# 提取购买(type=4)的行为数据
def get_from_action_data(fname, chunk_size=50000):reader = pd.read_csv(fname, header=0, iterator=True)chunks = []loop = Truewhile loop:try:chunk = reader.get_chunk(chunk_size)[["user_id", "sku_id", "type", "time"]]chunks.append(chunk)except StopIteration:loop = Falseprint("Iteration is stopped")df_ac = pd.concat(chunks, ignore_index=True)# type=4,为购买df_ac = df_ac[df_ac['type'] == 4]return df_ac[["user_id", "sku_id", "time"]]
df_ac = []
df_ac.append(get_from_action_data(fname=ACTION_201602_FILE))
df_ac.append(get_from_action_data(fname=ACTION_201603_FILE))
df_ac.append(get_from_action_data(fname=ACTION_201604_FILE))
df_ac = pd.concat(df_ac, ignore_index=True)
print(df_ac.dtypes)

user_id int64
sku_id int64
time object
dtype: object

# 将time字段转换为datetime类型
df_ac['time'] = pd.to_datetime(df_ac['time'])# 使用lambda匿名函数将时间time转换为星期(周一为1, 周日为7)
df_ac['time'] = df_ac['time'].apply(lambda x: x.weekday() + 1)   #apply会把一列中的每一条记录都做一个映射
df_ac.head()

# 周一到周日每天购买用户个数
df_user = df_ac.groupby('time')['user_id'].nunique()   #.nunique()返回唯一值的个数。统计以‘time’为分组'user_id'的唯一值的个数。
df_user = df_user.to_frame().reset_index()   #原索引作为一列保留,列名分别为 ‘time’ 'user_id'
df_user.columns = ['weekday', 'user_num']    #重新定义列名
# 周一到周日每天购买商品个数
df_item = df_ac.groupby('time')['sku_id'].nunique()  #统计以‘time’为分组'sku_id'的唯一值的个数。
df_item = df_item.to_frame().reset_index()
df_item.columns = ['weekday', 'item_num']
# 周一到周日每天购买记录个数
# 统计以‘time’为分组的各个time的个数。size()可以包含空值
df_ui = df_ac.groupby('time', as_index=False).size()   #as_index=False是sql风格的分组输出,默认是False。
df_ui = df_ui.to_frame().reset_index()
df_ui.columns = ['weekday', 'user_item_num']
# 条形宽度
bar_width = 0.2
# 透明度
opacity = 0.4plt.bar(df_user['weekday'], df_user['user_num'], bar_width, alpha=opacity, color='c', label='user')
plt.bar(df_item['weekday']+bar_width, df_item['item_num'], bar_width, alpha=opacity, color='g', label='item')
plt.bar(df_ui['weekday']+bar_width*2, df_ui['user_item_num'], bar_width, alpha=opacity, color='m', label='user_item')plt.xlabel('weekday')
plt.ylabel('number')
plt.title('A Week Purchase Table')
plt.xticks(df_user['weekday'] + bar_width * 3 / 2., (1,2,3,4,5,6,7))
plt.tight_layout()
plt.legend(prop={'size':10})



分析:周六,周日购买量较少

8.2 一个月中每天购买量

2016年2月

df_ac = get_from_action_data(fname=ACTION_201602_FILE)# 将time字段转换为datetime类型并使用lambda匿名函数将时间time转换为天
df_ac['time'] = pd.to_datetime(df_ac['time']).apply(lambda x: x.day)
df_ac.head()

df_user = df_ac.groupby('time')['user_id'].nunique()
df_user = df_user.to_frame().reset_index()
df_user.columns = ['day', 'user_num']df_item = df_ac.groupby('time')['sku_id'].nunique()
df_item = df_item.to_frame().reset_index()
df_item.columns = ['day', 'item_num']df_ui = df_ac.groupby('time', as_index=False).size()
df_ui = df_ui.to_frame().reset_index()
df_ui.columns = ['day', 'user_item_num']
# 条形宽度
bar_width = 0.2
# 透明度
opacity = 0.4
# 天数
day_range = range(1,len(df_user['day']) + 1, 1)
# 设置图片大小
plt.figure(figsize=(14,10))plt.bar(df_user['day'], df_user['user_num'], bar_width, alpha=opacity, color='c', label='user')
plt.bar(df_item['day']+bar_width, df_item['item_num'], bar_width, alpha=opacity, color='g', label='item')
plt.bar(df_ui['day']+bar_width*2, df_ui['user_item_num'], bar_width, alpha=opacity, color='m', label='user_item')plt.xlabel('day')
plt.ylabel('number')
plt.title('February Purchase Table')
plt.xticks(df_user['day'] + bar_width * 3 / 2., day_range)
# plt.ylim(0, 80)
plt.tight_layout()
plt.legend(prop={'size':9})


分析: 2月份5,6,7,8,9,10 这几天购买量非常少,原因可能是中国农历春节,快递不营业

2016年3月

df_ac = get_from_action_data(fname=ACTION_201603_FILE)# 将time字段转换为datetime类型并使用lambda匿名函数将时间time转换为天
df_ac['time'] = pd.to_datetime(df_ac['time']).apply(lambda x: x.day)
df_user = df_ac.groupby('time')['user_id'].nunique()
df_user = df_user.to_frame().reset_index()
df_user.columns = ['day', 'user_num']df_item = df_ac.groupby('time')['sku_id'].nunique()
df_item = df_item.to_frame().reset_index()
df_item.columns = ['day', 'item_num']df_ui = df_ac.groupby('time', as_index=False).size()
df_ui = df_ui.to_frame().reset_index()
df_ui.columns = ['day', 'user_item_num']
# 条形宽度
bar_width = 0.2
# 透明度
opacity = 0.4
# 天数
day_range = range(1,len(df_user['day']) + 1, 1)
# 设置图片大小
plt.figure(figsize=(14,10))plt.bar(df_user['day'], df_user['user_num'], bar_width, alpha=opacity, color='c', label='user')
plt.bar(df_item['day']+bar_width, df_item['item_num'], bar_width, alpha=opacity, color='g', label='item')
plt.bar(df_ui['day']+bar_width*2, df_ui['user_item_num'], bar_width, alpha=opacity, color='m', label='user_item')plt.xlabel('day')
plt.ylabel('number')
plt.title('March Purchase Table')
plt.xticks(df_user['day'] + bar_width * 3 / 2., day_range)
# plt.ylim(0, 80)
plt.tight_layout()
plt.legend(prop={'size':9})


分析:3月份14,15,16不知名节日,造成购物大井喷,总体来看,购物记录多于2月份

2016年4月

df_ac = get_from_action_data(fname=ACTION_201604_FILE)# 将time字段转换为datetime类型并使用lambda匿名函数将时间time转换为天
df_ac['time'] = pd.to_datetime(df_ac['time']).apply(lambda x: x.day)
df_user = df_ac.groupby('time')['user_id'].nunique()
df_user = df_user.to_frame().reset_index()
df_user.columns = ['day', 'user_num']df_item = df_ac.groupby('time')['sku_id'].nunique()
df_item = df_item.to_frame().reset_index()
df_item.columns = ['day', 'item_num']df_ui = df_ac.groupby('time', as_index=False).size()
df_ui = df_ui.to_frame().reset_index()
df_ui.columns = ['day', 'user_item_num']
# 条形宽度
bar_width = 0.2
# 透明度
opacity = 0.4
# 天数
day_range = range(1,len(df_user['day']) + 1, 1)
# 设置图片大小
plt.figure(figsize=(14,10))plt.bar(df_user['day'], df_user['user_num'], bar_width, alpha=opacity, color='c', label='user')
plt.bar(df_item['day']+bar_width, df_item['item_num'], bar_width, alpha=opacity, color='g', label='item')
plt.bar(df_ui['day']+bar_width*2, df_ui['user_item_num'], bar_width, alpha=opacity, color='m', label='user_item')plt.xlabel('day')
plt.ylabel('number')
plt.title('April Purchase Table')
plt.xticks(df_user['day'] + bar_width * 3 / 2., day_range)
# plt.ylim(0, 80)
plt.tight_layout()
plt.legend(prop={'size':9})


分析:一脸懵逼中…可能又有啥节日? 还是说每个月中旬都有较强的购物欲望?

8.3 商品类别销售统计

周一到周一各类别商品销售情况

# 从行为记录中提取商品类别数据
def get_from_action_data(fname, chunk_size=50000):reader = pd.read_csv(fname, header=0, iterator=True)chunks = []loop = Truewhile loop:try:chunk = reader.get_chunk(chunk_size)[["cate", "brand", "type", "time"]]chunks.append(chunk)except StopIteration:loop = Falseprint("Iteration is stopped")df_ac = pd.concat(chunks, ignore_index=True)# type=4,为购买df_ac = df_ac[df_ac['type'] == 4]return df_ac[["cate", "brand", "type", "time"]]
df_ac = []
df_ac.append(get_from_action_data(fname=ACTION_201602_FILE))
df_ac.append(get_from_action_data(fname=ACTION_201603_FILE))
df_ac.append(get_from_action_data(fname=ACTION_201604_FILE))
df_ac = pd.concat(df_ac, ignore_index=True)
# 将time字段转换为datetime类型
df_ac['time'] = pd.to_datetime(df_ac['time'])# 使用lambda匿名函数将时间time转换为星期(周一为1, 周日为7)
df_ac['time'] = df_ac['time'].apply(lambda x: x.weekday() + 1)
df_ac.head()

# 观察有几个类别商品
df_ac.groupby(df_ac['cate']).count()#count()计数区分size(),不包含空值

# 周一到周日每天购买商品类别数量统计
df_product = df_ac['brand'].groupby([df_ac['time'],df_ac['cate']]).count()
df_product=df_product.unstack()  #表格在行列方向上均有索引(类似于DataFrame),花括号结构只有“列方向”上的索引(类似于层次化的Series),结构更加偏向于堆叠(Series-stack,方便记忆)。stack函数会将数据从”表格结构“变成”花括号结构“,即将其行索引变成列索引,反之,unstack函数将数据从”花括号结构“变成”表格结构“,即要将其中一层的列索引变成行索引。
df_product.plot(kind='bar',title='Cate Purchase Table in a Week',figsize=(14,10))

分析:星期二买类别8的最多,星期天最少。

每月各类商品销售情况(只关注商品8)

2016年2,3,4月

df_ac2 = get_from_action_data(fname=ACTION_201602_FILE)# 将time字段转换为datetime类型并使用lambda匿名函数将时间time转换为天
df_ac2['time'] = pd.to_datetime(df_ac2['time']).apply(lambda x: x.day)
df_ac3 = get_from_action_data(fname=ACTION_201603_FILE)# 将time字段转换为datetime类型并使用lambda匿名函数将时间time转换为天
df_ac3['time'] = pd.to_datetime(df_ac3['time']).apply(lambda x: x.day)
df_ac4 = get_from_action_data(fname=ACTION_201604_FILE)# 将time字段转换为datetime类型并使用lambda匿名函数将时间time转换为天
df_ac4['time'] = pd.to_datetime(df_ac4['time']).apply(lambda x: x.day)
dc_cate2 = df_ac2[df_ac2['cate']==8]
dc_cate2 = dc_cate2['brand'].groupby(dc_cate2['time']).count()
dc_cate2 = dc_cate2.to_frame().reset_index()
dc_cate2.columns = ['day', 'product_num']dc_cate3 = df_ac3[df_ac3['cate']==8]
dc_cate3 = dc_cate3['brand'].groupby(dc_cate3['time']).count()
dc_cate3 = dc_cate3.to_frame().reset_index()
dc_cate3.columns = ['day', 'product_num']dc_cate4 = df_ac4[df_ac4['cate']==8]
dc_cate4 = dc_cate4['brand'].groupby(dc_cate4['time']).count()
dc_cate4 = dc_cate4.to_frame().reset_index()
dc_cate4.columns = ['day', 'product_num']
# 条形宽度
bar_width = 0.2
# 透明度
opacity = 0.4
# 天数
day_range = range(1,len(dc_cate3['day']) + 1, 1)
# 设置图片大小
plt.figure(figsize=(14,10))plt.bar(dc_cate2['day'], dc_cate2['product_num'], bar_width, alpha=opacity, color='c', label='February')
plt.bar(dc_cate3['day']+bar_width, dc_cate3['product_num'], bar_width, alpha=opacity, color='g', label='March')
plt.bar(dc_cate4['day']+bar_width*2, dc_cate4['product_num'], bar_width, alpha=opacity, color='m', label='April')plt.xlabel('day')
plt.ylabel('number')
plt.title('Cate-8 Purchase Table')
plt.xticks(dc_cate3['day'] + bar_width * 3 / 2., day_range)
# plt.ylim(0, 80)
plt.tight_layout()
plt.legend(prop={'size':9})


分析:2月份对类别8商品的购买普遍偏低,3,4月份普遍偏高,3月15日购买极其多!可以对比3月份的销售记录,发现类别8将近占了3月15日总销售的一半!同时发现,3,4月份类别8销售记录在前半个月特别相似,除了4月8号,9号和3月15号。

查看特定用户对特定商品的的轨迹

def spec_ui_action_data(fname, user_id, item_id, chunk_size=100000):reader = pd.read_csv(fname, header=0, iterator=True)chunks = []loop = Truewhile loop:try:chunk = reader.get_chunk(chunk_size)[["user_id", "sku_id", "type", "time"]]chunks.append(chunk)except StopIteration:loop = Falseprint("Iteration is stopped")df_ac = pd.concat(chunks, ignore_index=True)df_ac = df_ac[(df_ac['user_id'] == user_id) & (df_ac['sku_id'] == item_id)]return df_ac
def explore_user_item_via_time():user_id = 266079item_id = 138778df_ac = []df_ac.append(spec_ui_action_data(ACTION_201602_FILE, user_id, item_id))df_ac.append(spec_ui_action_data(ACTION_201603_FILE, user_id, item_id))df_ac.append(spec_ui_action_data(ACTION_201604_FILE, user_id, item_id))df_ac = pd.concat(df_ac, ignore_index=False)print(df_ac.sort_values(by='time'))
explore_user_item_via_time()

NO.90——京东用户购买意向预测之数据预处理相关推荐

  1. 【机器学习】京东用户购买意向预测-数据集介绍和数据清洗 - 1

    主题:京东用户购买意向预测 数据集: 这里涉及到的数据集是京东最新的数据集: JData_User.csv 用户数据集 105,321个用户 JData_Comment.csv 商品评论 558,55 ...

  2. 京东用户购买意向预测(一)

    数据清洗 故事背景: 数据集: 数据挖掘流程: 数据集验证 首先检查JData_User中的用户和JData_Action中的用户是否一致 因为数据量很大所以每次读取的时间有点长,所以很着急看结果的话 ...

  3. 京东用户购买意向预测(一)数据清洗

    故事背景: 京东作为中国最大的自营式电商,在保持高速发展的同时,沉淀了数亿的忠实用户,积累了海量的真实数据.如何从历史数据中找出规律,去预测用户未来的购买需求,让最合适的商品遇见最需要的人,是大数据应 ...

  4. JData数据处理及高潜用户购买意向预测

    竞赛概述: 本次大赛以京东商城真实的用户.商品和行为数据(脱敏后)为基础,参赛队伍需要通过数据挖掘的技术和机器学习的算法,构建用户购买商品的预测模型,输出高潜用户和目标商品的匹配结果,为精准营销提供高 ...

  5. 京东算法大赛-高潜用户购买意向预测(一) 资料整理

    初学者可以参考daoliker提供的资料:https://github.com/daoliker/JData,这是一位热心的参赛者提供的一份入门程序,涵盖了数据清洗.数据(统计)分析.特征抽取.搭建模 ...

  6. 京东JData算法大赛——高潜用户购买意向预测

    赛题分析 京东提供了用户在2016-02-01-2016-04-15时间区域内用户对商品的行为评价等数据,预测2016-04-16-2016-04-20时间区间内用户的下单情况. 赛题和阿里的第一个竞 ...

  7. 京东JData算法大赛高潜用户购买意向预测——复现(并没有),提供数据集

    19-1-15更新,后面改了做法所以随笔烂尾了,具体内容不用看,想参考的可以看下面的参考链接 另外提供数据集在百度云,希望能帮到大家 链接: https://pan.baidu.com/s/1ojjV ...

  8. 京东JData算法大赛-高潜用户购买意向预测(github源码)

    向AI转型的程序员都关注了这个号

  9. 京东JData2017算法大赛高潜用户购买意向预测数据集下载

    找了老半天,都没找到,要么链接过期,要么要收费,感觉这种东西收费不是很君子,毕竟这东西不是咱们自己产的嘛,感谢这位博主,下面是这位博主提供的下载链接 这位博主还提供了一些复现的思路,大家可以学习下 链 ...

最新文章

  1. ajax传向前台的html代码里又有事件的时候,绑定事件失败解决方法
  2. can a select block a truncate (ZT)
  3. [转载] Java线程池框架源码分析
  4. 一道有意思的导论问题
  5. comsol临时文件夹中有不支持的字符_文件名中不能包含的字符
  6. B君的圆锥(51Nod-1629)
  7. 贵大计算机在职,贵州大学在职研究生招生信息网
  8. 机器学习算法:scikit-learn 线性回归算法总结
  9. SpringMVC基础学习(二)—开发Handler
  10. java 歌词解析代码_网易云歌词爬取(java)
  11. pom文件中的dependencyManagement和dependency
  12. Java 学生选课系统 源代码
  13. ***YZJ的牛肉干***
  14. 中科大计算机与华科,2021全国理工科大学排名!打破传统模式,华科第二,哈工大第五...
  15. (Paper)Network in Network网络分析
  16. sql server 通过参数获取两位数月份
  17. M1 macOS 无法录制系统声音?SoundFlower后继有BlackHole【macOS系统声音内录】
  18. python动态规划01背包_01背包问题(动态规划)python实现
  19. 【已解决】Mac不能登录iCloud,账号密码输入正确会转圈,之后再次回到初始登陆iCloud页面
  20. Linux下面的类红警游戏

热门文章

  1. msvcr120.dll丢失如何修复
  2. 抖音数据 - 网民评论数据采集,分析
  3. 【每日蓝桥】10、一三年省赛Java组真题“剪格子”
  4. Android监听进入和退出第三方应用
  5. 知乎7w阅读!五面阿里拿下飞猪事业部offer,月薪30K
  6. 路由汇总带来的三层环路-解决实验
  7. IT(计算机/软件/互联网)专业词汇宝典
  8. 阿里新推出“阿里云网盘”App,有机会干掉“百度网盘”吗?
  9. 如何让图片保持原比例,占满整个盒子
  10. Altium Designer 相同模块的布局布线操作