真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

對xgboost和lightgbm的理解及其調(diào)參應(yīng)該關(guān)注的點(diǎn)

這兩個(gè)算法都是集成學(xué)習(xí)了分類回歸樹模型,先討論是怎么集成的。
集成的方法是 Gradient Boosting
比如我要擬合一個(gè)數(shù)據(jù)如下:
對xgboost和lightgbm的理解及其調(diào)參應(yīng)該關(guān)注的點(diǎn)

創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供那坡網(wǎng)站建設(shè)、那坡做網(wǎng)站、那坡網(wǎng)站設(shè)計(jì)、那坡網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、那坡企業(yè)網(wǎng)站模板建站服務(wù),10年那坡做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

第一次建了一個(gè)模型如上圖中的折線,效果不是很理想,然后要新建一個(gè)模型來綜合一下結(jié)果,那么第二個(gè)模型如何建,我們將實(shí)際目標(biāo)值和我們第一個(gè)模型的預(yù)測的差值 作為第二次模型的目標(biāo)值如下圖再建一個(gè)模型:
對xgboost和lightgbm的理解及其調(diào)參應(yīng)該關(guān)注的點(diǎn)
然后不斷地新建新的模型,過程如下:
對xgboost和lightgbm的理解及其調(diào)參應(yīng)該關(guān)注的點(diǎn)

最后就能集成這些模型不斷提升預(yù)測的精度。
步驟如下:
損失函數(shù):
對xgboost和lightgbm的理解及其調(diào)參應(yīng)該關(guān)注的點(diǎn)
最小化目標(biāo):
對xgboost和lightgbm的理解及其調(diào)參應(yīng)該關(guān)注的點(diǎn)
對每一個(gè)基學(xué)習(xí)器求偏導(dǎo):
對xgboost和lightgbm的理解及其調(diào)參應(yīng)該關(guān)注的點(diǎn)
對xgboost和lightgbm的理解及其調(diào)參應(yīng)該關(guān)注的點(diǎn)

這兩個(gè)算法的基學(xué)習(xí)器都是分類回歸樹,也就是先分類然后回歸的樹,這里采用決策樹來做特征分類。
建立決策樹要考慮主要的問題是,我們?nèi)绾握业胶线m的特征和合適的切分點(diǎn)來做數(shù)據(jù)集劃分。判斷標(biāo)準(zhǔn)是什么。
可以采用遍歷的方式,遍歷每一個(gè)特征的每一個(gè)數(shù)據(jù),注意為了能夠快速劃分?jǐn)?shù)據(jù)集,在分某一個(gè)特征的時(shí)候,就根據(jù)這個(gè)特征進(jìn)行排序,這樣切割數(shù)據(jù)集的時(shí)候就不要每一個(gè)數(shù)據(jù)重新進(jìn)行和切分點(diǎn)的閾值進(jìn)行比較。
劃分依據(jù)是分類之后的數(shù)據(jù)集的目標(biāo)值的方差和要下降的最多(對于目標(biāo)值是連續(xù)值)。
假設(shè)下面代碼中最后一列為目標(biāo)值:

def err_cnt(dataSet):
    '''回歸樹的劃分指標(biāo)
    input:  dataSet(list):訓(xùn)練數(shù)據(jù)
    output: m*s^2(float):總方差
    '''
    data = np.mat(dataSet)
    return np.var(data[:, -1]) * np.shape(data)[0]

這樣就可以建立每一顆樹。
但是考慮到遍歷每一個(gè)特征,還要遍歷每一個(gè)特征的每一個(gè)值會(huì)效率很低,所以lightgbm相對xgboost有個(gè)改進(jìn),就是對于某一個(gè)特征的值得分布建立一個(gè)直方圖,然后根據(jù)直方圖的切分點(diǎn)來對數(shù)據(jù)集進(jìn)行分割。
對于這個(gè)地方有個(gè)重要的參數(shù):
max_bin,也就是我這里每一個(gè)特征畫直方圖最大的柱子的個(gè)數(shù)有多少個(gè),如果畫的越多說明分得越細(xì),所以在調(diào)整這個(gè)參數(shù)的時(shí)候要自己先對特征的分布有個(gè)把握,我的特征是否需要這么多個(gè)bin來繪制直方圖。直方圖有個(gè)好處,子節(jié)點(diǎn)的兄弟節(jié)點(diǎn)的直方圖只要用父節(jié)點(diǎn)減去子節(jié)點(diǎn)就可以獲得該兄弟節(jié)點(diǎn)的直方圖。

