2019-07-05 09:47:56 wushaowu2014 阅读数 591
  • Spark快速大数据处理

    课程的主要内容包括: 1.ZooKeeper-分布式过程协同组件 2.Hadoop3-大数据基础组件 3.Tez-Yarn底层计算引擎 4.Hive3-大数据仓库 5.Spark2实时大数据处理 6.Oozie5-大数据流程引擎 课程特点: 1.最新API: Hadoop3/Spark2/Hive3/Oozie5 2.手工搭建集群环境:编译+搭建 3.配套资源:分阶段镜像+课件+安装资源,其中安装资源包括案例源码、脚本等 4.案例为主:分模块案例+天池数据分析竞赛 5.故障教学 6.完整实战项目:天池数据分析

    12795 人正在学习 去看看 余海峰

       下面是自己参加竞赛的一点经历和心得,希望对你有所帮助!

       接触竞赛也有一年多了,期间收获最好的成绩应该是第四名,虽然成绩不怎么样,但是真真切切学到很多东西。参加比赛一开始出于奖金的诱惑,奖金动不动就十几百万,甚至更多,现在也出于问题的挑战性和可行性,以及硬件问题。
       好了,先说说参加比赛的优势。大多赛题都来源于我们的生活,或工业中的各种难题,比如手机流量套餐推荐、浏览内容推荐、是否购买某种产品、天气预测,流量预测,部件寿命预测、等太多的问题,当你接触这些问题后,你会发现原来这些问题都是小case了,嗯,这样真的不再担心找不到工作,但要找更高薪的工作,我想应该还要看人品的,哈哈
       这里,除了可以接触各行业的问题外,你还会结识许多大佬,是的,你会发现都是这么几个大佬打比赛(应该有打比赛为业的吧),他们好像垄断的前排位置,哈哈,也不完全垄断,不然我们参加岂不是陪跑咯。其实每个比赛,一个是看实力,一个是看运气成分。向他们学习,抱他们大腿,哈哈,那你收获更大了

       我刚研究生入学,接触竞赛也是机缘巧合,虽然本科就知道天池,但只是望尘莫及。最开始参加的是CCF同时在天池和datafountain发布的店铺定位,期间也参加了ccf的其他赛题,当时我和我另外一个本科同学参加的,他话比较多的时间在店铺单位这题上,最后我们成绩并进不了复赛,值得高兴的是,另外的小超市预测赛题进复赛了,并取得不错的效果,最后高兴的太早,对于小白翻车在所难免。是的,这真的会花时间,但我们收获了一些知识,以及教训。这里我想提的是,如果你导师有项目,建议先做老师项目为主,竞赛有时间可以接触接触,否则可能被老板批评的。其实,有些竞赛有指导教师,如果你导师感兴趣或者研究方向对口,这样其实可以当个项目来做,到时可以写篇paper投了也不是不可能,顺便再捞个证书奖什么的,嗯,确实想法很美好。当然,有些竞赛会把优秀的方案,推送到一些会议,而这里投会议论文应该so easy了

       忘了,我其实是放养的,说白点就是没老师管,想想有时放养其实挺不错的,但其不然。有老师,做或不做老师的项目,老师都会定期发工资的,不像我们只有羡慕的份咯,还有一点,有导师可以报销各种费用啊,没导师只能自己掏咯,区别还是挺大的。
       好像有点涉及研究生生活了,其实我一开始是想写这个来着,应该到毕业之时,我会分享出来。

       写到这吧,有机机会我在分享参加竞赛值得注意的问题,让你们少踩坑,下面我分享几个竞赛网站:
国外的 kaggle 等
国内的 天池,科赛,dc,df等

       最后,提个醒,参加比赛,一个千万别耽误自己的毕业,一个别耽误导师的项目,祝好!2019-07-05
 

2018-11-12 19:07:54 weixin_42039699 阅读数 1710
  • Spark快速大数据处理

    课程的主要内容包括: 1.ZooKeeper-分布式过程协同组件 2.Hadoop3-大数据基础组件 3.Tez-Yarn底层计算引擎 4.Hive3-大数据仓库 5.Spark2实时大数据处理 6.Oozie5-大数据流程引擎 课程特点: 1.最新API: Hadoop3/Spark2/Hive3/Oozie5 2.手工搭建集群环境:编译+搭建 3.配套资源:分阶段镜像+课件+安装资源,其中安装资源包括案例源码、脚本等 4.案例为主:分模块案例+天池数据分析竞赛 5.故障教学 6.完整实战项目:天池数据分析

    12795 人正在学习 去看看 余海峰

2018年全国信息安全竞赛-安徽省大数据与人工智能应用类竞赛(本科组)--心得总结

距离比赛结束近一个月了,比赛定于10月13-14日在安徽工业经济职业技术学院举行。最终取得了14名的成绩获得了二等奖。想想有必要写下这次比赛的一些心得体会。以前听到大数据觉得比较虚无缥缈,但却对其一直有一份好奇,可能正是因为这种好奇,让我有幸的参加了这次大数据竞赛,最终确定组了团队代表学校参赛。真正准备的时间准确的说只有一个月,从开学开始,但这一个月真的学到了很多很多未知的东西。第一次学会安装双系统,第一次写CSDN博客,第一次改装自己的电脑,第一次对大数据有了新的认识,第一次那么疯狂的学习和吸收知识。我想这次比赛给我带来的收获是巨大的,激发了我对计算机的兴趣,体会了团队分工合作的重要性,以及坚持不懈去学习新的知识。

一、竞赛相关信息:

  • 竞赛环境:

竞赛操作系统:CentOS、编程语言:Java、Python、JavaScript。集成环境为PyCharm和Eclipse。

  • 竞赛内容:
  1. 大数据平台部署,根据要求完成平台环境搭建和测试15%
  2. 大数据预处理,对给定的数据(数据并不完整,有重复等)进行预处理,使得数据准确、完整、一致、可用,并能够对数据格式进行转换。30%
  3. 大数据分析,进行数据分析20%
  4. 大数据可视化,对给定数据进行可视化展示,对可视化结果进行解释说明15%
  5. 综合题,对给定的数据集,应用大数据预处理、大数据分析与挖掘等技术,求解一个给定的问题20%

二、个人心得体会

  • 操作系统

学习大数据需要熟悉并掌握Linux操作统。Linux操作系统有很多版本:Ubuntu、Fedora、Debian、Centos等,比赛所用的操作系统是带图形界面的Centos6.8。可以说系统环境是一开始学习的最大障碍,这对我们来说还是未知的。由于电脑配置原因,我开始并没有尝试用虚拟机安装Linux操作系统,而是选择安装Ubuntu双系统。期间虽然各种问题各种坑,但是最终成功解决了Ubuntu18.04系统相关问题,熟悉Linux操作系统,掌握了一些基础的Linux命令:sudo、wget、cd、mkdir、ls、ssh、scp、vi、rm -rf、source、ifconfig、cp、tar -zxvf、mv等。有了环境搭建的前提。同时也让我写了第一篇CSDN博客,学会通过博客将自己解决问题的方法分享给他人,通过博客记下重要的笔记便于自己以后的回看,深入理解,分享一些自己的东西。

  • 大数据平台部署(云服务器)

我准备的大数据环境包括:Hadoop、Zookeeper、HBase、MySQL、Hive、Spark、Sqoop、Flume的部署安装。实际问题双系统的Ubuntu只能解决Hadoop的伪分布式单节点安装,并不能解决Hadoop的完全分布式搭建。期间在学校大数据实验室网站上练习和熟悉了Hadoop的完全分布式搭建。因虚拟机比较吃电脑配置,后来决定使用云服务器安装和部署所需的大数据环境。因为是学生有优惠,分别在阿里云,百度云,腾讯云各租了一台云主机,系统是Centos7.0+,没有6.8版本的了。6.8和7.0+除了防火墙命令不同,其余命令几乎相同。6.8为iptables,7.0+是firewall。毕竟只有我使用了云服务器来搭建,当然也是遇到了各种问题,详细内容便不记录于此,博客中有记录。因为当时时间比较紧迫就没有改装电脑配置,赛后,我第一次改装自己的电脑,自己安装了8g内存条,以及128g固态硬盘。对电脑硬件配置有了些了解,也对今后的大数据学习有所帮助,毕竟之前是租的云服务器。大数据平台环境部署准备基本完成了。接下来就是反复练习搭建,前期每次搭建几乎都会遇到新的问题,然后一个一个去解决。比赛前我们进行了两次模拟计时演练,这是必要的,基础分当然要确保完全拿到。

  • 大数据预处理和分析

