天池阿里音乐流行趋势预测大赛–复赛
☛想要干货直接忽略这部分☚
话说初赛我们三个人,最好的成绩也就做到了200名,当时真的不打算搞了,但是命运就是这么喜欢捉弄人,第二赛季一换数据,就到了第二名, 一看我艹,什么情况,瞬间就又燃起了继续搞的希望。这就是中国的那句古话——山重水复疑无路,柳暗花明又一村。所以不到最后千万不要轻言放弃。
分享一下整个赛程的名次变化,其实还是很跌宕的。
OK,不扯淡了,进入正题。
二、 复赛——三起三落的跌宕人生
初赛几乎尝试了所有的通用的模型,我们三个人的三个角度,每个人都提了百十维的特征,但是模型乏力,所以复赛还是果断的换了角度。最后的成绩停留在三个角度上,我们分别起名是ME
,NSI
,OST
,下面分别对这三个模型做详细的介绍(会说一些在答辩中都没有介绍的细节)。
1、 ME
从目标函数出发,通过对目标函数松弛,求解目标函数的极值。
Fi=∑j∈W⎛⎝⎜1−1N∑k=1N((Si,j,k−Tj,k)/(Tj,k))2−−−−−−−−−−−−−−−−−−−−−−⎷⎞⎠⎟∗1N∑k=1NTj,k−−−−−−−−−⎷其中后半部分是固定的,而前半部分恰恰是我们要预测的。
σi,j=1N∑k=1N((Si,j,k−Tj,k/(Tj,k))−−−−−−−−−−−−−−−−−−−−−⎷可以看到这一个部分其实很容易受到极小值的影响,举一个简单的例子就是,如果后面60天的数据中播放量59天都是100.,但是有1天是10,这时直观的算法是如果预测100,这时只有一天预测错了,这给人的直观印象是成绩应该不错吧,其实不然,如果使用公式可以看到其中59个值(误差是0),但是一个误差是9倍,也就是这部分的值是大于1,所以整体的误差就是大于1,也就是说最后虽然59个值预测正确,最后的得分仍然负数。。。
既然分析到了这些,那么我们就要考虑如何去优化这个函数。其实最naive的松弛想法就是加入我们预测一个值,所以针对这一个值对其进行优化。这个
σ函数
很明显就是二次函数,所以对目标函数进行求导。
∂σi,j∂xj=∂1N∑Nk=1((x−Ti,k)/Ti,k)2−−−−−−−−−−−−−−−−−−−−√∂xj=−12N∗∑Nk=i2(xj−Ti,k)/T2i,k1N∑Nk=1((xj−Ti,k)/T2i,k)2=0最后可以得出
x
的最优取值为
x∗j=∑Nk=11/Ti,k∑Nk=11/T2i,k这时可以看到最后得到的公式是十分的简单,实现起来用简单的几行sql就可以完成,同样我们可以使用前面的任意天数替代真实数据,所以最后的代码也就20行左右。我们把这个方法叫做
ME(最小化误差模型)
。下面的代码是带有评测的代码。select artist_id,sqrt(sum(e.target)) * (1-sqrt(avg(pow((e.plays-e.target)/e.target,2)))) as fscore from( select c.artist_id,c.ds,c.target,d.plays from( select t.artist_id,t.ds,t.target from ( select artist_id, ds, plays as target from artist_play WHERE ds >= '{target_from_date}' and ds<='{target_to_date}' )t )c left outer join( select artist_id,sum(1/plays)/sum(1/plays/plays) as plays from( select artist_id,ds, plays from {local_data2use} WHERE ds >= "{me_from_date}" and ds <= "{toDate}" )b group by artist_id )d on(c.artist_id=d.artist_id) )e group by artist_id order by artist_id;
在第二赛季换数据之后,我们使用14天的
ME
就获得了第8,但是后面我们有对ME
进行了优化,我们把14天的ME
记作ME14
,同理我们可以得到ME1
~ME30
,最后我们将这30个ME
求了一个算术平均。也许这时候各位大侠可能会问了,为什么要对它求平均?各位大侠请看这张图,虽然
ME
可以有效的减少一些极小值对预测的影响,但是整体是下降趋势,这时如果使用算术均值,就可以抵消一些由于原本是下降趋势,而预测偏高的影响。如果非要拔高为什么要这么做可能就是所谓的模型融合吧。。。最后
ME(avg30)
可以拿到498000+分,估计可以进入前20,也就20行左右的代码。。。
2.OST
在有了
ME
作为我们的baseline之后发现其实预测一个是是有上限的,我们用了最极端的例子就是7~8月的真实值作ME
预测7-8月的播放量,发现也就480000+分,也就是无论你做的再怎么好它的upbound就在那里,不增不减。所以就要做波动。
各位大侠可以先看看下面的这个数据。
估计各位大侠已经想到了,波动预测Airma
应该是首选了,当然我们也试了,效果在这样的数据上面勉强还算可以,但是这样的数据也就占总共数据的5%左右。但是也有他的弊端就是因为Airma
做的事周期预测,可以看到这些数据除了高点,其他的点趋势也是很容易预测错,预测小了还可以,但是如果本来是下降的趋势,模型预测成了上升感觉就会分分钟GG,因为目标函数对极小值还是十分敏感的。所以周期是不能这么用的。那么这个波动应该怎么用呢?这时候仔细观察数据,我们为何不剑走偏锋,不用7天的周期,而是只去修改一个值,相当于是对baseline的修改。我们把这个模型叫做
OST(老歌周期模型)
。最后OST的模型就是修改哪些基于统计得来的某一天一定会出现极值的日期。虽然是这么用了,但是最后成绩却没有提升,由于是最后的idea,没时间验证,但是对于分数的提升我们的把握还是很大的。
3.NSI
下面就是这个比赛的重中之重,新歌衰减模型。
各位大侠看下面的这个数据。红点是新歌发布,所以我们能不能拟合一下这个新歌的衰减趋势?
答案是肯定的!
虽然肯定可以拟合这个衰减曲线,但是衰减曲线有很多种,到底应该用什么样的衰减曲线进行拟合?但是可选的有
线性回归模型
,GBDT
等通用模型,或者自建模型
。首先可以把线性模型pass掉,因为线性模型使用直线进行拟合,但是可以看到数据在前期的衰减是很剧烈的,所以如果使用线性模型,很容易在预测的前几天就会衰减到负数。那通用模型学习可以吗,经过分析之后发现也不行,因为如果使用所有的新歌训练一个通用模型,这样虽然泛化能力够强,但是不能达到足够的个性化,一个很明显的点就是衰减到什么程度不是通用的。但是如果每一个新歌训练一个模型,这时数据很少也就20个左右,很容易过拟合,所以通用模型也被pass掉了,那就只剩下最后的那个自建模型。
仔细观察数据可以看到,新歌的衰减很像指数衰减。
y=1eax+b+1
这样的衰减函数,可以对y进行转化,然后转化成线性函数进行拟合,但是尝试后就会发现,如果对y进行转化,在最后的预测值又需要的将y转化回来,这时y是指数函数转化,由于预测本来就是不是很准确,极小的误差,表现在y上就会偏差很大。下图红线部分。这时如果对x进行log变化,就可以这样对y的影响降到最低,如图绿线部分。最后我们管这个模型叫做
OSI(新歌衰减模型)
这里有几个trick要跟大家分享一下:
a. 衰减无穷远点问题
由于这个模型在拟合的时候仍然使用线性函数,所以仍然会出现在60天后预测出现负数的可能,虽然这个可能已经很小,但是还是有必要处理一下,就是不能让新歌一直衰减,所以在模型中添加了
无穷远点
,那么何为无穷远点
呢?在模型中我们使用200天之后的作为无穷远点
。以此减少可能无限衰减的情况。b. 衰减到多少问题
这个问题其实也是十分棘手的,我们不能说所有的新歌都衰减到原来的10%,这种数据太人工,或者太naive,所以我们要找到一个合适的衰减到的值。对于这个问题我们使用的统计的方法,将新歌分成两类,如果这个artist前面有发新歌,那么我们就取他所有发的新歌衰减到的最后的均值,如果没有新歌,那衰减到的比例就是最后的
global
的均值。c. 是所有的新歌我们都要吗?
肯定不是的,对于拟合出来的曲线,我们采用r2值进行衡量,如果r2值大于一定的阈值(证明拟合的这个曲线还不错),我们就保留,如果小于,我们就抛弃。当然我们也会删除掉那些在最后几天发布的新歌,因为这个趋势不好去拟合,稍有不慎就,满盘皆输。
三、总结——骏马蹄前无沟堑,怂人眼里全是坎。
上周一参加了最终的答辩,本来以为可以膜拜一下大熊老师讲
Airma
各种调参的,但是发现大家都没有用这种东西,我们前面的队伍使用的最核心的思想就是不同的artist进行了分类,大熊老师他们通过对artist的不同表现使用GBDT分来,然后在回归,最后拿到这么好的名次,因为模型的回归能力确实不是特别的好,但是分类一般来说准确率是有保障的,因为有概率的输出吗!第二名和第三名的团队都是采用了不同的分类方式。所以这次比赛感觉最纯的干货就是先分类,再回归。从初赛走来,感触颇多,可能我对于别人来说就是证明我不是坑队友,当然我也找到了神队友。
当当当,最后爆照时间。。。