建立了每一個(gè)樹之后要考慮過擬合的問題,例如假如每一個(gè)葉子節(jié)點(diǎn)上面只有一個(gè)數(shù)據(jù),當(dāng)然就能完美擬合訓(xùn)練數(shù)據(jù)集,但是可能泛化能力就很差,也就是我的樹建的很深,這里有兩個(gè)參數(shù):
min_data_in_leaf
表示一個(gè)葉子節(jié)點(diǎn)上面最少有多少個(gè)數(shù)據(jù),要根據(jù)訓(xùn)練數(shù)據(jù)集的目標(biāo)值的分布來看,有可能有的目標(biāo)值就真的有一個(gè)偏離非常遠(yuǎn)(例如平安數(shù)據(jù)大賽中有的目標(biāo)賠率非常高,可能是發(fā)生了重大事故),你實(shí)在要擬合這個(gè)數(shù)據(jù),只能把這個(gè)參數(shù)調(diào)成1
min_sum_hessian_in_leaf
這個(gè)參數(shù)表示一個(gè)葉子上的數(shù)據(jù)的權(quán)重的和,如果調(diào)的很小,也就是這個(gè)葉子上面的數(shù)據(jù)越少,也有過擬合的風(fēng)險(xiǎn),調(diào)的越大說明葉子上面數(shù)據(jù)越多,要根據(jù)數(shù)據(jù)集的目標(biāo)值的分布來確定
n_estimators 表示有多少顆樹
num_leaves表示有多少葉子,請注意,lightgbm和xgboost建立一棵樹的時(shí)候有不同(他們并不是完整的二叉樹,也就是num_leaves可以小于2^max_depth)

xgboost建樹的過程如下(level-wise tree):
對xgboost和lightgbm的理解及其調(diào)參應(yīng)該關(guān)注的點(diǎn)

lightgbm建樹的過程如下(leaf-wise tree):
對xgboost和lightgbm的理解及其調(diào)參應(yīng)該關(guān)注的點(diǎn)
優(yōu)先生長殘差比較大的節(jié)點(diǎn)。上圖中在第二步后會(huì)選擇生長殘差較大的下一層而不是補(bǔ)齊右子樹的子節(jié)點(diǎn)。
lightgbm建立新的模型的時(shí)候?qū)τ诿恳粋€(gè)數(shù)據(jù)并不是一視同仁的,他會(huì)做一個(gè)采樣,選擇梯度(殘差)較大的數(shù)據(jù)作為新的模型的輸入。

對于調(diào)參有個(gè)博客介紹的很好:
https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/

最后本文放一段代碼 演示如何建立一顆分類回歸樹:

import numpy as np
import pickle

class node:
    '''樹的節(jié)點(diǎn)的類
    '''
    def __init__(self, fea=-1, value=None, results=None, right=None, left=None):
        self.fea = fea  # 用于切分?jǐn)?shù)據(jù)集的屬性的列索引值
        self.value = value  # 設(shè)置劃分的值
        self.results = results  # 存儲(chǔ)葉節(jié)點(diǎn)的值
        self.right = right  # 右子樹
        self.left = left  # 左子樹

def load_data(data_file):
    '''導(dǎo)入訓(xùn)練數(shù)據(jù)
    input:  data_file(string):保存訓(xùn)練數(shù)據(jù)的文件
    output: data(list):訓(xùn)練數(shù)據(jù)
    '''
    data = []
    f = open(data_file)
    for line in f.readlines():
        sample = []
        lines = line.strip().split("\t")
        for x in lines:
            sample.append(float(x))  # 轉(zhuǎn)換成float格式
        data.append(sample)
    f.close()

    return data

def split_tree(data, fea, value):
    '''根據(jù)特征fea中的值value將數(shù)據(jù)集data劃分成左右子樹
    input:  data(list):訓(xùn)練樣本
            fea(float):需要?jiǎng)澐值奶卣鱥ndex
            value(float):指定的劃分的值
    output: (set_1, set_2)(tuple):左右子樹的聚合
    '''
    set_1 = []  # 右子樹的集合
    set_2 = []  # 左子樹的集合
    for x in data:
        if x[fea] >= value:
            set_1.append(x)
        else:
            set_2.append(x)
    return (set_1, set_2)

def leaf(dataSet):
    '''計(jì)算葉節(jié)點(diǎn)的值
    input:  dataSet(list):訓(xùn)練樣本
    output: np.mean(data[:, -1])(float):均值
    '''
    data = np.mat(dataSet)
    return np.mean(data[:, -1])

def err_cnt(dataSet):
    '''回歸樹的劃分指標(biāo)
    input:  dataSet(list):訓(xùn)練數(shù)據(jù)
    output: m*s^2(float):總方差
    '''
    data = np.mat(dataSet)
    return np.var(data[:, -1]) * np.shape(data)[0]