大数据预处理和分析需要用到Java和Python,我们赛前准备的Java进行MapReduce处理,比赛时并没有用上。这次是利用Spark,Python和Hive进行预处理和分析。Spark和Hive我们准备的并不充分,只准备了Spark环境的搭建,Hive环境的搭建以及基本操作。这一部分丢分比较严重,所以后面要深入学习大数据,这部分是重点,掌握MySQL的基本命令行操作,SQL语句。熟练的使用Hive数据仓库和HQL。比赛时,我们那个赛场,用Python的队伍很多,实话说Python在大数据中的优势地位真的很大。数据挖掘,分析,处理,可视化都能用。后期我也会深入学习Python,这个当今很流行的语言。

  • 大数据可视化

大数据可视化可以使用D3.js,Echarts,Highcharts对数据进行可视化,这部分不是很难,熟练的掌握js会占有很大的优势。相关官网也给出了实例和教程。比赛使用的是Echarts,我们准备的也是Echarts,有很多图的模板,如:折线图、柱状图、饼图、散点图等,竞赛时出的是一道折线图和一道雷达图,这部分资料我们没有准备充分,我们做出来了折线图,漏掉了雷达图。

  • 综合应用题

不是很难,对数据进行分析,处理,最终用spark进行精确度计算。不过由于时间原因要进行题目复查,有些数据处理的不够,最终分析的精确度有些差异。

  • 资料获取

开始有的资料仅仅只是些电子文档,后来老师推荐了厦门大学实验室网站,里面有不少大数据学习的资料。学校的实验室网站也有不少资料。但这些根本不够,用纸质资料去学习会遇到很多问题。个人比较偏爱视频资料和纸质资料结合看。可以说这一个月,学校图书馆五楼有关大数据的图书我基本都看了一遍,一些有用的借回来读,一次6本,读完再借。当然这么短时间并不能掌握,只能说对竞赛中的每一部分有了些概念性的了解,毕竟书本的实践性不强。所以就找了一些视频学习网站,如:腾讯课堂、慕课网、千峰网、尚学堂等,对每一部分进行视频学习。建议视频与纸质档或者电子档资料结合看效果更好些。

  • 问题解决

整个比赛历程,从赛前到赛时都会遇到各种各样你会意想不到问题。装双系统误删Windows,双系统grub开机引导,Hadoop环境搭建,SSH免密登录,不连网的情况下安装MySQL,云服务器挖矿程序,hosts文件中服务器公私网ip问题等等,有的问题几小时,有的问题甚至可以困扰你几天,但是不能太固执己见,解决不了就要换种方法换个思路去尝试或者避免。比赛时遇到不会的问题需要灵活处理,比如一些数据量小的数据,实在不会处理,可以手动筛选,占时也不多。养成习惯,问题解决后,记下来解决方法,笔记文档保留,下次再碰到就能迎刃而解,也可以分享给他人,帮助别人解决问题。这也是我写博客的原因。后期我会写一个属于我自己的博客,将我的笔记,理解,经历分享在上面。

  • 团队合作

团队合作真的真的真的很重要。首先大家的分工要很明确,因为时间很短,一个人不可能完成很多事,分工合作会大大提高效率。一个团队,几个志同道合的人有缘聚在一起,大家相互学习,相互鼓励,会给整个队伍中的每个人带来精神支撑,你不是一个人在奋斗。这也让我学会了团队间的沟通交流以及必要的鼓励。

  • 不足之处

总结本次竞赛的不足之处后期都要深入学习。

  1. HiveQL(Hive的SQL语句)掌握不好,也可以说是MySQL的SQL语句掌握不好吧。Hive操作和MySQL操作很多类似。平时习惯了使用Navicat对MySQL进行图形化界面操作,对MySQL的命令行操作甚至一些基本SQL语句都不了解。
  2. Spark准备不充分,数据分析那块丢分严重。Spark还涉及Python和Scala语言。
  3. 环境搭建这块,对环境的操作很熟,但是对HDFS,HBase,Hive,Spark等每一部分的概念、理解不够。
  4. 缺少相关综合性实例或实验的练习,每一部分都是分开找资料学习的,平时练习也缺少一些综合性数据分析和处理练习。

三、总结

经历过这次比赛,总的来说收获很大。不仅激发了学习的兴趣,也掌握了一些适合自己的学习方法,提升了自己的能力。通过这次比赛,我学会了把学习目标变成某一小块,某段时间段内专心这一部分,解决后再去下一部分。养成了写博客的习惯,变向的记录心得,笔记,回看时便会更加深入的理解。学会融入团队,相互学习,相互交流,相互鼓励。这些有着共同爱好和志向的人,今后可能会成为帮助你的好朋友。还有就是要坚持不懈的去完成一件事,喜爱它,并为之付出。今后的路还很长,还需继续学习......

2016-06-23 20:35:20 Bryan__ 阅读数 7990
  • Spark快速大数据处理

    课程的主要内容包括: 1.ZooKeeper-分布式过程协同组件 2.Hadoop3-大数据基础组件 3.Tez-Yarn底层计算引擎 4.Hive3-大数据仓库 5.Spark2实时大数据处理 6.Oozie5-大数据流程引擎 课程特点: 1.最新API: Hadoop3/Spark2/Hive3/Oozie5 2.手工搭建集群环境:编译+搭建 3.配套资源:分阶段镜像+课件+安装资源,其中安装资源包括案例源码、脚本等 4.案例为主:分模块案例+天池数据分析竞赛 5.故障教学 6.完整实战项目:天池数据分析

    12795 人正在学习 去看看 余海峰

本次分享为笔者在一年半时间里的关于数据挖掘技术在学习和实践方面的经验

由于准备时间仓促和水平有限,有误之处请多多指教



过去的参赛成绩





一般从如下4个方面来做深入分析

一套全自动的数据挖掘工具应该是所有挖掘者的梦想

git上有人开发了一套自动的流程参考:https://github.com/rhiever/tpot




很多同学不太注重预处理,预处理实际上是相当重要的环节

预处理做好了,后面可以省去不少麻烦事

尤其是数据集的划分,一般需要准确模拟线上提交,方便快速迭代想法

聚类一般用来过滤异常值,将业务场景细分等作用

预处理参考:http://blog.csdn.net/bryan__/article/details/51228971



特征工程可以说是整个工程中最为重要的环节

特征没做好,参数调到老

着重根据业务场景来构建特征,注意时间尺度一致,不要使用标签信息来统计特征



使用GBDT和LR可以自动发现组合特征,省去人工构造



特征选择也是重要的一个环节,大量特征会导致训练成本较高,甚至模型跑不出来

总体需要注意的是与标签列相关性高,特征之间冗余度低,避免共线性等等

压缩方法一般对于图像特征效果可能比较好,一般情况的场景效果可能稍差

时间够的话用wrapper吧,能找到效果最好的特征子集,模型自带的特征排序效果也非常不错

特征选择资料参考:http://blog.csdn.net/bryan__/article/details/51607215



分类模型里面,比较常见的是线性模型,决策树模型,SVM超平面间隔模型,神经网络模型

LR和SVM使用前记得先归一化,LR取LOG效果也不错,树模型不用归一化

SVM一般使用线性核和高斯核,调参可以使用自动搜索  核选择和参赛问题参考:http://blog.csdn.net/bryan__/article/details/51506801

这些不同性质的模型可以用来做后面的模型融合

分类模型简单使用参考:http://blog.csdn.net/bryan__/article/details/51288953



回归模型一般也是这些常见的算法,L1和L2区别简单来说是p范数的问题,具体参考:http://blog.csdn.net/bryan__/article/details/51288760


至于规则模型,可以说是难点吧,没有深入理解业务知识不太好掌握,用好了也是大杀器


推荐算法一般主要内容是计算相似度过滤,频繁项挖掘,矩阵分解,图算法等等


文本处理的核心是将文本转换成特征向量,注意tf-idf得到的词在不同文档中值不一样,word2vec得到的词向量在所有文档都一样

如何把word2vec得到的向量变成文档的向量呢?一般是简单采用向量相加然后平均的方法



在现实场景用,数据不平衡是十分常见的问题,一般处理方法是代价敏感,也就是在算法层面增加小类权重

在数据层面一般是采用过采样方法,常见的smote处理比较随意,最好采用我们实验室的基于粗糙集的研究成果,哈哈~

另外不太推荐复制小类样本,周志华都说了不能这样,笔者表示支持


模型融合稍微复杂一点,把握好差异性和多样性融合

差异性是在算法层面,比如树模型和线性模型融合就算是差异性融合

多样性是指在数据,特征,参数等方面的多样性

bagging的优点是减少方差,也就是稳定性好

boosting的优点是减少误差,也就是更准确

stacking的顶层使用线性融合,数据量小的时候容易导致过拟合

ranking针对AUC优化效果不错,使用的是样本的排名来做融合,跟具体得分没啥关系


