热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PaddlePaddle实战|KDD Cup Regular ML Track基线实现解析

素有数据挖掘领域“世界杯”之称的KDDCup正在火热进行中,百度作为此次大赛的主办方,除了提供10,000美金特别奖,还为使用Paddle

素有数据挖掘领域“世界杯”之称的KDD Cup正在火热进行中,百度作为此次大赛的主办方,除了提供10,000美金特别奖,还为使用PaddlePaddle的参赛选手精心提供了KDD Cup Regular ML Track基线支持,此基线能够在Linux和单机CPU/GPU上运行,通过使用基线,参赛队伍可以更方便地进行特征工程和网络的优化,高效完成训练,并获得更好的结果。

为了让选手更方便地使用此基线,我们将为大家剖析KDD Cup Regular ML Track基线的技术特点和使用过程。

本文对应代码地址:

https://github.com/PaddlePaddle/models/tree/develop/PaddleRec/ctr/Paddle_baseline_KDD2019

阅读本文请参考GitHub代码库。

数据预处理

问题定义:

通过给定的用户query记录,展示记录,用户对出行方式点击行为等原始数据预测用户选择的出行方式(transportmode 1 - transport mode 11)。注意有一部分记录(plans)没有返回点击行为,题目要求没有点击同样需要预测。我们将问题重新定义为二分类问题。对每一个transport mode的点击行为都给出一个0到1的概率值(包括上述未点击行为,强行定义为transport mode 0),进而表示为对给定一种mode的ctr预估问题。

特征预处理:

特征预处理的作用是将原始数据转换成一条一条可以用作训练模型的实例(instances)。我们采用json格式保存instances,其中一条instance的json示例:

{"mode_min_distance": 1,"pid": "","weather": {"min_temp": "10","wea": "q","wind": "12","max_temp": "25"},"plan_rank": 1,"query": {"hour": "09","weekday": "3","d2": 40.0,"o2": 39.92,"o1": 116.43,"d1": 116.57},"eta_rank": 3,"label": 0,"mode_min_eta": 3,"price_rank": 3,"profile": [0],"mode_rank1": 11,"mode_rank2": 3,"mode_rank3": 4,"mode_rank4": 7,"mode_rank5": 1,"mode_max_eta": 1,"plan": {"distance": 0.13730889964270376,"price": 0.00760043431053203,"eta": 0.07021413598936856,"transport_mode": 11},"mode_max_distance": 7,"whole_rank": 5,"mode_max_price": 4,"mode_min_price": -1,"distance_rank": 4
}

注意每一条instance通过json直接解析成Python的dict结构(本文例子中有dict嵌套结构),我们可以自定义生成自己的特征和label供模型训练或者预测,dict中的键为特征名,值为特征值。

代码:preprocess_dense.py/preprocess.py 为训练样本生成代码, pre_test_dense.py/pre_process_test.py 为测试样本生成代码。带有dense后缀的为生成dense特征和sparse特征的处理脚本,不带后缀的为全sparse特征的处理脚本。具体选用哪种生成策略或者结合两种生成策略可自定义处理,这里仅提供大致思路,特征工程方面的拓展工作在此框架下比较方便。本文后续实现模型将以同时生成dense和sparse特征为例,详情见preprocess_dense.py。

组建模型

