对样本、特征的管理,在真实场景中尤其重要。对于生产出来的一条数据,首先对其进行正负类别判断,转化成了样本。样本里面的原始字段需要清洗、整合,才能得到特征。
以资讯推荐为例,一种有效的管理流程分成三步:样本表,特征表,拼接方案。
样本表结构:
生产时间,用户id,文档id,类别
特征表结构(用户侧特征和文档侧特征混合存在一张表里头):
生产时间,用户id,用户侧特征名,特征具体内容
生产时间,文档id,文档侧特征名,特征具体内容
拼接方案(确定每条样本由哪些特征组成,涉及到具体拼接):
# log_df: ftime, user_id, doc_id, label
# feature_df: ftime, owner, feature_name, feature_content
#需要使用到的特征
feature_list = [...]
#用户侧特征扩展
user_df = log_df.join(feature_df, (log_df["ftime"]==feature_df["ftime"])
& (log_df["user_id"]==feature_df["owner"]))
user_df = user_df.filter(user_df["feature_name"] in feature_list)
#文本侧特征扩展
doc_df = log_df.join(feature_df, (log_df["ftime"]==feature_df["ftime"])
& (log_df["doc_id"]==feature_df["owner"]))
doc_df = doc_df.filter(doc_df["feature_name"].isin(feature_list)==True)
#用户特征与文本特征汇合
sample_df = user_df.join(doc_df, (user_df["user_id"]==doc_df["user_id"])
&(user_df["doc_id"]==doc_df["doc_id"])
&(user_df["ftime"] == doc_df["ftime"]))
sample_df = sample_df.withColumn("concat_feature",
concat_ws("##", sample_df["feature_name"], sample_df["feature_content"]))
sample_df = sample_df.groupBy("ftime", "user_id","doc_id", "label").
agg(collect_list('concat_feature').alias("feature_list")) #此时sample_df只有"ftime", "user_id","doc_id", "label"和"feature_list"
#特征按顺序排列好
def arrange_feature_func(feature_list):
pass
arrange_feature_udf = udf(arrange_feature_func, StringType())
sample_df = sample_df.withColumn("whole_feature",
arrange_feature_udf(sample_df["feature_list"]))