def build_tree(data, min_sample, min_err):
    '''構(gòu)建樹
    input:  data(list):訓(xùn)練樣本
            min_sample(int):葉子節(jié)點(diǎn)中最少的樣本數(shù)
            min_err(float):最小的error
    output: node:樹的根結(jié)點(diǎn)
    '''
    # 構(gòu)建決策樹,函數(shù)返回該決策樹的根節(jié)點(diǎn)
    if len(data) <= min_sample:
        return node(results=leaf(data))

    # 1、初始化
    best_err = err_cnt(data)
    bestCriteria = None  # 存儲(chǔ)最佳切分屬性以及最佳切分點(diǎn)
    bestSets = None  # 存儲(chǔ)切分后的兩個(gè)數(shù)據(jù)集

    # 2、開始構(gòu)建CART回歸樹
    feature_num = len(data[0]) - 1
    for fea in range(0, feature_num):
        feature_values = {}
        for sample in data:
            feature_values[sample[fea]] = 1

        for value in feature_values.keys():
            # 2.1、嘗試劃分
            (set_1, set_2) = split_tree(data, fea, value)
            if len(set_1) < 2 or len(set_2) < 2:
                continue
            # 2.2、計(jì)算劃分后的error值
            now_err = err_cnt(set_1) + err_cnt(set_2)
            # 2.3、更新最優(yōu)劃分
            if now_err < best_err and len(set_1) > 0 and len(set_2) > 0:
                best_err = now_err
                bestCriteria = (fea, value)
                bestSets = (set_1, set_2)

    # 3、判斷劃分是否結(jié)束
    if best_err > min_err:
        right = build_tree(bestSets[0], min_sample, min_err)
        left = build_tree(bestSets[1], min_sample, min_err)
        return node(fea=bestCriteria[0], value=bestCriteria[1], \
                    right=right, left=left)
    else:
        return node(results=leaf(data))  # 返回當(dāng)前的類別標(biāo)簽作為最終的類別標(biāo)簽

def predict(sample, tree):
    '''對每一個(gè)樣本sample進(jìn)行預(yù)測
    input:  sample(list):樣本
            tree:訓(xùn)練好的CART回歸樹模型
    output: results(float):預(yù)測值
    '''
    # 1、只是樹根
    if tree.results != None:
        return tree.results
    else:
    # 2、有左右子樹
        val_sample = sample[tree.fea]  # fea處的值
        branch = None
        # 2.1、選擇右子樹
        if val_sample >= tree.value:
            branch = tree.right
        # 2.2、選擇左子樹
        else:
            branch = tree.left
        return predict(sample, branch)

def cal_error(data, tree):
    ''' 評估CART回歸樹模型
    input:  data(list):
            tree:訓(xùn)練好的CART回歸樹模型
    output: err/m(float):均方誤差
    '''
    m = len(data)  # 樣本的個(gè)數(shù)   
    n = len(data[0]) - 1  # 樣本中特征的個(gè)數(shù)
    err = 0.0
    for i in range(m):
        tmp = []
        for j in range(n):
            tmp.append(data[i][j])
        pre = predict(tmp, tree)  # 對樣本計(jì)算其預(yù)測值
        # 計(jì)算殘差
        err += (data[i][-1] - pre) * (data[i][-1] - pre)
    return err / m

def save_model(regression_tree, result_file):
    '''將訓(xùn)練好的CART回歸樹模型保存到本地
    input:  regression_tree:回歸樹模型
            result_file(string):文件名
    '''
    with open(result_file, 'wb') as f:
        pickle.dump(regression_tree, f)

if __name__ == "__main__":
    # 1、導(dǎo)入訓(xùn)練數(shù)據(jù)
    print ("----------- 1、load data -------------")
    data = load_data("sine.txt")
    # 2、構(gòu)建CART樹
    print ("----------- 2、build CART ------------")
    regression_tree = build_tree(data, 30, 0.3)
    # 3、評估CART樹
    print ("----------- 3、cal err -------------")
    err = cal_error(data, regression_tree)
    print ("\t--------- err : ", err)
    # 4、保存最終的CART模型
    print ("----------- 4、save result -----------")
    save_model(regression_tree, "regression_tree")

數(shù)據(jù)格式如下:
對xgboost和lightgbm的理解及其調(diào)參應(yīng)該關(guān)注的點(diǎn)
數(shù)據(jù)中間用tab鍵隔開 前面的列為特征,最后一列為目標(biāo)值。


網(wǎng)站題目:對xgboost和lightgbm的理解及其調(diào)參應(yīng)該關(guān)注的點(diǎn)
當(dāng)前路徑:http://weahome.cn/article/ggcsco.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部