赛后复盘 - DataCastle 科大讯飞AI营销算法大赛

最近这个月参加了DataCastle上的科大讯飞AI营销算法大赛,最后的名次是97 / 1086,没能进入复赛(要求前50名)。其实也没什么好失落的,已经尽力了,这就是我现阶段的真实水平。最大的遗憾,应该是比赛结束前三天才知道这个比赛竟然有交流用的QQ群!感觉错过了一个亿!这段时间里总是在想,DataCastle这个平台怎么做得这么差,竞赛圈里没有人发帖,没有交流,只能靠自己和队友埋头苦干。后来才知道原来大家天天都在群里交流心得。。唉,生活就是遗憾的艺术吧。

Anyway,还是有一些收获的,写篇博客复盘一下。等复赛的最后结果开源之后,应该会有更多的收获吧,到时候再更新一下。


一些自问自答

  • 似乎这一个月里其实也没做多少内容?

是的。我原本以为自己投入了很多的精力,做了很多事情,今天写完博客之后才发现,其实也没做什么。可能是在给将来积累知识和经验吧,终究是能够用得上的,避免今后掉进相同的坑里。

  • 有没有学到什么关于广告业务的知识?

并没有。我到今天都不知道数据特征里的创意(creative)和一级频道(f_channel)到底指的是什么,而且这个比赛的所有变量都是脱敏过后的,能看到的都是一堆乱码,都是诸如ag_2100040,724495373286, B4734117F3 这样的数据,场景的代入感很差。我也不必要知道某个变量是什么意思,知道它是categorical feature还是numeric feature就够了。

我并不知道该怎么样把广告的点击率给提升上去,我所做的事情,更多是找到一种判断方法,判断什么样的广告点击率高,什么样的广告点击率低,仅此而已。

  • 写代码的水平有没有提升?

有提升,但提升不大。虽然我写的代码有一千多行,但都很简单,就是些常见的pandas的操作罢了。要说有什么新的,应该是学了一下python中的try..except...以及continuenext等语句的写法。之前参加kaggle的home credit default risk竞赛的时候,接触到了一些大型的工程,十个py文件,四千多行代码,层层叠叠的复杂依赖关系,这次比赛里没有用到,因为数据量小,我觉得没啥必要,徒增麻烦。

  • 对特征工程有什么新的理解?

似乎生成新的特征并不需要对实际业务有多么深刻的理解,常见的套路就是求各种各样的统计量,count/ unique/ sum/ mean/ var等等,如此种种,感觉就是暴力一把梭,把所有的可能都给枚举出来,穷尽各种可能,然后用高性能的机器去遍历,寻找出好的特征。当然,我的这个理解可能是错的,因为我并不擅长创造新特征,我的想象力太差了,希望这个比赛最终结束之后能有新的观点吧。

  • 为什么要参加比赛?
    • 可以把平时学习的东西综合应用到实际中,能强化理解,能锻炼自己;
    • 有利于自己实现转行,打比赛的时候别人才不管你是什么学科背景的呢,提交分数高才是王道;
    • 比赛的数据都是来自于真实世界、真实业务场景下的宝贵的真实数据,我对这样的数据没有抵抗力,我想触碰真实世界,不想在模拟的数据集里闹腾;
    • 和选手们进行交流和讨论,结交数据科学圈内的新朋友,积累人脉,逐步实现转型;
    • 提交成绩和排名榜的更新都是实时的,就像是《头号玩家》的排名榜,我觉得很刺激,很有趣,像是大家在一块儿打游戏;
  • 觉得自己在数据科学这块领域中的核心竞争力是什么?

暂时还没有。硬要说有的话,大概就是自己对于数据科学的热情和对未知事物的好奇心吧。

  • 参加比赛有没有觉得沮丧的时候?

有,很多很多。做的实验有很多都是失败的,经常实现不了预期的效果,成绩长期没有提升。最沮丧的时候是发现自以为学到了很多新知识,把成果拿出来和别人PK,这才发现原来自己是在自娱自乐。

  • 下一步有什么打算?

还没想好。不过不太想做数据挖掘类(回归和分类)的比赛了,想尝试一下深度学习(计算机视觉)方向的比赛。数据挖掘比赛做久了,感觉什么都是玄学,感觉做什么都有data leakage,很多东西都难以解释难以理解,有种flying blind的感觉。


比赛内容

