2020 KDD比赛指导视频学习

特征工程专题

模型融合专题

赛题理解+Baseline基本思路

 

2020 KDD比赛指导视频学习_推荐系统
2020 KDD比赛指导视频学习_特征工程_02
2020 KDD比赛指导视频学习_特征工程_03
2020 KDD比赛指导视频学习_用户画像_04
2020 KDD比赛指导视频学习_用户画像_05
2020 KDD比赛指导视频学习_推荐系统_06
2020 KDD比赛指导视频学习_推荐系统_07
2020 KDD比赛指导视频学习_数据分析_08
2020 KDD比赛指导视频学习_推荐系统_09
时间被打乱了,简化了数据

2020 KDD比赛指导视频学习_数据_10

2020 KDD比赛指导视频学习_用户画像_11
2020 KDD比赛指导视频学习_数据分析_12
2020 KDD比赛指导视频学习_推荐系统_13
2020 KDD比赛指导视频学习_数据分析_14
2020 KDD比赛指导视频学习_数据分析_15
意思就是越排在前面的中了,得的分越高
2020 KDD比赛指导视频学习_数据_16
迭代类的模型怎么处理
树类型的模型怎么处理

用户画像了解一下

构建推荐系统的核心任务之一在于如何准确地分析出用户的兴趣特点,也就是我们常说的用户画像。

简单说来,用户画像是指从用户产生的各种数据中挖掘和抽取用户在不同属性上的标签,
如年龄、性别、职业、收入、兴趣等。
完备且准确的属性标签将有力地揭示用户本质特征,因而极大地促进精准的个性化推荐。

主流用户画像方法一般是基于机器学习尤其是有监督学习的技术。这类方法从用户数据中抽取特征来作为用户的表示向量,并利用有用户属性标签的数据作为有标注数据来训练用户画像预测模型,从而对更多的没有标签的用户的属性进行预测。

尽管目前的用户画像方法已经取得了不错的效果并被广泛应用于实际推荐系统中,这些方法仍然存在一定的问题和挑战:

首先,这些已有的方法大多数都基于手工抽取的离散特征,这些特征无法刻画用户数据的上下文信息,因此对于用户的表征能力较为有限。

其次,现有的用户画像方法通常基于简单的线性回归或分类模型,无法从用户数据中自动学习高层次抽象特征,也无法对特征之间的交互关系进行建模。另外,已有的用户画像方法往往基于单一类型和单一来源的数据,这些数据对于用户的表征不够丰富。而实际上,用户数据往往是多来源和多类型的。

最后,已有的用户画像方法大都没有考虑用户属性标签的时效性,因此很难刻画用户动态变化的属性如兴趣等。

2020 KDD比赛指导视频学习_数据_17
2020 KDD比赛指导视频学习_特征工程_18
2020 KDD比赛指导视频学习_特征工程_19
2020 KDD比赛指导视频学习_推荐系统_20
2020 KDD比赛指导视频学习_特征工程_21
2020 KDD比赛指导视频学习_用户画像_22
2020 KDD比赛指导视频学习_数据_23
2020 KDD比赛指导视频学习_特征工程_24
2020 KDD比赛指导视频学习_特征工程_25
2020 KDD比赛指导视频学习_推荐系统_26
向量召回会比关联召回更好一点,关联召回,需要item之间有关联,如果关联小,限制会很大

2020 KDD比赛指导视频学习_用户画像_27
now_phase=0 指定了第几阶段的数据集

2020 KDD比赛指导视频学习_推荐系统_28
2020 KDD比赛指导视频学习_数据_29
2020 KDD比赛指导视频学习_数据_30
2020 KDD比赛指导视频学习_数据分析_31
2020 KDD比赛指导视频学习_推荐系统_32
2020 KDD比赛指导视频学习_特征工程_33
2020 KDD比赛指导视频学习_数据_34
2020 KDD比赛指导视频学习_特征工程_35
2020 KDD比赛指导视频学习_用户画像_36
2020 KDD比赛指导视频学习_推荐系统_37
2020 KDD比赛指导视频学习_特征工程_38
2020 KDD比赛指导视频学习_推荐系统_39
2020 KDD比赛指导视频学习_特征工程_40
2020 KDD比赛指导视频学习_推荐系统_41
2020 KDD比赛指导视频学习_特征工程_42
2020 KDD比赛指导视频学习_推荐系统_43
2020 KDD比赛指导视频学习_数据_44
2020 KDD比赛指导视频学习_数据_45

数据分析

 

查看目录下数据

列出…/data/underexpose_train/目录下数据

!ls ../data/underexpose_train/