模型融合的时候需要注意不同模型结果的相关性

如下列举了几种常用的相关性指标,也可以用来做特征选择的时候计算相关性

单独用一种说服力不强,一般是同时跑多个指标来评估相关性

关于如何使用这几种算法参考:http://blog.csdn.net/bryan__/article/details/51607215



下面介绍几种常用的bagging方法,随机森林是比较常用的树模型bagging

在样本,特征,参数,基分类器上随机,然后平均


下面这种是我们之前在参加DC一个比赛夺冠时使用的xgboost bagging

主要是在特征和参数层面的bagging



SVM在处理小样本分类的时候性能强悍,但是随着数据量的增加,SVM有可能会跑不出结果

在数据量大的时候,一般可以采用训练集分解的方式来解决时间复杂度问题

分解为p份时间复杂度降低p倍,当然不能分解太多,不然样本不够导致单模型性能欠佳

如果使用bootstrap来采样的话,那么会有部分样本没被选中,这部分样本可以用来调参


stacking可能理解稍微困难一些,参考:http://blog.csdn.net/bryan__/article/details/51229032

需要注意的是底层模型尽量不要用同质模型

上层模型一般使用LR、NN等线性模型









下面是阿里巴巴ODPS平台的数据分析工具,可以参考下




2017-05-07 00:50:50 u012969412 阅读数 8310
  • Spark快速大数据处理

    课程的主要内容包括: 1.ZooKeeper-分布式过程协同组件 2.Hadoop3-大数据基础组件 3.Tez-Yarn底层计算引擎 4.Hive3-大数据仓库 5.Spark2实时大数据处理 6.Oozie5-大数据流程引擎 课程特点: 1.最新API: Hadoop3/Spark2/Hive3/Oozie5 2.手工搭建集群环境:编译+搭建 3.配套资源:分阶段镜像+课件+安装资源,其中安装资源包括案例源码、脚本等 4.案例为主:分模块案例+天池数据分析竞赛 5.故障教学 6.完整实战项目:天池数据分析

    12795 人正在学习 去看看 余海峰

特此声明:引用白虎QQ群的吉更大神

京东竞赛技术参考汇总


关键字
xgboost
高纬度特征的特征轮
交叉验证
网格搜索调参
单一模型
多模型融合
特征工程
描述统计量

ML指代机器学**,DM指代数据挖掘
DM流程通常分两个阶段
Step1. 数据清洗,数据格式调整
Step2. 特征构建,模型选择,效果评估
Step1.是整个流程中最耗时的,这点想必大家早有耳闻,DM界有句名言 garbage in ,garbage out ,可见清洗数据非常重要。从我的经验看,这部分工作跟实际处理的业务问题关系很大,比较dirty,也没有统一流程,所以本文重点放在Step2.
3. 前期准备
3.1. 数据变换
先把原始数据通过一定变换,变成通用的多列数据类型,作为ML模型的输入,也就是上面的Step1。用X代表样本及其特征集合,y代表样本标签集合,整个流程如下:
 
3.2. 问题分类
根据标签y的不同,可以把DM问题分为以下几类:
二分类问题(这种问题在工业界最为常见,比如广告点击率预估、推荐系统购买行为预测),此时y只有一维,取值只有两个(比如0-1),每个样本有唯一的标签。比如预测广告是否会被用户点击;用户是否会购买某种商品
多分类问题(比如微博用户情感分析、用户对理财产品偏好性分析),通常此时y有多维,每维代表一个类标签,取值只有两个(比如0-1),每个样本有唯一的标签;当然,y也可以只有一维,取值有多个,每个值代表一个类标签。比如通过微博分析出用户情感属于喜怒哀乐等哪类;将理财产品的用户群体分为偏好型/温和型/厌恶型
多标签问题(比如音乐的标签划分),y有多维,跟多分类的区别在于,样本可以同时属于多个标签。作为一枚钢琴爱好者,这里以钢琴作品举例,假设标签集合为{独奏,协奏,浪漫主义,印象主义},最爱之一的德彪西「月光」无疑属于{独奏,印象主义},朗总成名作柴一则可归为{协奏,浪漫主义},云迪家喻户晓的肖邦夜曲是{独奏,浪漫主义},而中国特色的「保卫黄河」可归为{协奏}
单回归问题(比如股价预测),y只有一维,取值为连续值。比如预测阿里明天的股价
多回归问题(比如天气预测),y有多维,取值连续。比如预测明天的气温、空气湿度、降雨量
3.3. 评价指标
预测结果的好坏需要用一些指标来衡量,通常不同类型的DM问题有不同的评价指标。对于二分类问题,很多时候类别本身不均衡(比如正样本很多负样本极少),所以我们通常用AUC值——即ROC曲线下的面积——来评价二分类结果;在多分类或者多标签问题中,我们通常选取评价指标为交叉熵(cross-entropy)或者log损失(log loss);对于回归问题,则可以选用MSE(mean square error)
3.4. 工具
我跟原博客作者一样,提倡使用python解决DM问题,因为python的第三方库非常齐全,以下是常见的、用于DM问题的python库:
pandas: 仿照了R语言的数据结构、数据操作,一般用来做数据预处理,特征工程,其DataFrame数据格式用起来相当便利
scikit-learn: 家喻户晓的ML库,各种聚类、分类、回归模型等,也可以用来做预处理
xgboost: 陈天奇大神的杰作,改进了传统的GBDT模型,在底层用一些trick加速模型训练,非常值得一试,可以取代其他ML库里的GBDT系列模型 (很早就听说过这个碉堡的库,但一直没有上手实践,实在汗颜…后面我会结合GBDT做特征工程,实践下效果,发布到公众号)
keras: 神经网络相关的库,可以选择基于tensorflow或theano,赶脚很强大,我也是刚接触
matplotlib: 作图必备,语言风格跟MATLAB很像,很好上手
tpdm: 我没听过,原作者提到的,感兴趣的童鞋可以了解下
3.5. 开发环境
这里我补充说一下python开发环境和上面几个库的安装方法。首先我跟原作者一样,因为追求自(装)由(逼),所以不用python IDE(比如Anaconda, Pycharm),当然,装IDE可能省很多事情,个人建议安装Pycharm。然后我自己的python开发环境(纯属个人**惯,仅供参考):
windows: notepad++及其插件nppexec/explorer,结合我昨天发布的『一个神奇的脚本,一键运行各类程序』,里面的nppexec脚本可一键执行Python。以及linux风格的shell: git bash (git bash是基于msys的,跟cygwin略有不同)
mac: sublime及其插件Package Control/anaconda,以及iTerm2,或者自带的terminal。(sublime中import某些python库,比如matplotlib/sklearn/tensorflow会出点bug,需要修改下环境变量啥的,遇到相关问题可以微信我,尽量帮你解决)
linux: vim(因为我一般在命令行模式下开发)。如果是界面linux,应该可以有其他选择
另外,jupyter notebook(前身是ipython notebook)是个好东西,可以逐步执行python代码片段,不依赖于平台,可在浏览器中打开,非常适合学**过程中练手。
再说库的安装,首先强烈建议安装64位python2.7,然后针对不同操作系统:
windows[不推荐]: 略蛋疼,64位的库大多没有官方版本,具体安装方式见我之前写过的一篇文章『在Windows下安装64位Python及数据挖掘相关库』(后续我会完善该文,但只发送给指定分组,具体见文末Bonus)。大多数库的安装都类似,但xgboost稍微复杂些,不能直接pip install,而是要装VS来编译其中相关文件,再安装,遇到问题可以微信我。另外tensroflow目前没有windows版本
mac[推荐]: 最新的python2.7一般都自带pip,所以装好python后,直接在terminal中 pip install 相关库就可以了,注意库的依赖关系,一般先安装numpy,scipy,matplotlib,再装其他库
linux[推荐]: 基本跟mac类似
4. DM问题框架
终于到了最核心的部分,原作者总结了一个他参加各类DM比赛常用的ML流程图,真是一图胜千言
 
这里我擅自补充一下,这张图看着眼花缭乱,其实就两点,这两点也是DM比赛中最核心的两点:
特征工程(包括各种离散化、组合、选择)
模型选择、模型融合(即ensemble)
能把这两点做好,实属不易,但其实在工业界,特征工程和模型融合是否需要做到极致,是要看具体问题的。有些业务的数据维度本身就很稀少,并不足以支撑庞大的特征体系;有些业务需要很强的可解释性(比如金融领域),于是很多模型不能直接用;有些业务则要系统的实时性和稳定性,过于复杂的ensemble虽然能提升一点指标,但也许得不偿失。
上图当中的粉色部分是最常用的一些步骤,简单梳理一下:先确定DM问题的类型,然后对数据集划分,接着对常见的数值变量和类别变量做相应处理,可以进行特征选择,最后选择合适的模型做预测,评估模型并输出结果。下面将详细展开。
4.1. 问题定义
首先搞清楚要解决的问题属于哪一类,结合上节所讲,我们一般通过观察y标签类来定义DM问题的类型。
4.2. 数据集划分
在明确了问题的分类后,我们将对数据集划分成训练集(Training Data)和验证集(Validation Data)(补充:很多时候还要划分出测试集(Test Data),先用训练集验证集的交叉验证来寻找模型的最优超参数,模型调优完毕后,最终用测试集来评估模型最终效果,具体参考我之前在公众号发布的『新手数据挖掘中的几个常见误区』第二节)。划分方式如下:
 