来自官方的背景介绍:科大讯飞AI营销云在高速发展的同时,积累了海量的广告数据和用户数据,如何有效利用这些数据去预测用户的广告点击概率,是大数据应用在精准营销中的关键问题,也是所有智能营销平台必须具备的核心技术。本次大赛提供了讯飞AI营销云的海量广告投放数据,参赛选手通过人工智能技术构建预测模型预估用户的广告点击概率,即给定广告点击相关的广告、媒体、用户、上下文内容等信息的条件下预测广告点击概率。希望通过本次大赛挖掘AI营销算法领域的顶尖人才,共同推动AI营销的技术革新。

简单来说就是道两分类的机器学习题,target变量为用户是否点击该广告(1为点击,0为未点击)。初赛的数据量级是,训练集100万样本,测试集4万样本,特征一共有34个。这份比赛数据比较特别的一点是,几乎所有的特征都是categorical feature,所有特征大致可以分为下面四类:

特征

可以看到,除了province/ creative_width/ creative_height/ time这四个特征之外,所有的特征都是categorical的,说白了就是,几乎所有的特征都是id,各种各样的id。

比赛的评估标准是logloss,越低越好。


比赛进程

初期探索

参赛的第一天,主要是熟悉了一下数据的构成,做了一些简单的EDA,然后就是清洗一下make(手机品牌)和model(手机型号)这两个特征。说实在的,科大讯飞给的这套数据,不太干净,感觉他们收集用户数据的时候没有统一的标准和规则,很杂很乱(其他公司的数据也未必好到哪里去...)。

以特征make(手机品牌)为例,显然APPLE/ Apple/ apple/ iPhone这四个都是苹果手机,于是我把这四类样本给合并为Apple,而且,make特征本应该是各种手机厂商,但是却混进来很多的手机型号,比方说这个特征里有MI 8/ MI 6/ MI MAX 2/ MI Note Pro等,身为小米脑残粉的我当然知道这些都是小米手机,于是我把这些取值全部修改为了Xiaomi,但是,我显然不可能知道世界上所有的手机型号,而这个make特征里又恰恰混进了很多的手机型号,于是我花了两三个小时,通过Google来搜索某个型号属于什么品牌,然后修改其取值。

make特征的缺失值大概是10万,占总样本量的10%左右,查看了一些缺失的样本过后,我发现其中一部分样本的缺失值可以很科学地进行填补。比方说,有一个样本,它的make特征是缺失的,但是model却显示为OPPO R7Plus,所以这款手机的品牌显然是OPPO。这样的样本有很多,我按照这种通过手机型号来推断手机品牌的方法,进行缺失值填补,最后make特征的缺失量从10万减少到了不到3万,而剩下的这些缺失值就没法填补了。

model特征(手机型号)的问题在于数据录入错误,比方说,里面同时存在着OPPO+R11/ OPPO-R11/ OPPO R11这三类手机型号,但是显然这是同一类型号,只不过系统把空格错误地处理为了+号和-号,这样的错误几乎无处不在,所以我又花了几个小时的时间来进行修正。没有什么技术难度(就是一些简单的pandas操作),就只是繁琐罢了。说起来,看着数据不断地变得干净、统一,心里还挺满足的。

osv(手机操作系统版本)这个特征也花了一些时间来清洗。我们知道,现在市面上就两款操作系统,谷歌的android和苹果的ios,(塞班已经停止发展了,这套数据里也没有塞班的手机)。安卓的最新版本是9,但是绝大多数用户的版本都是8;ios现在最新版是12,但这套数据里绝大多数苹果用户的版本都是ios 11。理论上来说,osv这个特征的最大取值应该是12,因为最新版本号也就只有12,但是数据里却出现了很多的21/ 22/ 23这样的取值。查了一下资料,原来这是安卓手机的API level,它和安卓版本号大致是一种一一对应的关系:

安卓版本

于是我按照这张表统一了安卓手机的版本号,合并了API level。苹果手机倒是没有这样的数据问题,它主要的错误在于写法不统一,比如,数据里有11.4.1/ 11_4_1/ iOS 11.4.1 / iOS11.4.1/ iPhone OS 11.4.1这五类样本,显然都是同一个系统版本(所以我说科大讯飞的数据不太干净)。我清洗了这类错误。

上面说的make/ model/ osv这三个特征是出问题比较多,比较不干净的特征,所以花了一些时间来认真地清洗,其他特征的问题不大。