列出…/data/underexpose_test/目录下目录

!ls ../data/underexpose_test/

2020 KDD比赛指导视频学习_数据_46

列出…/data/underexpose_test/underexpose_test_click-0/目录下数据

!ls ../data/underexpose_test/underexpose_test_click-0/

2020 KDD比赛指导视频学习_用户画像_47

查看…/data/underexpose_train/underexpose_user_feat.csv数据

!head ../data/underexpose_train/underexpose_user_feat.csv

2020 KDD比赛指导视频学习_数据分析_48

查看…/data/underexpose_train/underexpose_item_feat.csv数据

!head -1 ../data/underexpose_train/underexpose_item_feat.csv

2020 KDD比赛指导视频学习_数据_49

查看…/data/underexpose_train/underexpose_train_click-0.csv数据

!head ../data/underexpose_train/underexpose_train_click-0.csv

2020 KDD比赛指导视频学习_推荐系统_50

查看…/data/underexpose_test/underexpose_test_click-0/underexpose_test_click-0.csv数据

!head ../data/underexpose_test/underexpose_test_click-0/underexpose_test_click-0.csv

2020 KDD比赛指导视频学习_数据_51

查看…/data/underexpose_test/underexpose_test_click-0/underexpose_test_qtime-0.csv数据

!head ../data/underexpose_test/underexpose_test_click-0/underexpose_test_qtime-0.csv

2020 KDD比赛指导视频学习_推荐系统_52

导入python包
import pandas as pd
import numpy as np
from tqdm import tqdm
import warnings
warnings.filterwarnings("ignore")
读取数据

候选集——用户候选集,商品候选集

pd.read_csv?

2020 KDD比赛指导视频学习_特征工程_53

用户候选集

underexpose_user_feat = pd.read_csv("./data/underexpose_train/underexpose_user_feat.csv"
                                    ,names=["user_id", "user_age_level", "user_gender", "user_city_level"]
                                    ,nrows=100     # 测试的时候改小,便于测试运行 
                                    ,sep=","
                                   )
underexpose_user_feat.head()

2020 KDD比赛指导视频学习_数据_54

候选用户user_id个数

underexpose_user_feat.user_id.count() #  ,nrows=100     # 测试的时候改小,便于测试运行一样

2020 KDD比赛指导视频学习_用户画像_55

查看用户user_age_level分布

underexpose_user_feat.user_age_level.value_counts() # 下面的我不是测试,用的就是nrows=None

2020 KDD比赛指导视频学习_数据分析_56

查看用户user_gender分布

underexpose_user_feat.user_gender.value_counts(dropna=False,ascending=False,sort=False)

2020 KDD比赛指导视频学习_特征工程_57

分析:男女比例接近5 :1 ,女多男少

查看用户user_city_level分布

underexpose_user_feat.user_city_level.value_counts(dropna=False,ascending=False,sort=False)

2020 KDD比赛指导视频学习_数据_58

商品候选集

list_item_id = []
list_txt_vec = []
list_img_vec = []
with open("../data/underexpose_train/underexpose_item_feat.csv") as f:
    for line in tqdm(f):
        line_split = line.strip().split(',[')
        list_item_id.append(line_split[0])
        list_txt_vec.append(line_split[1].strip(']'))
        list_img_vec.append(line_split[2].strip(']'))
underexpose_item_feat = pd.DataFrame({"item_id":list_item_id,"txt_vec":list_txt_vec,"img_vec":list_img_vec})
underexpose_item_feat = underexpose_item_feat[["item_id", "txt_vec", "img_vec"]]
underexpose_item_feat.head()

2020 KDD比赛指导视频学习_推荐系统_59

查看商品item_id个数

underexpose_item_feat.item_id.count()

2020 KDD比赛指导视频学习_数据分析_60

查看商品txt_vec向量维度

len(underexpose_item_feat.txt_vec.values[0].split(","))

128

np.sum([float(x_)**2 for x_ in underexpose_item_feat.txt_vec.values[0].split(",")])

808.8675917468368

np.sum([float(x_)**2 for x_ in underexpose_item_feat.txt_vec.values[1].split(",")])

405.9183285070672
2020 KDD比赛指导视频学习_数据_61
2020 KDD比赛指导视频学习_用户画像_62

查看商品img_vec向量维度

len(underexpose_item_feat.img_vec.values[0].split(","))

128

np.sum([float(x_)**2 for x_ in underexpose_item_feat.img_vec.values[0].split(",")])

372.028070148304

np.sum([float(x_)**2 for x_ in underexpose_item_feat.img_vec.values[1].split(",")])

374.25006719310994