这里我用自己本地的一个小数据集(名为toy_data.txt)做展示,获取方式见文末Bonus,加载以上小数据集的代码如下:
import pandas as pd
df = pd.read_csv("toy_data.txt",sep = "\t")
df.head()
运行结果:
 
最后一个字段Label就是我们要预测的y,在我的数据集里取值0或1,所以是一个二分类问题。
对于分类问题,要根据标签来划分数据集,比如每种标签采样多少,这样才能保证训练集跟验证集的样本标签分布接近,另外采样方式也不限于随机采样,可以根据实际业务问题选择合适的采样方式。这里我们可以借助scikit-learn来实现分层的K折交叉验证,代码如下
X = df.ix[:,0:-1]
y = df.ix[:,-1]
from sklearn.cross_validation import StratifiedKFold
kf = StratifiedKFold(y,3) # 三折交叉验证
用以下代码验证一下训练集和验证集中的正样本的占比:
idx_train, idx_valid = next(iter(kf))
print float(sum(y[idx_train]))/len(idx_train)
print float(sum(y[idx_valid]))/len(idx_valid)
结果为0.69713 0.69565,两者非常接近。
注意,不太推荐使用iter(kf),这里只是为了展示标签分布,具体我会在本文第五节『实战』中介绍如何高效地使用交叉验证。
如果是回归问题,则不存在分类问题中类别标签分布不均的情况,所以我们只需采用普通的K折交叉验证即可:
from sklearn.cross_validation import KFold
kf = KFold()
4.3. 特征工程
毫不夸张地说,特征工程是DM重要的一环,也是决定DM比赛的关键因素。纵观DM比赛,几年间已由追求模型是否fancy转向无尽的特征工程,主要得益于越来越标准化的ML模型,以及更好的计算能力。
特征工程可以做的很复杂很庞大,但受限于本人目前的水平,这里只结合原博客内容讲解一些最基本(也是最经典)的处理方法。
4.3.1. 处理类别变量
类别变量(categorial data)是一种常见的变量,在我之前写的『新手数据挖掘中的几个常见误区』 一文的第三节中讨论过为何要对类别变量编码
在toy_data当中,字段Continent, Country, Product, Brand, TreeID, Industry, Saler都可以看做是类别变量。处理类别变量一般是先标签化,然后再二值化编码。标签化的目的是将字段的原始值(如字符串、不连续的数字等)转换成连续的整数值,再对整数值二值化编码,如果原始值是整数,则直接二值化即可
我们拿toy_data前几个样本的Continent字段举例,对其进行编码:
mapper = skp.DataFrameMapper([
('Continent', sklearn.preprocessing.LabelBinarizer()),
])
tempX = df[['Continent']].head()
print tempX
print mapper.fit_transform(tempX.copy())
运行结果如下
 
可以看到,原来的一列Continent字段变成了三列,分别代表[ 'AM', 'EP', 'LA' ],取值1表明是,取值0表明否。这就是常说的one-hot编码。如果类别变量的取值是整数,则直接用sklearn.preprocessing.OneHotEncoder()即可,把上面代码中LabelBinarizer()替换掉
注意我们必须将对训练集上的变换原封不动的作用到测试集,而不能重新对测试集的数据做变换(详见我之前写的『新手数据挖掘中的几个常见误区』第一节)。
4.3.2. 处理数值变量
一般而言,数值变量不用做太多处理,只需做正规化(normalization)和标准化(standardization)即可,分别对应scikit-learn中的Normalizer和StandardScaler。不过对于稀疏变量,在做标准化的时候要注意,选择不去均值。
其实数值型变量最好也进行离散化,离散手段从基本的等距离散法、按分隔点人为指定,到聚类、输入树模型等,手段很多,在此不详细展开,我会在后续文章中提及。
4.3.3. 处理文本变量
文本在实际问题中很常见,比如用户评论、新闻摘要、视频弹幕等等。我们用的toy_data不包含文本变量,所以这里我参考了scikit-learn的文档,一个小的corpus作为我们的训练数据集。
corpus = [
'This is the first document.',
'This is the second second document.',
'And the third one.',
'Is this the first document?',
]
corpus有四句话,可以看做是四个样本。接下来我们先用一个简单的方法处理文本变量——统计corpus中每个词出现次数,代码如下:
from sklearn.feature_extraction.text import CountVectorizer
vectorizer1 = CountVectorizer(min_df=1)
temp1 = vectorizer1.fit_transform(corpus)
print vectorizer1.get_feature_names()
print temp1.toarray() # temp1是sparse类型, 转换成ndarray方便查看
运行结果:
 
第一行是corpus中所有词,下面的ndarray每行代表该词在该样本中出现次数,比如第2行第6列的2代表second这个词在第二句话中出现了2次。一般我们不会直接用这个结果,而是会将每行归一化之类。
这种处理方式简单粗暴,没有考虑词与词之间的关系。我们改进一下这个方法,除了考虑单个词之外,还考虑corpus中成对出现的词(类似NLP里n-gram的 bi-gram,具体请自行Google),代码如下
vectorizer2 = CountVectorizer(ngram_range=(1, 2))
temp2 = vectorizer2.fit_transform(corpus)
print vectorizer2.get_feature_names()
print temp2.toarray()
运行结果:
 
然而,这还不够,像a is this这类的助词、介词等,词频将非常高(在NLP中又叫停止词 stop word),所以需要减小他们的权重。一种做法是,不再简单统计该词在文档中出现的词频,而且还要统计 出现该词的文档的占比,这在NLP中叫tfidf。说的有点绕,具体到我们的例子中可以写成如下表达式:
某单词x的tfidf = x在一个样本中出现的次数/出现x的文档占比
分子即tf,分母即1/idf,有时需要用log sqrt之类的函数作用在tf或者 1/idf上,以减弱某项的影响。同样,我们可以:
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer3 = TfidfVectorizer(ngram_range=(1, 2))
temp3 = vectorizer3.fit_transform(corpus)
print vectorizer3.get_feature_names()
print temp3.toarray()
运行结果:
 
仔细观察不难发现,is this这类的停止词在变换后数值变小了。
!!注意!!跟处理类别变量、数值变量一样,我们在处理文本变量时,必须将训练集上的变换方式原封不动地作用到验证集或测试集上,而不能重新对验证集或者测试集做变换。比如在得到上面的vectorizer3后,我们将其作用在一个新的样本 ['a new sentence']上,代码如下
print vectorizer1.transform(['a new sentence']).toarray()
我们可以看到,结果是 [[0 0 0 0 0 0 0 0 0]],因为这个样本里的三个词从未出现在训练集corpus中,这是正确的结果!
为了方便将变换作用在未来的测试集,我们可以先把vectorizer3用pickle保存到本地,用的时候再load,保存方式如下:
import cPickle as pickle
pickle.dump(vectorizer3, open('vectorizer3.pkl','w'))
用的时候再 vectorizer = pickle.load(open('vectorizer3.pkl','r'))即可。
4.3.4. 特征融合
ToDo 区别对待稠密特征和稀疏特征,
4.3.4. 特征降维
ToDo PCA等
4.3.5. 特征选择
ToDo
4.4. 模型选择和模型融合
ToDo