在做了一些基本的清洗之后,我开始使用LightGBM模型来跑算法。LightGBM除了运算速度非常快以外,还有一个优点,就是它能够直接处理categorical feature,不用把它们进行one hot encoding转化为维度很高的稀疏矩阵,这也是我非常喜欢LightGBM的原因之一。

我在比赛第一天就提交了结果,当时线下的交叉验证分数是0.4236,但是提交之后的线上分数只有0.43419,远远不如线下的成绩。事实证明,线上分数比线下分数要差,从第一天第一次提交结果开始,就一直困扰着我,直到现在,直到此时此刻都不明白是为什么。因为我提交得很快,所以当时的排名是第11名,这是我参赛以来的最好成绩了,从那以后就一直在退步。事实证明,提交得快没啥用,暂时排名是靠前是因为大佬们都还没提交呢,真正重要的是提交性能好的结果。


线上线下的分数差距

接下来的时间里,除了进一步清洗数据之外,就是在思考,为什么线上的分数比线下的分数差这么多。线下的交叉验证分数显然是一个过分乐观的分数,线上的分数则是冷冰冰的现实。我使用交叉验证的模式,得到的预测结果的线上线下分数差距是100个万分点,我想要缩小这个差距。

我的一个猜想是,验证集和测试集的数据分布不一致(查了不少资料,大家都是这么归因的),验证集的分数过于乐观,没能generalize到测试集上面。

我在竞赛圈里也问了这个问题,当时一位同学告诉我说,这个比赛实际上是具有时间序列属性的,训练集是第1~7天,测试集是第8天,所以不能用交叉验证,更理想的做法应该是用前6天的数据做训练,第7天做验证,第8天做测试。

How (and why) to create a good validation set 里也提到了这一点:

我能理解为什么不应该做交叉验证,因为你不能够用未来的数据做训练,而把过去的数据做验证,这不是现实场景下的应用方案。我理解,在道义上,是不应该做交叉验证的,可是,同样一套数据,我用交叉验证的分数总是优于规范的做法,不管是线上分数还是线下分数。于是我想,这套数据是时间序列的,又如何?短短几天时间内,用户的行为差异有这么大吗?把八天时间看做同一天,当做是横截面数据来做,又有什么不行的呢?

我其实不懂统计,对我而言,两个数据集的数据分布不一致是一件非常抽象的事情,所谓数据分布,指的是target变量y的分布?还是指所有特征X的联合分布?还是指(X, y)的联合分布?如果是指y或者(X, y)的话,这里就没法检验训练集和测试集是否分布相同,因为测试集是没有y的。

粗浅地了解了一下,似乎是有Kolomogorov-Smirnov检验等方法来对数据分布是否一致进行判断,对离散变量和对连续变量的检验方法也各有不同,我因为在这方面没有太多的基础,随后也就放弃了。并且,做检验最后得到的结果无非就是告诉你,这两个数据集是否分布一致,并给出一个置信度。这其实并不是我想要的,我想要的,不是判断这两份数据的分布究竟是否一致(况且我做了几天比赛之后已经能够比较有信心地说这两个分布就是不一致的),而是如何解决数据分布不一致这个问题。

根据我对现实世界的观察,我认为安卓用户和苹果用户在用户行为上还是有很大的差异的,我查看了数据,发现在训练集里,安卓苹果用户比例是91.1% / 8.9%,而在测试集里,安卓苹果用户比例是87.8% / 12.2%,这其实是非常大的差异。我当时心中一喜,以为找到了分布不一致的解决方案,心里想着,训练集和测试集的分布差异,肯定不止体现于用户的手机系统这个维度上,但是,安卓手机和苹果手机的分布比例,可以看做是整套数据分布差异的一个近似,因此,通过调整用户手机系统的分布,应该有助于训练集和测试集趋向于一致。

于是我尝试了重抽样的方法,从整个训练集中随机抽取38000个苹果手机用户的样本,使得训练集的样本量从100万增加到了104万,这样一来,就确保了验证集和测试集的安卓苹果用户比例一致,都为87.8% / 12.2%。理论上来说,这种做法应该能够使得验证集(线下)分数和测试集(线上)分数之间的差距缩小。可是我在实际操作之后,我发现这个差距不但没有缩小,反而是100个万分点扩大到了120个万分点。这个比赛中,选手之间的差距都非常小,前后两人之间分数差距不到1个万分点,而我却把线上线下差距扩大了20个万分点,这意味着什么?意味着我的实验失败了。