训练集——用户点击商品数据
list_phase_range = [0,1,2,3,4]
list_train_phase_file = [(x_,"./data/underexpose_train/underexpose_train_click-"+str(x_)+".csv") for x_ in list_phase_range]
list_train_phase_file

2020 KDD比赛指导视频学习_特征工程_63

def get_train_click(list_train_phase_file):
    list_underexpose_click = []
    columns = ["user_id", "item_id", "time", "phase"]
    for phase, file in tqdm(list_train_phase_file):
        underexpose_click = pd.read_csv(file
                                        ,names=["user_id", "item_id", "time"]
                                        ,nrows=None      
                                        ,sep=","
                                       )
        underexpose_click["phase"] = phase
        underexpose_click = underexpose_click[columns]
        list_underexpose_click.append(underexpose_click)
    all_underexpose_click = pd.concat(list_underexpose_click)
    return all_underexpose_click[columns]
underexpose_train_click = get_train_click(list_train_phase_file)

2020 KDD比赛指导视频学习_数据_64

len(underexpose_train_click)

241784

underexpose_train_click.head()

2020 KDD比赛指导视频学习_推荐系统_65

underexpose_train_click.sort_values(['user_id','time']).head(20)

2020 KDD比赛指导视频学习_推荐系统_66

underexpose_train_click[underexpose_train_click["user_id"]==1].sort_values(["time"]).head(20)

2020 KDD比赛指导视频学习_数据_67

underexpose_train_click[underexpose_train_click["user_id"]==1].sort_values(["time","phase"]).head(20)

2020 KDD比赛指导视频学习_特征工程_68

underexpose_train_click[underexpose_train_click["user_id"]==2].head(20)

2020 KDD比赛指导视频学习_数据_69

测试集——用户点击数据-待预测数据
list_phase_range = [0,1,2,3,4]
list_test_phase_file = [(x_,"../data/underexpose_test/underexpose_test_click-"+str(x_)+"/underexpose_test_click-"+str(x_)+".csv") for x_ in list_phase_range]
list_test_phase_query_file = [(x_,"../data/underexpose_test/underexpose_test_click-"+str(x_)+"/underexpose_test_qtime-"+str(x_)+".csv") for x_ in list_phase_range]
list_test_phase_file

2020 KDD比赛指导视频学习_特征工程_70

list_test_phase_query_file

2020 KDD比赛指导视频学习_特征工程_71

def get_test_click(list_test_phase_file, list_test_phase_query_file):
    list_underexpose_click = []
    columns = ["user_id", "item_id", "time", "phase"]
    for phase, file in tqdm(list_test_phase_file):
        underexpose_click = pd.read_csv(file
                                        ,names=["user_id", "item_id", "time"]
                                        ,nrows=None      
                                        ,sep=","
                                       )
        underexpose_click["phase"] = phase
        underexpose_click = underexpose_click[columns] 
        list_underexpose_click.append(underexpose_click)
    for phase, file in tqdm(list_test_phase_query_file):
        underexpose_qtime = pd.read_csv(file
                                    ,names=["user_id", "query_time"]
                                    ,nrows=None      
                                    ,sep=","
                                   )   
        underexpose_qtime.columns = ["user_id", "time"]
        underexpose_qtime["phase"] = phase
        underexpose_qtime["item_id"] = -999
        underexpose_qtime = underexpose_qtime[columns]
        list_underexpose_click.append(underexpose_qtime)
    all_underexpose_click = pd.concat(list_underexpose_click)
    return all_underexpose_click[columns]
underexpose_test_click = get_test_click(list_test_phase_file, list_test_phase_query_file)

2020 KDD比赛指导视频学习_数据分析_72

len(underexpose_test_click[underexpose_test_click['item_id']<0])

2020 KDD比赛指导视频学习_推荐系统_73

len(set(underexpose_test_click[underexpose_test_click['item_id']<0].user_id))

2020 KDD比赛指导视频学习_推荐系统_74

查看测试集合数据-待预测的数据

len(underexpose_test_click[underexpose_test_click["item_id"]!=-999])

21216

len(underexpose_test_click[underexpose_test_click["item_id"]==-999])

1663

underexpose_test_click.head()

2020 KDD比赛指导视频学习_特征工程_75

underexpose_test_click.sort_values(['user_id','time']).head(20)

2020 KDD比赛指导视频学习_数据分析_76

underexpose_test_click[underexpose_test_click["user_id"]==11].sort_values(['time']).head(20)

2020 KDD比赛指导视频学习_特征工程_77

underexpose_test_click[underexpose_test_click["user_id"]==11].sort_values(['time','phase']).head(20)

