介绍
H&M Personalized Fashion Recommendations baseline,基于not_so_fancy_but_fast_benchmark这个kernel。
核心逻辑:
- 针对每个customer,推荐他最近购买最多的前12个article
- 如果最近购买的article不足12个,则用被购买最多的12-n个article补足
- 如果这个customer没有购买记录,则使用被购买最多的12个article补足
代码
导入包+配置目录
from datetime import datetime
import numpy as np
import pandas as pd
from tqdm import tqdm
from pathlib import Path
data_path = Path('/kaggle/input/h-and-m-personalized-fashion-recommendations/')
读取交易数据和submission表
%%time
transactions = pd.read_csv(
data_path / 'transactions_train.csv',
# 强行设置article_id为str,否则会按照int格式读,并把字符串开头的0都去掉
dtype={'article_id': str}
)
submission = pd.read_csv(data_path / 'sample_submission.csv')
交易日期的数据做预处理,取出月份feature
transactions['t_dat'] = pd.to_datetime(transactions['t_dat'])
transactions['month'] = transactions['t_dat'].dt.month
print(transactions.shape)
transactions.head()
交易日期的最早和最晚时间
transactions['t_dat'].min(), transactions['t_dat'].max()
(Timestamp('2018-09-20 00:00:00'), Timestamp('2020-09-22 00:00:00'))
每个月都有多少笔交易
transactions['month'].value_counts()
6 3670709
7 3158996
5 2922134
4 2817336
9 2620223
10 2543812
8 2490722
11 2468652
1 2339825
3 2334502
12 2267142
2 2154271
Name: month, dtype: int64
选择只使用夏天(4-10月)的数据,因为测试阶段只是2020年9月22日之后一周的数据
# 如果加上这句话,LB score可以从0.0064到0.0186,可以看出时间的选择很重要
transactions = transactions.loc[transactions['t_dat'] >= datetime(2020, 9, 7)]
transactions = transactions.loc[transactions['month'].isin([4,5,6,7,8,9,10])]
transactions.reset_index(drop=True, inplace=True)
print(transactions.shape)
(20223932, 6)
针对每个customer,取出其购买每个article的数量
purchase_dict = {}
# 每个customer买的每个article
# purchase_dict的每个key是一个customer_id
# purchase_dict的每个value是一个dict,其key是article_id,value是购买次数
for i,x in enumerate(zip(transactions['customer_id'], transactions['article_id'])):
cust_id, art_id = x
if cust_id not in purchase_dict:
purchase_dict[cust_id] = {}
if art_id not in purchase_dict[cust_id]:
purchase_dict[cust_id][art_id] = 0
#每有一个记录,则+1
purchase_dict[cust_id][art_id] += 1
print(len(purchase_dict))
1123233
submission的格式
print(submission.shape)
submission.head()
需要预测的customer_id列表
not_so_fancy_but_fast_benchmark = submission[['customer_id']]
prediction_list = []
取出销量最高的12个article
dummy_list = list((transactions['article_id'].value_counts()).index)[:12]
dummy_pred = ' '.join(dummy_list)
对每个customer做预测
for i, cust_id in tqdm(enumerate(submission['customer_id'].values.reshape((-1,)))):
# 如果该customer有购买记录
if cust_id in purchase_dict:
# 根据他的购买历史,根据销量倒排,其中的x[0]是article_id, x[1]是购买次数
l = sorted((purchase_dict[cust_id]).items(), key=lambda x: x[1], reverse=True)
# 取出对应的article_id
l = [y[0] for y in l]
# 如果购买历史有12个article
if len(l)>12:
s = ' '.join(l[:12])
else:
# 如果不足,则用最热门的补充剩下的
s = ' '.join(l+dummy_list[:(12-len(l))])
else:
# 如果该customer没有购买记录,则用热门的12个作为预测值
s = dummy_pred
prediction_list.append(s)
存储预测结果
not_so_fancy_but_fast_benchmark['prediction'] = prediction_list
not_so_fancy_but_fast_benchmark.head()
保存文件,submit
not_so_fancy_but_fast_benchmark.to_csv('not_so_fancy_but_fast_benchmark.csv', index=False)