既然手机操作系统不是数据分布差异的本源,我便继续尝试其他的变量。我想到,一天24个小时,用户在不同时间段的点击广告的心境、行为和状态都是不同的,于是我检查了一下训练集和测试集在时间段这个特征上的分布,发现它们的差别还是挺大的。

左边为训练集的小时分布 | 右边为测试集的小时分布

于是沿用之前的做法,按照测试集的小时分布,从训练集中抽取样本作为验证集,确保了验证集和测试集在时间段这个维度是一致的。运行模型,线下得到的分数非常好,0.408991,远远地超过了我目前所有的模型分数,兴奋地点击了提交,却失落地发现线上分数只有0.4270,线上线下的差距进一步扩大到了180个万分点。

好吧,这一次实验又失败了。但是想不明白为什么。也许是因为我抽样的方法不对?也许不应该从整个训练集中抽样来生成验证集,这和交叉验证本质上没什么区别,他们都使得训练集和验证集都有着全部7天的数据,这就陷进了使用未来的信息去预测过去的信息的错误中了。也许这是问题所在。于是我将训练集分为第1~6天和第7天两部分,前一部分做训练集,后一部分按照测试集的小时分布,抽取出一个子样本来作为验证集。这样一来,我既没有犯使用未来的信息去预测过去的信息的错误,也确保了验证集和测试集数据分布的一致。

心想,这一次应该有所好转了吧。然鹅现实是,差距进一步恶化了,并且线上线下的分数都变差了。好吧,再一次实验失败了。

这几个实验可以看做是我的这次比赛经历的一个缩影吧,每次以为我就要抓住线上线下差距的本源了,兴奋地张开了手,却发现我什么都没有抓住,真是失落极了。


关于Data Leakage

关于广告点击率预测的数据挖掘比赛其实有很多很多,比如kaggle的TalkingData AdTracking Fraud Detection Challenge,腾讯TSA的社交广告算法大赛等,相关的论文也发表了不少,当然我是没有时间和精力把所有的资料都看一遍啦,只能学一点是一点。

我在比赛初期的做法很不规范,我把整个训练集做了特征工程之后,得到了一个新的训练集,然后才在它的基础上做交叉验证跑模型,下面会提到为什么这种做法不规范。

我从类似的比赛中发现,大家都提取了一类很重要的变量:分组点击率,比方说,按照app来分组,求出每个app的平均的广告点击率。嗯,这样的特征的含义还挺直观的。后来查资料的时候发现这种做法其实有个官方名字,叫Target Encoding:

于是开始往我的模型里加上这类变量。在比赛的第七天晚上,加入了这类变量跑算法的时候,惊讶地发现线下的成绩竟然是0.22!和之前所有模型的分数完全不在一个档次上!当时兴奋地以为自己找到了性能非常棒的magic features,屁颠屁颠地跑去提交结果,没想到,分数竟然是我所有模型中最差的,垫底的那一个。

感觉自己在几分钟内体验了极度的兴奋和极度的失落。。。

冷静下来之后找了找原因,查了查Google的资料,发现原来是我的不规范的交叉验证导致了data leakage。

所谓的data leakage,简单来说就是,训练模型的时候,模型学到了不该学的东西。举一个例子,你是一位数学课任老师,期末考试要到了,你决定给同学们做一套模拟试题,让他们提前热热身,进入状态,但是,在出期末考试题目的时候,你不小心把几道已经出过的模拟试题原封不动地放进了期末考卷里,后来你发现,大家的考试成绩都出奇地好。你以为是同学们的整体实力都变强了,但事实是,你无意之间把考题给泄露出去了,同学们在参与测试之前,就已经见过考试题目了。

机器学习中的泄露也是同样的道理,模型的性能表现如何是用验证集来评估的。如果,模型在进行训练的时候,就已经见过了验证集的数据的模样,那么它的分数会出奇地好,就像考试泄题一般好。

Data leak occurs when you aren't careful distinguishing training data from validation data. For example, this happens if you run preprocessing (like fitting the Imputer for missing values) before calling train_test_split. Validation is meant to be a measure of how the model does on data it hasn't considered before. You can corrupt this process in subtle ways if the validation data affects the preprocessing behavoir.. The end result? Your model will get very good validation scores, giving you great confidence in it, but perform poorly when you deploy it to make decisions.

评估一个模型的时候,必须选用一套该模型迄今为止从来没有见过的数据做验证,这才是科学合理的验证方式,只有在这种验证方法下取得好成绩的模型,才能够真正地部署应用到实际生活之中。否则,你将会看到一个模型的分数令你十分满意,可应用到现实生活之中时却表现得一塌糊涂。