2020 KDD比赛指导视频学习_用户画像_78

len(underexpose_test_click.drop_duplicates(['user_id','phase']))

1663

len(set(underexpose_test_click['user_id']))

1663

建模数据准备

序列数据处理

underexpose_train_click.head()

2020 KDD比赛指导视频学习_用户画像_79

def deal_click_data(underexpose_click_data):
    underexpose_click_data = underexpose_click_data.sort_values(['user_id','phase','time'])
    dict_user_phase_action = {}
    for i,row in tqdm(underexpose_click_data.iterrows()):
        user_id, item_id, time, phase = int(row["user_id"]), int(row["item_id"]), float(row["time"]), int(row["phase"])
        if phase not in dict_user_phase_action:
            dict_user_phase_action[phase] = {}
        if user_id not in dict_user_phase_action[phase]:
            dict_user_phase_action[phase][user_id] = {"item_seq":[],"time_seq":[],"diff_time_seq":[]}
        else:
            diff_time = (time - dict_user_phase_action[phase][user_id]["time_seq"][-1]) * 10**4
            dict_user_phase_action[phase][user_id]["diff_time_seq"].append(diff_time)    
        dict_user_phase_action[phase][user_id]["item_seq"].append(item_id)
        dict_user_phase_action[phase][user_id]["time_seq"].append(time)
    return dict_user_phase_action
# 2 * 10 **4
dict_train_user_phase_action = deal_click_data(underexpose_train_click)
dict_test_user_phase_action = deal_click_data(underexpose_test_click)

查看处理好的序列数据

训练数据

dict_train_user_phase_action.keys()
dict_train_user_phase_action[0].keys()

2020 KDD比赛指导视频学习_用户画像_80

dict_train_user_phase_action[0][1]

2020 KDD比赛指导视频学习_推荐系统_81

测试数据

dict_test_user_phase_action.keys()

2020 KDD比赛指导视频学习_用户画像_82

dict_test_user_phase_action[0].keys()

2020 KDD比赛指导视频学习_特征工程_83

dict_test_user_phase_action[0][11]

2020 KDD比赛指导视频学习_数据_84

用户画像数据处理

underexpose_user_feat.head()

2020 KDD比赛指导视频学习_推荐系统_85

def deal_user_feat_data(user_feat_data):
    user_feat_data = user_feat_data.fillna(-1)
    dict_user_feat = {}
    dict_user_age_level, index_user_age_level = {}, 0
    dict_user_gender, index_user_gender = {}, 0
    dict_user_city_level, index_user_city_level = {}, 0
    for i,row in tqdm(user_feat_data.iterrows()):
        user_id, user_age_level, user_gender, user_city_level = int(row["user_id"]), int(row["user_age_level"]), row["user_gender"], int(row["user_city_level"])
        if user_id not in dict_user_feat:
            dict_user_feat[user_id] = {}
        if user_age_level not in dict_user_age_level:
            dict_user_age_level[user_age_level] = index_user_age_level
            index_user_age_level += 1
        if user_gender not in dict_user_gender:
            dict_user_gender[user_gender] = index_user_gender
            index_user_gender += 1
        if user_city_level not in dict_user_city_level:
            dict_user_city_level[user_city_level] = index_user_city_level
            index_user_city_level += 1
        dict_user_feat[user_id]["user_age_level"] = dict_user_age_level[user_age_level]
        dict_user_feat[user_id]["user_gender"] = dict_user_gender[user_gender]
        dict_user_feat[user_id]["user_city_level"] = dict_user_city_level[user_city_level]
    return dict_user_feat, dict_user_age_level, dict_user_gender, dict_user_city_level
dict_user_feat, dict_user_age_level, dict_user_gender, dict_user_city_level = deal_user_feat_data(underexpose_user_feat)

指标测评

 

Baseline

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

特征工程原理

 

特征工程:

  • 目的
    1.从数据中抽取和目标相关的信息
    2.减少信息过多带来的麻烦
    3.筛选相关信息

  • 数据分析
    1.熟悉了解业务
    2.明白商业逻辑

  • 特征提取和处理
    1.特征提取:各类统计量
    2.特征处理:类别特征、连续特征、类别序列特征、连续序列特征

  • 特征选择
    1.信息筛选:可解释性(为了提供改进的方向)
    2.特征筛选:特征重要性、线性回归参数

特征工程实践

 

模型融合原理

 

2020 KDD比赛指导视频学习_特征工程_86

2020 KDD比赛指导视频学习_数据分析_87

找偏差相近的模型进行融合

2020 KDD比赛指导视频学习_数据分析_88

模型融合实践