LambdaMART简介——基于Ranklib源码(二 Regression Tree训练)
上一節中介紹了 λ?λ 的計算,lambdaMART就以計算的每個doc的 λ?λ 值作為label,訓練Regression Tree,并在最后對葉子節點上的樣本 lambda?lambda 均值還原成 γ?γ ,乘以learningRate加到此前的Regression Trees上,更新score,重新對query下的doc按score排序,再次計算deltaNDCG以及 λ?λ ,如此迭代下去直至樹的數目達到參數設定或者在validation集上不再持續變好(一般實踐來說不在模型訓練時設置validation集合,因為validation集合一般比訓練集合小很多,很容易收斂,達不到效果,不如訓練時一步到位,然后另起test集合做結果評估)。
?
其實Regression Tree的訓練很簡單,最主要的就是決定如何分裂節點。lambdaMART采用最樸素的最小二乘法,也就是最小化平方誤差和來分裂節點:即對于某個選定的feature,選定一個值val,所有<=val的樣本分到左子節點,>val的分到右子節點。然后分別對左右兩個節點計算平方誤差和,并加在一起作為這次分裂的代價。遍歷所有feature以及所有可能的分裂點val(每個feature按值排序,每個不同的值都是可能的分裂點),在這些分裂中找到代價最小的。
舉個栗子,假設樣本只有上一節中計算出 λ?λ 的那10個:
1 qId=1830 features and lambdas 2 qId=1830 1:0.003 2:0.000 3:0.000 4:0.000 5:0.003 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(1):-0.495 3 qId=1830 1:0.026 2:0.125 3:0.000 4:0.000 5:0.027 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(2):-0.206 4 qId=1830 1:0.001 2:0.000 3:0.000 4:0.000 5:0.001 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(3):-0.104 5 qId=1830 1:0.189 2:0.375 3:0.333 4:1.000 5:0.196 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(4):0.231 6 qId=1830 1:0.078 2:0.500 3:0.667 4:0.000 5:0.086 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(5):0.231 7 qId=1830 1:0.075 2:0.125 3:0.333 4:0.000 5:0.078 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(6):-0.033 8 qId=1830 1:0.079 2:0.250 3:0.667 4:0.000 5:0.085 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(7):0.240 9 qId=1830 1:0.148 2:0.000 3:0.000 4:0.000 5:0.148 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(8):0.247 10 qId=1830 1:0.059 2:0.000 3:0.000 4:0.000 5:0.059 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(9):-0.051 11 qId=1830 1:0.071 2:0.125 3:0.333 4:0.000 5:0.074 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(10):-0.061上表中除了第一列是qId,最后一列是lambda外,其余都是feature,比如我們選擇feature(1)的0.059做分裂點,則左子節點<=0.059的doc有: 1, 2, 3, 9;而>0.059的被安排到右子節點,doc有4, 5, 6, 7, 8, 10。由此左右兩個子節點的lambda均值分別為:
?
? ? ? ? λ?L??ˉ?=λ?1?+λ?2?+λ?3?+λ?9?4?=?0.495?0.206?0.104?0.0514?=?0.214?λLˉ=λ1+λ2+λ3+λ94=?0.495?0.206?0.104?0.0514=?0.214
? ? ? ? λ?R??ˉ?=λ?4?+λ?5?+λ?6?+λ?7?+λ?8?+λ?10?6?=0.231+0.231?0.033+0.240+0.247?0.0616?=0.143?λRˉ=λ4+λ5+λ6+λ7+λ8+λ106=0.231+0.231?0.033+0.240+0.247?0.0616=0.143
?
繼續計算左右子節點的平方誤差和:
?
? ? ? ? s?L?=∑?i∈L?(λ?i??λ?L??ˉ?)?2?=(?0.495+0.214)?2?+(?0.206+0.214)?2?+(?0.104+0.214)?2?+(?0.051+0.214)?2?=0.118?sL=∑i∈L(λi?λLˉ)2=(?0.495+0.214)2+(?0.206+0.214)2+(?0.104+0.214)2+(?0.051+0.214)2=0.118
? ? ? ? s?R?=∑?i∈R?(λ?i??λ?R??ˉ?)?2?=(0.231?0.143)?2?+(0.231?0.143)?2?+(?0.033?0.143)?2?+(0.240?0.143)?2?+(0.247?0.143)?2?+(0.016?0.143)?2?=0.083?sR=∑i∈R(λi?λRˉ)2=(0.231?0.143)2+(0.231?0.143)2+(?0.033?0.143)2+(0.240?0.143)2+(0.247?0.143)2+(0.016?0.143)2=0.083
?
因此將feature(1)的0.059的均方差(分裂代價)是:
?
? ? ? ? Cost?0.059@feature(1)?=s?L?+s?R?=0.118+0.083=0.201?Cost0.059@feature(1)=sL+sR=0.118+0.083=0.201
?
我們可以像上面那樣遍歷所有feature的不同值,嘗試分裂,計算Cost,最終選擇所有可能分裂中最小Cost的那一個作為分裂點。然后將 s?L??sL 和?s?R??sR 分別作為左右子節點的屬性存儲起來,并把分裂的樣本也分別存儲到左右子節點中,然后維護一個隊列,始終按平方誤差和 s 降序插入新分裂出的節點,每次從該隊列頭部拿出一個節點(并基于這個節點上的樣本)進行分裂(即最大均方差優先分裂),直到樹的分裂次數達到參數設定(訓練時傳入的leaf值,葉子節點的個數與分裂次數等價)。這樣我們就訓練出了一棵Regression Tree。
?
上面講述了一棵樹的標準分裂過程,需要多提一點的是,樹的分裂還有一個參數設定:葉子節點上的最少樣本數,比如我們設定為3,則在feature(1)處,0.001和0.003兩個值都不能作為分裂點,因為用它們做分裂點,左子樹的樣本數分別是1和2,均<3。葉子節點的最少樣本數越小,模型則擬合得越好,當然也容易過擬合(over-fitting);反之如果設置得越大,模型則可能欠擬合(under-fitting),實踐中可以使用cross validation的辦法來尋找最佳的參數設定。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的LambdaMART简介——基于Ranklib源码(二 Regression Tree训练)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 再理解RankNet算法
- 下一篇: LambdaMART的源码分析:一(MA