时间序列和数据挖掘 
前言
首先我们来看下一些常见的数据挖掘场景:
广告点击率预测: 根据用户历史上的浏览、点击、停留时间等行为,预测用户会不会点击该广告
推荐系统: 根据用户历史的购买记录、点击行为,以及商品描述文本、用户画像等等一些系列特征,预测用户未来的购买需求
命名实体识别: NLP (自然语言处理) 的经典问题,识别出一句有序的文本里,特定类别的词组
股价预测: 预测某支股票或某些股票,未来一段时间的价格,或者粗糙一点——涨跌趋势
图像识别: 比如人脸识别、医疗图像分析
视频情感分析: 根据一段视频(可以看做是一系列时间上连续的图像),分析出这个视频表达的情感倾向
我们会发现,这些问题很多都跟『时间序列』有关(除了图像识别),并且也是数据挖掘比赛的常见赛题,以天猫14年的推荐大赛、支付宝15年的资金流入流出预测为例,这俩比赛有非常完整的前十强团队答辩ppt公布,我们会发现,处理这些问题的选手中,主要分俩流派:机器学习流派和统计学流派。14年的天猫推荐大赛是机器学习流派占主流:做特征、训练分类器、模型融合,把时间信息完全融入到特征中去;而15年的支付宝比赛是统计学流派占上风:用各种 AR (auto regression) 模型,从时间维度上建模,直接考虑时间上的连续性。
这些看似迥异的做法,其实都可以归结到一个大的理论中去,而这个理论,正是本文的核心。
基础
首先,我认为所有『有监督学习』问题,本质上都是在建立一个函数映射 f ,可以用一个式子来刻画:
f(X)->Y
这个式子是我自己想的,但其实只要有一定机器学习基础的人,都很容易想到这一点。这里的 X 是样本的特征,Y 是样本的标签,X 可以是向量、矩阵甚至多维矩阵,相应的,Y 可以是单个标签,也可以是一组标签。我们待会儿结合实例讲讲 X 和 Y 在具体情形下的具体形式
于是:
按照 Y 的取值是连续的,还是离散的,可以把有监督学习问题分为『回归』和『分类』,可以参考我的前作『分类和回归的本质』,给你一个不同的视角看待经典问题。
按照 Y 是单个标签,还是前后有关联的序列化标签,可以把有监督学习问题分为『时间序列』和『非时间序列』问题,而本文今天的主角,就是这个『时间序列』
上面两种划分方式的两两组合,会产生四种情况,比如:时间序列的回归问题,非时间序列的分类问题,等等。这四种情况基本涵盖了所有的机器学习模型,或者说,所有实际问题,都可以通过各种方式,最后转化成这四种情况里的一种。
其实,严格来讲,『时间序列』这个说法并不准确,比如在 NLP 中,一句话的每个单词组成一个序列,但他们并不代表有时间标签,只是有前后关系,所以这类问题其实叫『事件序列(event sequences)』。我们在本文当中为了简单起见,将这种带有前后顺序关系的序列,统称为『时间序列』,特此声明。
正文
接下来,我们将正式探讨『时间序列』问题的常见处理手段
从统计学的角度
处理时间序列最自然的方法,莫过于 AR 系列的模型 (ARIMA, ARMAX, …), 以及我之前在一篇很水的论文里用过的一阶马尔可夫链模型。这类模型的的最大特点,就是直接从预测变量 Y 的角度来考虑问题,比如现在要预测 y(T),比如T 时刻的股价,那我们就会用 {y(1),…,y(t)…, y(T-1) } 这些历史信息,做一阶差分、二阶差分、均值、方差等等等,得到各种统计量(有点特征工程的意思),然后来预测 y(T)。这种模型有两个显而易见的弊端:
只用到了预测变量本身,无法利用到其他信息如影响股价的政策因素等(不过统计学里已经有一些模型在 handle 这类问题了)
看似在时间维度上建立模型,但其实是用以往的记录分别来预测 y(T), y(T+1),…, 并没有考虑这些预测变量本身的时间相关性
能处理的历史记录时长有限
从经典机器学习的角度
依然是预测 y(T) ,这时候我们会对利用上所有的其他变量 X,比如上面说的,影响股价的政策因素等,而且与统计学的做派不同,我们也对历史记录提取不同的特征,但我们并不 care 是哪类统计量,比如什么一阶差分啥的,也不太 care 统计指标,我们只管拼命做特征,开脑洞做特征,用 CNN 自动做特征,反正就是特征工程搞得飞起,然后得到一个庞大无比的 X,用来预测 y(T)。其实不难发现,这种做法,就是我们在上一节提到的『非时间序列问题』,即把一个本来是『时间序列』的问题,转换成非时间序列问题。这种做法的好处是通过完善的特征工程,我们能把过去历史信息尽可能多地建模在 X 里,当然弊端也很明显,跟 AR 系列模型一样。
割裂了 y(T), y(T+1) 之间的时间相关性
处理的历史记录的时长有限
从RNN等模型的角度
先总结下,前面两种处理『时间序列』的方法,看似杂乱无章,实则可以简洁地纳入我们上一节提到的公式
f(X)->Y
具体到单个样本的预测,就是
f( X(T) ) -> Y(T)
比如,在统计学的方法中,那些从 {y(1),…,y(t)…, y(T-1) } 历史记录上提取的特征,其实就是这里的 X(T);而在经典机器学习方法中,我们脑洞打开所做的各类特征,依然可以归结为—— X(T)。
所以问题就来了,既然这两大类方法,都割裂了 y 之间的时间相关性,那有没有一个『大一统』模型能建立 y 之间的相关性呢? 我们转化成数学语言就是
f( X(1), X(2), …, X(T) ) -> Y(1), Y(2), …, Y(T)
这样,上面的 f( X(T) ) -> Y(T) 就可以看做是它的一个特例,即当样本只包含一个时间点的时候。
答案是肯定的,这样的模型是存在的,那就是——RNN,HMM,CRF 等等,这类模型在建模时显示地建立了 Y 之间的关系。但一般情况下,HMM、CRF 会有马尔可夫性假设,直白地说就是假设 Y(T) 只跟 Y(T-1) 有关系,所以相比而言,从理论上看,RNN 更完美(注意,只是理论上讲,具体效果还要看实际应用),而且,RNN 理论上能处理无限时长的时间序列,即上面的 T 可以无穷大,但因为训练时梯度在时间维度上的连乘操作,RNN 存在梯度消失和爆炸的风险,取而代之的是 GRU, LSTM 等,这又是另一个话题了,在此不表。
好,下面我们用更浅显明白的语言,来叙述这个『大一统』框架。这时候我们不得不搬出这张神图了:


这张图阐释了 RNN 所能处理的所有可能情形,绿色框是 RNN 模型,红色是 输入 X, 蓝色是预测目标 Y。我们重点关注第一个 one to one 和 最后一个many to many。不难发现,对于非时间序列模型,他们看待『时间序列』的角度是单一的,即他们建立的是针对样本 (x(T),y(T))的映射,就是这里的 one to one,而在时间序列模型里,一个样本天然的是 (sequenceX, sequenceY ),这里的 sequenceX 就是上面公式里的 X(1), X(2), …, X(T),同理 sequenceY 是 Y(1), Y(2), …, Y(T),对应的就是 many to many 的情形。
不过这里要提一下两个重要的补充
尽管理论上 RNN 可以建模无穷时间序列,可以处理不同时间长度的样本,不需要像其他方法一样,只能统计一个时间窗口内的历史信息,但在实际工程实现上,还是要尽量统一历史时间步长的,否则将对编程造成很大麻烦,这点在 Keras, Tensorflow, Theano 等框架里都有体现。
虽然把 统计学方法 和 经典机器学习方法 都纳入了这个『大一统』框架,看做是一个特例,但其实,RNN 并不需要像他们一样,做很复杂的特征工程,因为这些工作早已隐含在神经网络的各个非线性模块的各种映射里(这也是为什么说 神经网络能自动提取特征),并嵌入到了隐层输出 h 中,作为下一时刻的输入,所以下一个时刻的输入 X(T) 可以不用做那么多特征工程,这正是神经网络吸引人的地方。
一点发散
写到这儿的时候,我的脑子里突然闪过研究生期间学的『预测控制』理论。预测控制就是利用以往的系统状态、输出信号,来生成未来 N 步的控制率,但区别在于,这里的模型是已知的线性或非线性模型,所以是一种『机理建模』,而用 RNN、RF、GBDT 等,则是完全的数据驱动的黑箱建模。
总结
虽然讨论的是『时间序列』问题,但其实是借助 RNN 模型的理念,把处理所有『有监督学习』问题的思路都理清了
当处理的是非时间序列问题时(比如人脸识别),收集到的是一系列样本 (X, Y),只要建立 f(X) -> Y 的映射。X可以做特征工程,也可以交由 CNN 这类模型自动学出来
当样本是时间序列时,有两种做法:
仿照非时间序列问题的处理方法,收集一系列样本 (X(t),Y(t))建立 f(X(t))->Y(t) 的映射,但其实是『大一统』框架的一个特烈
更通用的『大一统』框架,则是从 RNN 的角度看待这个问题,建立 f( X(1), X(2), …, X(T) ) -> Y(1), Y(2), …, Y(T) 的映射
额外补充一点:在图像处理、语音识别中,输入特征的维度(像素点、语音波形)之间的相关度很大,可以交给神经网络自动提取特征,而在推荐系统、nlp等问题中,输入特征的维度(user的id、性别、年龄、词的词形)之间的相关性并不那么强,所以神经网络提取特征的效果,未必比得上人工特征。我认为这就是为何深度学习最先在语音和图像领域打开市场的主要原因。
十大误区:
 1
  太关注训练(Focus on Training)
  就像体育训练中越来越注重实战训练,因为单纯的封闭式训练常常让训练时状态神勇,比赛时却一塌糊涂。
  实际上,只有样本外数据上的模型评分结果才真正有用!(否则的话,直接用参照表好了!)
  例如:
癌症检测(Cancer detection):MD Anderson的医生和研究人员(1993)使用神经网络来进行癌症检测,惊奇地发现,训练时间越长(从几天延长至数周),对训练集的性能改善非常轻微,但在测试集上的性能却明显下降。
机器学习或计算机科学研究者常常试图让模型在已知数据上表现最优,这样做的结果通常会导致过度拟合(overfit)。
  解决方法:
解决这个问题的典型方法是重抽样(Re-Sampling)。重抽样技术包括:bootstrap、cross-validation、jackknife、leave-one-out…等等。
 
  2
  只依赖一项技术(Rely on One Technique)
  这个错误和第10种错误有相通之处,请同时参照其解决方法。没有对比也就没有所谓的好坏,辩证法的思想在此体现无疑。
  “当小孩子手拿一把锤子时,整个世界看起来就是一枚钉子。”要想让工作尽善尽美,就需要一套完整的工具箱。
  不要简单地信赖你用单个方法分析的结果,至少要和传统方法(比如线性回归或线性判别分析)做个比较。
  研究结果:
  按照《神经网络》期刊的统计,在过去3年来,只有1/6的文章中做到了上述两点。也就是说,在独立于训练样本之外的测试集上进行了开集测试,并与其它广泛采用的方法进行了对比。
  解决方法:
使用一系列好的工具和方法。(每种工具或方法可能最多带来5%~10%的改进)。
 
  3
  提错了问题(Ask the Wrong Question)
  一般在分类算法中都会给出分类精度作为衡量模型好坏的标准,但在实际项目中我们却几乎不看这个指标。为什么?因为那不是我们关注的目标。
  (1)项目的目标:一定要锁定正确的目标
  例如:
欺诈侦测(关注的是正例)(长途电话上的分析):不要试图在一般的通话中把欺诈和非欺诈行为分类出来,重点应放在如何描述正常通话的特征,然后据此发现异常通话行为。
  (2)模型的目标:让计算机去做你希望它做的事
  大多数研究人员会沉迷于模型的收敛性来尽量降低误差,这样让他们可以获得数学上的美感。但更应该让计算机做的事情应该是如何改善业务,而不是仅仅侧重模型计算上的精度。
  4
  只靠数据来说话(Listen (only) to the Data)
  “让数据说话”没有错,关键是还要记得另一句话:兼听则明,偏听则暗!如果数据+工具就可以解决问题的话,还要人做什么呢?
  (1)投机取巧的数据:数据本身只能帮助分析人员找到什么是显著的结果,但它并不能告诉你结果是对还是错。
  (2)经过设计的实验:某些实验设计中掺杂了人为的成分,这样的实验结果也常常不可信。
 
  5
  使用了未来的信息(Accept Leaks from the Future)
  看似不可能,却是实际中很容易犯的错误,特别是你面对成千上万个变量的时候。认真、仔细、有条理是数据挖掘人员的基本要求。
预报(Forecast)示例:预报芝加哥银行在某天的利率,使用神经网络建模,模型的准确率达到95%。但在模型中却使用了该利率作为输入变量。
金融业中的预报示例:使用3日的移动平均来预报,但却把移动平均的重点设在今天。
  解决方法:
要仔细查看那些让结果表现得异常好的变量,这些变量有可能是不应该使用,或者不应该直接使用的。
给数据加上时间,避免被误用。
  6
  抛弃了不该忽略的案例(Discount Pesky Cases)
  到底是“宁为鸡头,不为凤尾”,还是“大隐隐于市,小隐隐于野”?不同的人生态度可以有同样精彩的人生,不同的数据也可能蕴含同样重要的价值。
  异常值可能会导致错误的结果(比如价格中的小数点标错了),但也可能是问题的答案(比如臭氧洞)。所以需要仔细检查这些异常。
  研究中最让激动的话语不是“啊哈!”,而是“这就有点奇怪了……”
  数据中的不一致性有可能会是解决问题的线索,深挖下去也许可以解决一个大的业务问题。
  例如:
  在直邮营销中,在对家庭地址的合并和清洗过程中发现的数据不一致,反而可能是新的营销机会。
  解决方法:
可视化可以帮助你分析大量的假设是否成立。
 
  7
  轻信预测(Extrapolate)
  依然是辩证法中的观点,事物都是不断发展变化的。人们常常在经验不多的时候轻易得出一些结论。即便发现了一些反例,人们也不太愿意放弃原先的想法。
  维度咒语:在低维度上的直觉,放在高维度空间中,常常是毫无意义的。
  解决方法:
进化论。没有正确的结论,只有越来越准确的结论。
  8
  试图回答所有问题(Answer Every Inquiry)
  有点像我爬山时鼓励自己的一句话“我不知道什么时候能登上山峰,但我知道爬一步就离终点近一步。”
  “不知道”是一种有意义的模型结果。
  模型也许无法100%准确回答问题,但至少可以帮我们估计出现某种结果的可能性。
  9
  随便地进行抽样(Sample Casually)
  (1)降低抽样水平。例如,MD直邮公司进行响应预测分析,但发现数据集中的不响应客户占比太高(总共一百万直邮客户,其中超过99%的人未对营销做出响应)。于是建模人员做了如下抽样:把所有响应者放入样本集,然后在所有不响应者中进行系统抽样,即每隔10人抽一个放入样本集,直到样本集达到10万人。但模型居然得出如下规则:凡是居住在Ketchikan、Wrangell和Ward Cove Alaska的人都会响应营销。这显然是有问题的结论。(问题就出在这种抽样方法上,因为原始数据集已经按照邮政编码排序,上面这三个地区中不响应者未能被抽取到样本集中,故此得出了这种结论)。
  解决方法:“喝前摇一摇!”先打乱原始数据集中的顺序,从而保证抽样的随机性。
  (2)提高抽样水平。例如,在信用评分中,因为违约客户的占比一般都非常低,所以在建模时常常会人为调高违约客户的占比(比如把这些违约客户的权重提高5倍)。建模中发现,随着模型越来越复杂,判别违约客户的准确率也越来越高,但对正常客户的误判率也随之升高。(问题出在数据集的划分上。在把原始数据集划分为训练集和测试集时,原始数据集中违约客户的权重已经被提高过了)
  解决方法:
先进行数据集划分,然后再提高训练集中违约客户的权重。
 
  10
  太相信最佳模型(Believe the Best Model)
  还是那句老话-“没有最好,只有更好!”
  可解释性并不一定总是必要的。看起来并不完全正确或者可以解释的模型,有时也会有用。
  “最佳”模型中使用的一些变量,会分散人们太多的注意力。(不可解释性有时也是一个优点)
  一般来说,很多变量看起来彼此都很相似,而最佳模型的结构看上去也千差万别,无迹可循。但需注意的是,结构上相似并不意味着功能上也相似。
  解决方法:
把多个模型集装起来可能会带来更好更稳定的结果。
【1. 特征变换】
(特别感谢 @寒小阳 @retanoj )


误区:
对训练集和测试集分别做变换,比如标准化、归一化、降维等