本文采用模型参考DeepFM论文(https://arxiv.org/abs/1703.04247),参见network_confv6, 其他基于fm&deep的更加花哨的模型组建请参考networks文件夹下其他文件,读者也可以开脑洞自定义实现,注意使用其他模型的时候需要对应修改instance喂入模型的格式。

训练模型

定义instance喂入模型格式

本文使用PaddlePaddle Dataset接口。Dataset是一个工厂类,有如下两种:

(1)QueueDataset:每轮训练从指定的文件列表里读取数据。

(2)InMemoryDataset:用户可以调用LoadIntoMemory把数据读到内存。每轮训练从内存中读取数据。

用户创建Dataset时,默认是QueueDataset(具体使用查看文档)。参见map_reader.py中实现MapDataset示例, 在用户实现的dataset类中,用户可以根据自己的特征实现任意的处理逻辑,在generate_sample()函数中定义每个instance输入到模型的格式,注意在示例中,一共通过feature_name定义了 "dense_feature", "context" + str(idx), "context_fm","label" 这四类输入格式。在local_train.py中使用dataset的示例:

dense_feature = fluid.layers.data(name="dense_feature",shape=[DIM_DENSE_FEATURE], dtype='float32')
context_feature = [fluid.layers.data(name="context"+ str(i), shape=[1], lod_level=1, dtype="int64")for i in range(0,NUM_CONTEXT_FEATURE)]
context_feature_fm = fluid.layers.data(name="context_fm",shape=[1], dtype='int64', lod_level=1)
label = fluid.layers.data(name='label', shape=[1],dtype='int64')print("ready to network")
loss, auc_var, batch_auc_var, accuracy, predict =ctr_deepfm_dataset(dense_feature, context_feature, context_feature_fm, label,args.embedding_size,args.sparse_feature_dim)print("ready to optimize")
optimizer = fluid.optimizer.SGD(learning_rate=1e-4)
optimizer.minimize(loss)
exe = fluid.Executor(fluid.CPUPlace())
exe.run(fluid.default_startup_program())
dataset = fluid.DatasetFactory().create_dataset()
dataset.set_use_var([dense_feature] + context_feature +[context_feature_fm] + [label])
pipe_command = PYTHON_PATH + " map_reader.py%d" % args.sparse_feature_dim
dataset.set_pipe_command(pipe_command)
dataset.set_batch_size(args.batch_size)
thread_num = 1
dataset.set_thread(thread_num)

注意set_pipe_command(pipe_command), pipe command是对原始的数据做处理,生成PaddlePaddle可以识别的格式。Dataset读取的每一行原始数据,都会用这里的命令做处理。可以是一个执行python脚本或者二进制等任意Linux命令,用户可以写自己的逻辑。pipe command生成var的顺序需要和set_user_var保持一致。

接下来就需要在pipe_command中处理数据。

在Pipe Command中处理数据

PaddlePaddle中提供了基类paddle.fluid.incubate.data_generator.MultiSlotDataGenerator,用户可以继承并实现自己的处理数据的逻辑。生成的数据需要与set_use_var中设置的顺序保持一致。具体代码参考map_reader.py中自定义处理原始数据代码,用户需实现generate_sample()函数来处理每一行数据:

def _process_line(self, line):instance &#61; json.loads(line)"""profile &#61;instance["profile"]len_profile &#61; len(profile)if len_profile >&#61; 10:user_profile_feature&#61; profile[0:10]else:profile.extend([0]*(10-len_profile))user_profile_feature&#61; profileif len(profile) > 1 or (len(profile)&#61;&#61; 1 and profile[0] !&#61; 0):for p inprofile:ifp >&#61; 1 and p <&#61; 65:user_profile_feature[p- 1] &#61; 1"""context_feature &#61; []context_feature_fm &#61; []dense_feature &#61; [0] *self.dense_lengthplan &#61; instance["plan"]for i, val inenumerate(self.dense_feature_list):dense_feature[i]&#61; plan[val]if (instance["pid"] &#61;&#61;""):instance["pid"]&#61; 0query &#61;instance["query"]weather_dic &#61;instance["weather"]for fea in self.pid_list:context_feature.append([hash(fea&#43; str(instance[fea])) % self.hash_dim])context_feature_fm.append(hash(fea&#43; str(instance[fea])) % self.hash_dim)for fea inself.query_feature_list:context_feature.append([hash(fea&#43; str(query[fea])) % self.hash_dim])context_feature_fm.append(hash(fea&#43; str(query[fea])) % self.hash_dim)for fea inself.plan_feature_list:context_feature.append([hash(fea&#43; str(plan[fea])) % self.hash_dim])context_feature_fm.append(hash(fea&#43; str(plan[fea])) % self.hash_dim)for fea inself.rank_feature_list:context_feature.append([hash(fea&#43; str(instance[fea])) % self.hash_dim])context_feature_fm.append(hash(fea&#43; str(instance[fea])) % self.hash_dim)for fea inself.rank_whole_pic_list:context_feature.append([hash(fea&#43; str(instance[fea])) % self.hash_dim])context_feature_fm.append(hash(fea&#43; str(instance[fea])) % self.hash_dim)for fea in self.weather_feature_list:context_feature.append([hash(fea&#43; str(weather_dic[fea])) % self.hash_dim])context_feature_fm.append(hash(fea&#43; str(weather_dic[fea])) % self.hash_dim)label &#61;[int(instance["label"])]return dense_feature, context_feature,context_feature_fm, labeldef generate_sample(self, line):def data_iter():dense_feature,sparse_feature, sparse_feature_fm, label &#61; self._process_line(line)#feature_name&#61; ["user_profile"]feature_name&#61; []feature_name.append("dense_feature")for idxin self.categorical_range_:feature_name.append("context"&#43; str(idx))feature_name.append("context_fm")feature_name.append("label")yieldzip(feature_name, [dense_feature] &#43; sparse_feature &#43; [sparse_feature_fm] &#43;[label])return data_iter

至此&#xff0c;模型定义&#xff0c;数据格式处理逻辑&#xff0c;训练流程都已确定&#xff0c;执行Python local_trian.py就可以开始训练了。

相信你已经掌握了如何使用KDD Cup Regular ML Track 基线&#xff0c;快去实际操作吧。如果还没有报名参加KDD Cup 2019&#xff0c;点击前往https://dianshi.baidu.com/competition/29/rule&#xff0c;报名截止日期为2019年5月23日。

百度大脑AI Studio还为此次参赛选手提供了免费Tesla V100的算力支持。作为当前性能最好的工业级训练卡之一&#xff0c;参赛者选择一人一卡&#xff08;单机&#xff09;项目模式下不必再担心CPU性能不足的问题。前往https://aistudio.baidu.com/aistudio/questionnaire?activityid&#61;371&#xff0c;或点击左下角“阅读原文”&#xff0c;即可在线申请算力邀请码。

参赛过程中如有任何疑问&#xff0c;欢迎加入KDD Cup 2019官方讨论群。入群方法如下&#xff1a;

识别下方二维码&#xff0c;添加PaddlePaddle小助手&#xff08;申请时请备注“KDD”&#xff09;&#xff0c;小助手会在第一时间邀您入群。

更多信息欢迎关注&#xff1a;

https://github.com/PaddlePaddle/models/tree/develop/PaddleRec/ctr/Paddle_baseline_KDD2019


推荐阅读
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了多因子选股模型在实际中的构建步骤,包括风险源分析、因子筛选和体系构建,并进行了模拟实证回测。在风险源分析中,从宏观、行业、公司和特殊因素四个角度分析了影响资产价格的因素。具体包括宏观经济运行和宏经济政策对证券市场的影响,以及行业类型、行业生命周期和行业政策对股票价格的影响。 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • 嵌入式处理器的架构与内核发展历程
    本文主要介绍了嵌入式处理器的架构与内核发展历程,包括不同架构的指令集的变化,以及内核的流水线和结构。通过对ARM架构的分析,可以更好地理解嵌入式处理器的架构与内核的关系。 ... [详细]
  • 本文介绍了在Python张量流中使用make_merged_spec()方法合并设备规格对象的方法和语法,以及参数和返回值的说明,并提供了一个示例代码。 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
author-avatar
HH小娃娃
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有