我之前的做法之所以会导致data leak,是因为我在求分组点击率的时候,是在整个训练集(100万样本)的基础上求的,这样一来,在做交叉验证的时候,我得到的点击率特征,既包含了训练集的信息,也包含了验证集的信息。模型都已经见过了验证集,这个验证集,已经没有验证的意义了。

在Youtube上看了一个视频Leakage in Meta Modeling And Its Connection to HCC Target-Encoding,里面多次说到在做Target Encoding的时候要小心data leakage:

所以,规范的交叉验证的做法应该是,将数据随机分成五份,取其中的4份(80万样本),做特征工程,做target encoding,然后把处理的过程原封不动地apply到验证集(20万样本)上面。这样一来,就能确保在处理特征的时候,只涉及到训练集,不管验证集长啥样,都是把训练集上的处理过程原封不动地照搬到验证集上面,这样,对模型来说,验证集就是一套从来没有见过的数据,这样的验证是可靠的。

这个时候,我才知道了sklearn中的pipeline的意义所在(我之前一直不喜欢pipeline,感觉像是八股文一样套路),pipeline能够确保你在操作训练集的时候,用的是fit_transform(),操作验证集时用的是transform()。原来,规范的操作能够避免很多的问题,学到了。

后来的这几天时间里,我都在进一步查阅关于data leakage的资料,然后把我的所有代码改成规范的验证范式来避免data leakage。其实学习的时候还挺开心的,因为不只是我这样的初学者,即便是有着多年机器学习经验的数据科学家,有的时候也会犯下这样的错误,造成的商业价值的损失高达几百几千万,我在年轻的时候认识到了这个问题的重要性,也挺好的。其实,初学者也好,高端大佬也好,我们所面临的最高检验,都是现实世界,只有在真实世界中表现良好的模型,才是真正有价值的模型的,其他的,都不重要。


比赛后期

上面说了,从第一天起,我们的排名就一直在掉,到了比赛结束前三天的时候,已经掉到270名了,最好的一次提交是在半个月前,也就是说,长达半个月的时间没有进步了。这天晚上,偶然知道这个比赛原来有交流用的QQ群。感觉自己错过了全世界。。。

加入了群聊之后,发现比赛的第一名选手把自己的baseline代码开源了。下载来运行了一下,好家伙,分数是0.424759,碾压了我提交过的所有模型,直接把我的排名提高了110名。

好吧,原来自己埋头苦干了这么久,还远远不及别人的baseline呢。实力的差距吧。

研究这份baseline的时候,发现代码不过也就100多行,没有任何的数据清洗,就是把所有的categorical feature进行one hot处理,得到的稀疏矩阵CSR的维度高达24000维,我原本以为我的笔记本电脑处理不了这么高维的数据,但是发现LightGBM处理CSR矩阵非常快,和稠密矩阵的速度差不多。

玄学的地方来了,同样的一套数据,同样是LightGBM算法,我一直使用的是label encoding,而第一名选手用的baseline,做的是one hot encoding。从label encoding改为one hot encoding后,排名一下提升100多名。实在难以理解。

我原本以为,用one hot来处理类别变量,不是一种好的处理方法,事实上这也是LightGBM放弃one hot的原因,微软的开发团队转而采用了many to many的方法来直接处理类别变量。现在看来,我还是缺乏经验,太想当然了,应该把one hot encoding和label encoding都尝试一遍才对。不过,我之前没有加入到群聊里,思路完全受阻,根本没有往这一块儿想,我根本不知道scipy库的里sparse matrix运算性能这么好,以前用one hot生成的是稠密矩阵,总是容易内存溢出。唉,早日加入到群聊里就好了,可以少走很多弯路,可以多学一些知识,真遗憾。

另外,baseline对于用户标签user tags这个特征的处理是把它当成文本,统计词频,用的是sklearn里的CountVectorizer和TfidfVectorizer,这也是我之前所不知道的,想了很长时间也不知道该怎么处理这个特征。

所以最后三天的时间里,我所做的事情就是在这份baseline的基础上做提升。

上面说了,我花了不少时间去清洗手机型号/ 手机品牌/ 系统版本号这三个特征,于是我在baseline的前面加入了这一部分清洗的代码,结果,玄学的地方又出现了,成绩竟然变差了???也就是说,我把一些错误的数据给纠正过来之后,反而导致模型的性能变差了??脏的、乱的数据通过清洗变得干净、统一之后,分数反而变差了??实在是难以理解,这就意味着,根本不需要做任何data cleaning,直接把最初的原始数据送到模型里跑就行了?这简直是颠覆了我的认知,太玄学了。

