赛题理解+Baseline基本思路
时间被打乱了,简化了数据
意思就是越排在前面的中了,得的分越高
迭代类的模型怎么处理
树类型的模型怎么处理
用户画像了解一下
构建推荐系统的核心任务之一在于如何准确地分析出用户的兴趣特点,也就是我们常说的用户画像。
简单说来,用户画像是指从用户产生的各种数据中挖掘和抽取用户在不同属性上的标签,
如年龄、性别、职业、收入、兴趣等。
完备且准确的属性标签将有力地揭示用户本质特征,因而极大地促进精准的个性化推荐。
主流用户画像方法一般是基于机器学习尤其是有监督学习的技术。这类方法从用户数据中抽取特征来作为用户的表示向量,并利用有用户属性标签的数据作为有标注数据来训练用户画像预测模型,从而对更多的没有标签的用户的属性进行预测。
尽管目前的用户画像方法已经取得了不错的效果并被广泛应用于实际推荐系统中,这些方法仍然存在一定的问题和挑战:
首先,这些已有的方法大多数都基于手工抽取的离散特征,这些特征无法刻画用户数据的上下文信息,因此对于用户的表征能力较为有限。
其次,现有的用户画像方法通常基于简单的线性回归或分类模型,无法从用户数据中自动学习高层次抽象特征,也无法对特征之间的交互关系进行建模。另外,已有的用户画像方法往往基于单一类型和单一来源的数据,这些数据对于用户的表征不够丰富。而实际上,用户数据往往是多来源和多类型的。
最后,已有的用户画像方法大都没有考虑用户属性标签的时效性,因此很难刻画用户动态变化的属性如兴趣等。
向量召回会比关联召回更好一点,关联召回,需要item之间有关联,如果关联小,限制会很大
now_phase=0 指定了第几阶段的数据集
数据分析
查看目录下数据
列出…/data/underexpose_train/目录下数据
!ls ../data/underexpose_train/
列出…/data/underexpose_test/目录下目录
!ls ../data/underexpose_test/
列出…/data/underexpose_test/underexpose_test_click-0/目录下数据
!ls ../data/underexpose_test/underexpose_test_click-0/
查看…/data/underexpose_train/underexpose_user_feat.csv数据
!head ../data/underexpose_train/underexpose_user_feat.csv
查看…/data/underexpose_train/underexpose_item_feat.csv数据
!head -1 ../data/underexpose_train/underexpose_item_feat.csv
查看…/data/underexpose_train/underexpose_train_click-0.csv数据
!head ../data/underexpose_train/underexpose_train_click-0.csv
查看…/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
查看…/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
导入python包
import pandas as pd
import numpy as np
from tqdm import tqdm
import warnings
warnings.filterwarnings("ignore")
读取数据
候选集——用户候选集,商品候选集
pd.read_csv?
用户候选集
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()
候选用户user_id个数
underexpose_user_feat.user_id.count() # ,nrows=100 # 测试的时候改小,便于测试运行一样
查看用户user_age_level分布
underexpose_user_feat.user_age_level.value_counts() # 下面的我不是测试,用的就是nrows=None
查看用户user_gender分布
underexpose_user_feat.user_gender.value_counts(dropna=False,ascending=False,sort=False)
分析:男女比例接近5 :1 ,女多男少
查看用户user_city_level分布
underexpose_user_feat.user_city_level.value_counts(dropna=False,ascending=False,sort=False)
商品候选集
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()
查看商品item_id个数
underexpose_item_feat.item_id.count()
查看商品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
查看商品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
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)
len(underexpose_train_click)
241784
underexpose_train_click.head()
underexpose_train_click.sort_values(['user_id','time']).head(20)
underexpose_train_click[underexpose_train_click["user_id"]==1].sort_values(["time"]).head(20)
underexpose_train_click[underexpose_train_click["user_id"]==1].sort_values(["time","phase"]).head(20)
underexpose_train_click[underexpose_train_click["user_id"]==2].head(20)
测试集——用户点击数据-待预测数据
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
list_test_phase_query_file
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)
len(underexpose_test_click[underexpose_test_click['item_id']<0])
len(set(underexpose_test_click[underexpose_test_click['item_id']<0].user_id))
查看测试集合数据-待预测的数据
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()
underexpose_test_click.sort_values(['user_id','time']).head(20)
underexpose_test_click[underexpose_test_click["user_id"]==11].sort_values(['time']).head(20)
underexpose_test_click[underexpose_test_click["user_id"]==11].sort_values(['time','phase']).head(20)
len(underexpose_test_click.drop_duplicates(['user_id','phase']))
1663
len(set(underexpose_test_click['user_id']))
1663
建模数据准备序列数据处理
underexpose_train_click.head()
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()
dict_train_user_phase_action[0][1]
测试数据
dict_test_user_phase_action.keys()
dict_test_user_phase_action[0].keys()
dict_test_user_phase_action[0][11]
用户画像数据处理
underexpose_user_feat.head()
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.特征筛选:特征重要性、线性回归参数
特征工程实践
模型融合原理
找偏差相近的模型进行融合
模型融合实践