C++,python,热爱算法和机器学习
全部博文(1214)
分类: IT业界
2019-04-05 22:24:09
近几年,机器学习竞赛网站Kaggle,很多获得第一名的选手用的模型算法都是xgboost。
那么xgboost到底是一个怎么样的算法,boosting又是一个什么样的算法概念?wikipedia 一看,简直要晕倒了呀,那么多复杂的公式,完全不知道从哪里入手。
有这个:
还有这个:
密密麻麻的公式,简直觉得要回大学把绿色的高数书拿出来再好好研究一下。今天我们不讲公式,只用简单明了的例子,小学生就能看懂的公式,来还原boosting的原理。
(以下例子用adaboosting)
首先用拟人化简单介绍一下adaboosting,把adaboosting想象为一个大家庭,大家庭里有爷爷,爸爸,奶奶,妈妈,儿子。现在出一张卷子给他们做,每人答完这张卷子,老师批完试卷,传给下一个做。爷爷做完卷子,错误率有30%。接着,爷爷传给爸爸做卷子,爷爷告诉爸爸,我这几题答错了,你答的时候要特别注意点,最好多读几遍,爸爸于是听从爷爷的叮嘱,也做了这张卷子,错误率20%,接着爸爸把同样的卷子给奶奶做,告诉了奶奶哪些题目要注意,奶奶错误率是60%,接着奶奶用同样的方法传给妈妈,妈妈传给儿子。
当所有人做完题目,家庭里的每个成员按照错误率有了一个排名,我们知道谁答对的多,谁答错的多。现在呢,又有了一张卷子,又需要答题。本来这个大家庭想推荐爸爸答题的,因为爸爸的正确率最高嘛,但是他们发现,一些爸爸答错的题目,排名最低的儿子却确答对了。比如说这道题目:
下面这个卡通人物是巴斯光年吗?
(爸爸居然说错,爸爸说这个应该是变形金刚 ????????????????????)
这个大家庭商量了下,觉得派一个人的风险有点大,万一之后题目都是这种类型的话,只派爸爸的话,那错误率岂不是要飙升,不如他们每人做一遍试卷,按照之前答题错误率高低,投票综合出个结果吧。比如爸爸错误率低,他的答案的占的比重就大一点,儿子错误率高,他的权重就小一点,但是也不能完全不考虑儿子的答案。
上面的例子,用2句话概括就是:
- 每个模型(人)按照错误率都有一个权重
- 模型(人)答错的地方,下一个模型(人)需要重点考虑,加重答错地方的权重,减小答对地方的权重
了解了概念后,我们用实际的数据一步一步演示下:
比如我们给出的一套卷子是猜性别,我们标注 -1是男的, 1是女的;
首先我们先偷看下正确答案:
题目 | 正确答案 |
---|---|
1 | -1 |
2 | 1 |
3 | 1 |
4 | 1 |
题目 | 正确答案 | 儿子答案 | 结果 | 每题权重 |
---|---|---|---|---|
1 | -1 | 1 | 错 | 0.25 |
2 | 1 | -1 | 错 | 0.25 |
3 | 1 | 1 | 对 | 0.25 |
4 | 1 | -1 | 错 | 0.25 |
儿子4道里面错3道,错误率是75%,
有了错误率后,我们可以算出儿子在最后投票的权重
(1/2)*Log((1-0.75)/0.75) = -0.55
这里代入公式就能算出儿子权重是-0.55,上面这个包含Log的公式主要作用是错误率超过一半我给一个负的权重,错误率低于一半,权重就给个正的。
表格里每道题0.25的权重是因为,儿子第一个答题,所以每道题同样对待 ? = 0.25。
前面说了,儿子做错的题,第2个做卷子的人要注意的,所以我们需要更新每道题的权重,
题目 | 正确答案 | 儿子答案 | 结果 | 儿子做之前题目权重 | 儿子做完后题目的权重 |
---|---|---|---|---|---|
1 | -1 | 1 | 错 | 0.25 | 0.433 |
2 | 1 | -1 | 错 | 0.25 | 0.433 |
3 | 1 | 1 | 对 | 0.25 | 0.144 |
4 | 1 | -1 | 错 | 0.25 | 0.433 |
更新每到题的权重我们用下面的公式:
题目答错了:原来题目权重 * e^(-1 * 这个人权重)
题目答对了:原来题目权重 * e^(+1* 这个人权重)
这个公式主要作用是,增大答错题目的权重,减小答对题目的权重,也就是说,喂喂喂,这道题目我错了哦,你下次要多注意点。
这样的话:
第一道儿子答错的题,新的权重是0.433 = 0.25*e^(-1*(-0.55))
第三道儿子答对的题,新的权重是0.144 = 0.25*e^(+1*(-0.55))
我们看到答错的题从原来的0.25上升到了0.433,而答对的题,从0.25下降倒了0.144。如果一道题很简单,每个人都能答对的话,那这个数会无限小,反过来,大家都答错的题目会越来越大,为了避免这种情况,我们最后把卷子交给下个人时候,我们再需要标准化每题的权重:
题目 | 儿子做完后题目权重 | 儿子交给下一个人题目的权重 |
---|---|---|
1 | 0.43 | 0.3 |
2 | 0.43 | 0.3 |
3 | 0.14 | 0.1 |
4 | 0.43 | 0.3 |
让这些题目权重相加等于1 (第一题 0.3 = 0.43/(0.43+0.43+0.14+0.43))
题目 | 正确答案 | 爷爷答案 | 结果 | 儿子交给爷爷做题权重 |
---|---|---|---|---|
1 | -1 | -1 | 对 | 0.3 |
2 | 1 | -1 | 错 | 0.3 |
3 | 1 | 1 | 对 | 0.1 |
4 | 1 | -1 | 错 | 0.3 |
爷爷答对2题,答错2题,原本错误率是50%的,但是因为每到题目的权重发生了变化,比如同样两道题,一道很容易,一道很难,如果同样对待一刀切的方法,肯定不公平,考虑了每道题的权重,我们重新算出错误率是 0.6 (0.6 =(0.3+0.3)/1) ,就是答错题权重总和除以所有题目权重。
用上面同样的公式我们得出爷爷的权重是 -0.2 (1/2)*LN((1-0.6)/0.6) = -0.2。
接下来根据爷爷答对答错的题目,重新计算题目权重
题目 | 正确答案 | 爷爷答案 | 结果 | 儿子交给爷爷题目权重 | 爷爷做完后题目权重 |
---|---|---|---|---|---|
1 | -1 | 1 | 对 | 0.30 | 0.24 |
2 | 1 | -1 | 错 | 0.30 | 0.37 |
3 | 1 | 1 | 对 | 0.10 | 0.08 |
4 | 1 | -1 | 错 | 0.30 | 0.37 |
同样的,爷爷在交给下个人做的时候,要重新标准化权重:
题目 | 爷爷做完后题目权重 | 爷爷交给下一个人题目的权重 |
---|---|---|
1 | 0.24 | 0.23 |
2 | 0.37 | 0.35 |
3 | 0.08 | 0.08 |
4 | 0.37 | 0.35 |
题目 | 正确答案 | 爸爸答案 | 结果 | 爷爷交给爸爸做题权重 |
---|---|---|---|---|
1 | -1 | -1 | 对 | 0.23 |
2 | 1 | 1 | 对 | 0.35 |
3 | 1 | -1 | 错 | 0.08 |
4 | 1 | -1 | 对 | 0.35 |
爸爸错了一道题,错误率是 0.08/1=0.077,爸爸权重是1.24,爸爸根据做对做错的情况,重新更新的题目的权重:
题目 | 正确答案 | 爸爸答案 | 结果 | 爸爸做之前题目权重 | 爸爸做完后题目的权重 |
---|---|---|---|---|---|
1 | -1 | -1 | 对 | 0.23 | 0.07 |
2 | 1 | 1 | 对 | 0.35 | 0.10 |
3 | 1 | -1 | 错 | 0.08 | 0.27 |
4 | 1 | 1 | 对 | 0.35 | 0.10 |
爸爸在交给下个人时候需要重新排一下题目权重:
题目 | 爸爸做完后题目权重 | 爸爸交给下一个人题目的权重 |
---|---|---|
1 | 0.07 | 0.13 |
2 | 0.10 | 0.19 |
3 | 0.27 | 0.50 |
4 | 0.10 | 0.19 |
因为例子关系,我们就举3个人做卷子为例子。
我们有了下面的权重:儿子 -0.55, 爷爷 -0.20, 爸爸 1.24。
我们出一道新的题目给他们3个人做,按照之前说的,他们投票综合结果做为大家庭的最后答案:
做题人 | 权重 | 答案 |
---|---|---|
儿子 | -0.55 | -1 |
爷爷 | -0.20 | -1 |
爸爸 | 1.24 | 1 |
加权平均: -0.55 * (-1) + -0.2 * (-1) + 1.24 * (1) = 1.99。因为1.99 > 0,符号为正,所以最后答案是女。
计算爷爷爸爸儿子错误率的公式
(1/2)*LN((1-0.75)/0.75) = -0.55 ,
有没有觉得和文章开头第一个公式很像:
而这句话:
题目答错了:原来题目权重 * e^(-1*这个人权重)
题目答对了:原来题目权重 * e^(+1*这个人权重)
是不是和第二个公式很像:
小学生都看的懂的boosting,我是不是没有骗人。另外,千万不要以为boosting真的那么简单,如果要深入学习,还是要多研究哦。