正解:
此误区是如此之习以为常,以至于已写进 libsvm 的官方文档(http://www.csie.ntu.edu.tw/~cjlin/papers/guide/guide.pdf)的某一节中:
 
事实上测试集的特征变换,应该使用跟训练集同样的因子(均值、标准差、PCA的变换矩阵w等等),我个人的直观理解是,这样能保证变换后的测试集样本与训练集样本处于同一个样本空间,从而基于训练集样本空间的 model,在测试集上也 work(更深层的可能涉及 learning theory,希望能有高人作补充)


有个简单的例子可以辅助理解:
现有总体样本 x={-1,1, 7,9},对应标签y={0,1,1,1},我们可以认为分类器为:
f(x>=0)=1
f(x<0)=0
若现令训练集为 x={-1,1},y={0,1},要预测测试集 x={7,9}的标签值
训练集的均值=0,所以做去均值变换后还是 x={-1,1},我们基于训练集能训练出上述的分类器。此时对测试集做变换,如果我们采用训练集的均值(=0),则 测试集没变化,用上述分类器能准确预测出 y={1,1},但如果我们对测试集去除其自身的均值(=(7+9)/2=8),我们将得到变换后的测试集 x={-1,1},采用上述分类器,将得到 y={0,1},显然预测失准




【2. Cross Validation】
(特别感谢 @寒小阳 @面包包包包包包)


误区:
CV (Cross Validation) 训练出来的最优模型,可以直接用于线上预测
正解:
CV只是确定了模型的最优超参数(就是没法通过模型学习、只能手动调整或者grid search之类的那类参数,像svm的gamma和c,kmeans的聚类数k、LDA的alpha和beta)
一旦 model 的最优超参数通过cv确定下来之后,还要再次对 model 用整个线下数据集做 training,然后将 model 用于线上预测
具体做法可以参考下图
 


【3. Dummy Variables】
( 特别感谢 @Matrix  @chrispy  @被吓坏的煜儿 )


误区:
处理类别特征的时候(比如类别:“color”={red, green, blue}),直接对不同类别赋予不同数值(比如:1,2,3),并把“季节”特征直接扔到模型里


正解:
对于无序类别特征(比如“color”),本身不存在数值上的大小关系,所以最好不要直接对其赋值,而是将类别特征“因子化”,变成“Dummy Varaibles”(这种处理手段也叫 one-hot),从一个特征("color")变成三个0-1特征(“是否red”,“是否green”, “是否blue”)
 
对于有序类别特征,(比如我在支付宝处理的购买力模型,有个特征是“城市等级”={1,2,3,4}),也可以用同样的方法因子化。
这么做的原因是什么呢?因为对于大部分模型,尤其是线性模型,对数值类特征都比较敏感,无法挖掘非线性关系。我们不妨以 LR 为例,假如我们给  color = {green, red, blue} 分别赋予 {1,2,3},而标签是 {冷色,暖色},显然对于 color 而言,这是个非线性映射, 数值为 1 和 3 时是冷色,2 是暖色,但 LR 训练的结果,只能给 color 这个特征赋予同一个权重 w,所以无法得到这种非线性关系,但若将 color 像上面提到的那样因子化,那我们训练出的 LR,可以给 red 赋予正向的权重, blue 和 green 赋予负向的权重,从而得到这种单个特征上的非线性映射。
不过对于决策树系列的模型,也许因子化就不十分必要了,因为决策树能学出非线性分割面,同样对 color 分 暖色、冷色的问题,也许决策树能学西出:
if color<=1 
y=冷色
else if 1<color<=3
y=暖色
else
y=冷色
优雅高效地数据挖掘:基于Python的sklearn_pandas库
来源:数据挖掘机养成记 时间:2016-08-31 14:17:19 作者:穆文
目录
前言
1. 关于DataFrameMapper
2. 用DataFrameMapper做特征工程
2.2. 单列变换
2.3. 多列变换
2.3.1. 多列各自用同样的变换
2.3.2. 多列整体变换
2.4. 对付稀疏变量
2.5. 保留指定列
2.6. 自定义列变换
2.7. 小小的总结
3. 实战
3.1. 数据探查
3.1.1. 缺失值处理
3.1.2. 长尾特征
3.2. 特征工程
3.2. 交叉验证
3.3. 预测
4. 思考
5. 参考资料
打赏
Bonus
前言
在数据挖掘流程中,特征工程是极其重要的环节,我们经常要结合实际数据,对某些类型的数据做特定变换,甚至多次变换,除了一些常见的基本变换(参考我之前写的『数据挖掘比赛通用框架』)外,还有很多非主流的奇技淫巧。所以,尽管有sklearn.pipeline这样的流水线模式,但依然满足不了一颗爱折腾数据的心。好在,我找到了一个小众但好用的库——sklearn_pandas,能相对简洁地进行特征工程,使其变得优雅而高效。
目前这个项目还在维护,大家有什么想法可以到 sklearn_pandas 的 github 主页提问题,以及获取最新的版本。
1. 关于DataFrameMapper
sklearn_pandas 起初是为了解决这样一个问题:在 sklearn 的旧版本中,很多常见模块(特征变换器、分类器等)对 pandas 的DataFrame类型不支持,必须先用DataFrame自带的 .values、.as_matrix之类的方法,将DataFrame类型转换成 numpy 的ndarray类型,再输入到 sklearn 的模块中,这个过程略麻烦。因此 sklearn_pandas 提供了一个方便的转换接口,省去自己转换数据的过程。
但当我花了几天时间探索了 sklearn_pandas 的库及其跟 pandas、sklearn 相应模块的联系后,我发现 sklearn 0.16.0 向后的版本对 DataFrame的兼容性越来越好,经我实际测试,现在最新的 0.17.1 版本中, model、preprocessing等模块的大部分函数已完全支持 DataFrame 类型的输入,所以我认为:
sklearn_pandas 的重点不再是数据类型转换,而是通过其自创的DataFrameMapper 类,更简洁地、把 sklearn 的 transformer灵活地运用在 DataFrame 当中,甚至可以发挥你的聪明才智,将几乎大部分特征变换在几行代码内完成,而且一目了然。
sklearn_pandas 官方文档提供的例子比较少,我看了下它的源码,有以下重要发现
DataFrameMapper 继承自 sklearn 的 BaseEstimator 和 TransformerMixin ,所以 DataFrameMapper 可以看做 sklearn 的 TransformerMixin 类,跟 sklearn 中的其他 Transformer 一样,比如可以作为 Pipeline 的输入参数
DataFrameMapper 内部机制是先将指定的 DataFrame 的列转换成 ndarray 类型,再输入到 sklearn 的相应 transformer中
DataFrameMapper 接受的变换类型是 sklearn 的 transformer 类,因而除了 sklearn 中常见的变换 (标准化、正规化、二值化等等)还可以用 sklearn 的 FunctionTransformer 来进行自定义操作
本文先介绍下如何用DataFrameMapper类型进行特征工程,再将 skleanr_pandas、sklearn、pandas 这三个库结合,应用到一个具体的数据挖掘案例中。
2. 用DataFrameMapper做特征工程
[注意]在正式进入本节前,建议先阅读本人之前写的『[scikit-learn]特征二值化编码函数的一些坑』,了解 sklearn 和 pandas 常见的二值化编码函数的特性和一些注意点。
若输入数据的一行是一个样本,一列是一个特征,那简单的理解,『特征工程』就是列变换。本节将讲解如何用DataFrameMapper结合 sklearn 的Transformer类,来进行列变换
首先import本文将会用到的所有类(默认已装好 scikit-learn, pandas, sklearn_pandas 等库)
import random
import sklearn
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# frameworks for ML
from sklearn_pandas import DataFrameMapper
from sklearn.pipeline import make_pipeline
from sklearn.cross_validation import cross_val_score
from sklearn.grid_search import GridSearchCV
# transformers for category variables
from sklearn.preprocessing import LabelBinarizer
from sklearn.preprocessing import MultiLabelBinarizer
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
# transformers for numerical variables
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import Normalizer
# transformers for combined variables
from sklearn.decomposition import PCA
from sklearn.preprocessing import PolynomialFeatures
# user-defined transformers
from sklearn.preprocessing import FunctionTransformer
# classification models
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
# evaluation
from sklearn.metrics import scorer
我们以如下的数据为例
 
 
2.2. 单列变换
『单列』可以是 1-D array,也可以是 2-D array,为了迎合不同的 transformer,但最终输出都是 2-D array,具体我们看以下例子
 
 
我们分别对这三列做了二值化编码、最大最小值归一化等,但要注意,OneHotEncoder接受的是 2-D array的输入,其他是 1-D array,具体请参考我之前写的『[scikit-learn]特征二值化编码函数的一些坑』。上面代码的运行结果如下
 
 
分别对应三种变换,前三列和后五列是pet和age的二值化编码,第四列是age的最大最小值归一化。
同样,我们也可以将这些变换『级联』起来(类似 sklearn 里的pipeline):
 
 
将age列先最大最小值归一化,再标准化,输出结果:
array([[ 0.20851441],
[ 1.87662973],
[-0.62554324],
[-0.62554324],
[-1.4596009 ],
[-0.62554324],
[ 1.04257207],
[ 0.20851441]])
2.3. 多列变换
除了上面的单列变换,DataFrameMapper也能处理多列
2.3.1. 多列各自用同样的变换
有时候我们要对很多列做同样操作,比如二值化编码、标准化归一化等,也可以借助于DataFrameMapper,使得执行更高效、代码更简洁。
 
 
这里同时对age和salary进行归一化,结果如下
 
 
同样,这些变换也可以级联
 
 
2.3.2. 多列整体变换
多列变换时,除了分别对每列变换,我们有时还需要对某些列进行整体变换,比如 降维(PCA, LDA) 和 特征交叉等,也可以很便捷地借助DataFrameMapper实现
 
 
以上我们对age和salary列分别进行了 PCA 和生成二次项特征
2.4. 对付稀疏变量
(写完此文后发现该功能并不是很work)
sklearn 中OneHotEncoder类和某些处理文本变量的类(比如CountVectorizer)的默认输出是 sparse类型,而其他很多函数输出是普通的 ndarray, 这就导致数据拼接时可能出错。为了统一输出,DataFrameMapper提供sparse参数来设定输出稀疏与否,默认是False。
2.5. 保留指定列
(稳定版 1.1.0 中没有此功能,development 版本中有 )
从上面的实验中我们可以看到,对于我们指定的列,DataFrameMapper将忠诚地执行变换,对于未指定的列,则被抛弃。
而真实场景中,对于未指定的列,我们可能也需要做相应处理,所以DataFrameMapper提供default参数用于处理这类列:
False: 全部丢弃(默认)
None: 原封不动地保留
other transformer: 将 transformer 作用到所有剩余列上
2.6. 自定义列变换
不难发现,上面我们利用DataFrameMapper所做的列变换,大多是调用sklearn中现有的模块(OneHotEncoder,MinMaxEncoder, PCA 等),那如果遇到一些需要自己定义的变换,该怎么做呢?比如常见的对长尾特征做log(x+1)之类的变换?
对 sklearn 熟悉的同学开动一下脑筋,答案马上就有了——那就是FunctionTransformer,该函数的具体参数细节可参考 sklearn 的官方文档,这里简单给个例子
 
 
以上我们将 numpy 中的函数log1p(作用等同于log(x+1))通过FunctionTransformer包裹成一个 sklearn 的transformer类,就能直接作用在不同列上啦。
动手能力强的同学还可以自己定义函数,提示一下,用 numpy 的ufunc,这里就不赘述了,留给大家探索吧。
2.7. 小小的总结
基于以上内容,以及我对 sklearn、pandas 相关函数的了解,我总结了以下对比表格:
 
 
至此,DataFrameMapper 的精髓已悉数传授,想必大家已摩拳擦掌跃跃欲试了吧。OK,接下来进入实战!
3. 实战
在进入实战前,先结合本人前作——『新手数据挖掘的几个常见误区』,简单梳理一下数据挖掘的流程:
数据集被分成训练集、验证集、测试集,其中训练集验证集进行交叉验证,用来确定最佳超参数。在最优参数下,用整个训练集+验证集上进行模型训练,最终在测试集看预测结果
我们这里结合一个实际的业务数据集来进行流程讲解。首先加载数据集
 
 
数据集字段如下
这是一个常见的时间序列数据集,所以我们按照时间上的不同,将其划分为训练集(1~5月)和测试集(6月)
 
                                                                   
3.1. 数据探查
3.1.1. 缺失值处理
常见的缺失值处理手段有          
填充
丢弃
看做新类别
我们先简单统计一下每个字段的空值率
 
 
这组数据比较理想,只有Saler字段是缺失的,所以我们只需要看下Saler和目标变量之间的关系
 
 
结果如下
 
 
以上结果表明空值对预测结果似乎有些影响,所以我们暂且将空值看做一类新的类别:
 
 
3.1.2. 长尾特征
长尾分布也是一种很常见的分布形态,常见于数值类型的变量,最简单的方法是用log(x+1)处理。在我们的数据集当中,Cost这个字段便是数值类型,我们看下它的分布:
 
 
log 变化的效果还是不错的,变量的分布相对均衡了。
3.2. 特征工程
通过上面简单的数据探查,我们基本确定了缺失值和长尾特征的处理方法,其他类别变量我们可以做简单的 One-hot 编码,整个策略如下
 
 
在确定好特征工程的策略后,我们便可以上我们的大杀器——DataFrameMapper了,把所有的变换集成到一起
 
 
3.2. 交叉验证
特征工程完毕后,便是交叉验证。交叉验证最重要的目的是为了寻找最优的超参数(详见本人前作『新手数据挖掘的几个常见误区』),通常我们会借助 sklearn 中的KFold ,train_test_split, metric.score等来进行交叉验证,这里简化起见,我们直接用 GridSearchCV,但要注意的是,GridSearchCV对FunctionTransformer类的支持不好,尤其有 lambda 函数时。所以为简化起见,我们注释掉上面使用了 lambda 函数的FunctionTransformer类(有兴趣的同学可以尝试抛弃GridSearchCV,手动进行交叉验证)。
这里我们选用最常见的LogisticRegression,并调整它的超参数——正则系数C和正则方式penalty(对此不熟悉的同学赶紧补下『逻辑回归』的基础知识)。同时如前面所讲,我们用pipeline把特征工程和模型训练都流程化,输入到GridSearchCV中:
 
 
我们定义了三折交叉验证(cv = 3),并选用准确率(scoring = ‘accuracy’)作为评估指标,运行结果如下:
 
 
最佳超参数是取 L2 正则,并且正则系数为 0.1
3.3. 预测
在得到模型的最优超参数后,我们还需要在训练集+验证集上进行特征变换,并在最优超参数下训练模型,然后将相应特征变换和模型施加到测试集上,最后评估测试集结果。
而现在,这一系列流程被GridSearchCV大大简化,只需两行代码即可搞定:
 
 
最后结果为0.6166666666666667,即测试集上的分类准确率。
4. 思考
行文至此,洋洋洒洒千言,但依然只是完成了数据挖掘中最基本的流程,所做的特征变换和选用的模型也都非常简单,所以还有很大的提升空间。
此处以下留两个点,可以动手实践,也欢迎在群里探讨(群二维码见第6节『Bonus』)
当选用的 model 不是 sklearn 中的模块时(比如 xgboost),特征工程还可以用 sklearn_pandas 的 DataFrameMapper, 但 sklearn 中傻瓜模式的 pipeline 就无从作用了,必须自己搭建 cross validation 流程
bad case 也有分析的价值
从单模型到模型的 ensemble
5. 参考资料
sklearn_pandas 官方文档、源码及 github 上的 issues
pandas、scikit-learn 官方文档
寒小阳的博客(http://blog.csdn.net/han_xiaoyang/article/details/49797143)
2020-03-24 19:34:17 Candylx 阅读数 32
  • Spark快速大数据处理

    课程的主要内容包括: 1.ZooKeeper-分布式过程协同组件 2.Hadoop3-大数据基础组件 3.Tez-Yarn底层计算引擎 4.Hive3-大数据仓库 5.Spark2实时大数据处理 6.Oozie5-大数据流程引擎 课程特点: 1.最新API: Hadoop3/Spark2/Hive3/Oozie5 2.手工搭建集群环境:编译+搭建 3.配套资源:分阶段镜像+课件+安装资源,其中安装资源包括案例源码、脚本等 4.案例为主:分模块案例+天池数据分析竞赛 5.故障教学 6.完整实战项目:天池数据分析

    12795 人正在学习 去看看 余海峰

标题EDA部分心得体会

   首先EDA是探索性数据分析的缩写,顾名思义,主要目的就是对拿到的数据进行清洗、分析等工作,也是比赛中的第一步,也是很重要的一步,因为你对数据的理解将直接影响到你的上限,直接影响后面的特征工程那部分,直接影响结果,在拿到赛题数据后,我们要大致了解一下数据,比如你的DataFrame是几行几列的啊,有没有缺失值,有没有异常值,查看每列的存在nan情况,异常值检测,比如价格那列有没有负数等等,先对数据本身有一个大致的了解,你要知道这些数据大致表达了什么,然后你就要知道数据的结构特征,比如数据之间有没有什么联系等,然后就是统计一下缺失值的数量,如果数量多我们要考虑是否舍弃这个特征,如果确实少的话需要填补,是简单填补,还是用什么模型填补,比如随机森林等,然后大致了解下预测值的分布,查看总体分布概况(无界约翰逊分布等),查看skewness and kurtosis,因为想让其符合正态分布,数据有可能右偏,也有可能左偏。再查看预测值的具体频数,再看一下特征的分类情况,特征可分为类别特征和数字特征,并对类别特征查看unique分布,提取出所有数字特征,为下一步分析做准备。
   然后就是绘图部分,图的类型有很多种,比如时序图--查看变化规律,直方图--查看数据分布情况,密度曲线--查看分布情况,箱型图--查看数据异常情况,以及不同数据间的对比分析,小提琴图--进阶版的箱型图,可以查看某个值附近的概率分布。
   接下来是量化方法,首先是相关性分析,分为定类变量、定序变量、定距变量,然后就是独立性分析,看看变量间有无线性相关性,或许还会存在非线性相关等,MV  test独立性检验。
   在分析数据的过程中可以用可视化的方式展示一些数据存在的问题,以及某些特征之间的联系等,代码部分我就不一一赘余了,等这个比赛结束,我会将我的比赛代码上传到github上,欢迎大家阅读。
没有更多推荐了,返回首页