接着,我造了不少groupby之后的分组统计特征,然后逐个加入到模型中,如果这个特征使得分数提高了,那么我就认为它是一个好的特征,应当保留下来。我用这种方法大概筛选十个左右的新特征,把它们一起放进模型里的时候,玄学的地方又双叒叕出现了,成绩特么地竟然下降了,也就是说,这十个特征,每个特征单独加到模型里之后,都能改进模型,可一旦它们一块儿进入到模型里之后,模型反而变差了。真奇怪,我所做的,就是标准的feature selection的流程啊,kaggle的广告点击率预测比赛里,获得第六名的选手就是这么做的啊。搞不明白,真玄学。

队友给我打了一个比方,好吧,玄学就是不能理解的。

比赛的最后一天里,尝试通过stakcing来冲一下排名,用baseline跑了几个LightGBM模型,搭配上之前跑的神经网络和CatBoost,可是不管怎么搭配模型进行stacking,分数都只会下降,没有提高,和预期完全不符(说起来,整个比赛过程中,就没有什么操作是能够实现预期效果的)。

在比赛结束前十分钟,我们还剩下两次提交机会,我的最好成绩是0.424759,队友的最好成绩是0.424893,原本打算选择这两次提交作为最终结果了,后来我转念一想,干脆别stacking了,干脆就把这两份文件求个加权平均吧。

惊喜!加权平均之后成绩上到了0.424691,排名提高了一些,然后队友告诉我,评价指标logloss是越低越好,不是越高越好,应该用调和平均,而不是加权平均,于是我用了最后一次提交机会。成绩又提高了!0.424689,比上一次又提升了。正好这两个文件可以用来做最后的提交文件。怎么说呢,直到比赛的最后一刻,我们都还在进步,算是虽败犹荣了吧。。。

我们的团队最好成绩,是在比赛结束前一分钟提交的,可以说是很迷了。如果能早点加入到群聊里和其他选手交流,说不定能够取得更好的成绩。

初赛结束,第二天换榜之后,我们的排名上到了第97名,也就是我们的最终排名了。算是很幸运了吧,看来有不少的选手过拟合了,换榜之后分数就掉了下来,主要还是数据量级太小了,分数不够稳定。


关于LightGBM

机器学习里有一个著名的NFL定理(No free lunch theorem,天下没有免费的午餐):没有任何一种算法,在任何场合下都能碾压其他的算法,现实情况一定是,在特定的某种场合下,这种算法效果最好,在另一种场景下,另一种算法效果更好。这很好理解,合适的才是最好的嘛。我认可这个定理,但我不能理解的是,为什么在数据挖掘竞赛中获得冠军的算法,通常都是以LightGBM/ XGBoost为代表的GBDT类算法,在比赛中,你很难遇到性能比它们更优秀的其他算法。

我第一次接触LightGBM是在我第一次参加数据挖掘竞赛(kaggle的Home Credit Default Risk)的时候,那时候发现大家用的都是这个模型,我也就跟风用了(另外一个原因是,我当时才接触数据挖掘不久,懂的模型很少,我不知道在处理真正的大数据时,工业上用的都是什么模型),后来也稍微尝试用了一下其他的模型,这才发现LightGBM模型是如此优越,它运行得很快,能够自动填补缺失值,跑出来的结果都很好,(又好又快可以说是机器学习模型的终极目标了吧,LightGBM做到了),所以它非常适合用于做实验,如果你有什么新的idea,使用LightGBM来检验一下,再合适不过了。参加过数据挖掘比赛的人都知道,快速迭代和快速实践是成功的关键之一。

我似乎是陷入了一个舒适圈里,觉得LightGBM就是最好的,我喜欢用它,我依赖用它。我似乎越来越不愿意尝试去用别的算法和模型了,并且思考问题的视角也越来越往LightGBM上面靠。这样不好,得改,否则视野会越来越狭隘,思维会逐渐枯死。还有很多的新事物值得探索。


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,154评论 5 464
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,252评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 145,107评论 0 327
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,985评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,905评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,256评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,978评论 3 388
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,611评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,891评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,910评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,736评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,516评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,995评论 3 301
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,132评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,447评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,034评论 2 343
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,242评论 2 339

推荐阅读更多精彩内容