介绍

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)
最后修改:2022 年 04 月 01 日 10 : 48 PM
如果觉得我的文章对你有用,请随意赞赏