學習日志---樹回歸(回歸樹,模型樹)-創(chuàng)新互聯(lián)

CART算法的樹回歸:

網(wǎng)站建設公司,為您提供網(wǎng)站建設,網(wǎng)站制作,網(wǎng)頁設計及定制網(wǎng)站建設服務,專注于企業(yè)網(wǎng)站設計,高端網(wǎng)頁制作,對成都酒店設計等多個行業(yè)擁有豐富的網(wǎng)站建設經(jīng)驗的網(wǎng)站建設公司。專業(yè)網(wǎng)站設計,網(wǎng)站優(yōu)化推廣哪家好,專業(yè)成都網(wǎng)站營銷優(yōu)化,H5建站,響應式網(wǎng)站。

返回的每個節(jié)點最后是一個最終確定的平均值。

#coding:utf-8

import numpy as np

# 加載文件數(shù)據(jù)
def loadDataSet(fileName):      #general function to parse tab -delimited floats
    dataMat = []                #assume last column is target value
    fr = open(fileName)
    for line in fr.readlines():
        curLine = line.strip().split('\t')
        fltLine = map(float,curLine) #map all elements to float()
        dataMat.append(fltLine)
    return dataMat

#在dataset中選擇特征為feature的這一列,以value值分成兩部分
def binSplitDataSet(dataSet, feature, value):
    mat0 = dataSet[np.nonzero(dataSet[:,feature] > value)[0],:][0]
    mat1 = dataSet[np.nonzero(dataSet[:,feature] <= value)[0],:][0]
    return mat0,mat1

#計算此矩陣的最后一列結(jié)果的平均值,用平均值來當做最后的返回結(jié)果,后面的模型樹返回的是一個 線性模型
def regLeaf(dataSet):
    return np.mean(dataSet[:,-1])

#計算dataset結(jié)果的混亂程度,用方差反應,因為是連續(xù)數(shù)據(jù)
def regErr(dataSet):
    return np.var(dataSet[:,-1]) * np.shape(dataSet)[0]

#選擇最佳的分離特征和該特征的分離點
#這里的ops是預先的給定值,1是差別太小就不分了,4是分開后的各自樣本數(shù),太小就舍去,這是一  種預剪枝方法
def chooseBestSplit(dataSet, leafType=regLeaf, errType=regErr, ops=(1,4)):
    tolS = ops[0]; tolN = ops[1]
    #if all the target variables are the same value: quit and return value
    if len(set(dataSet[:,-1].T.tolist()[0])) == 1: #exit cond 1
        return None, leafType(dataSet)
    m,n = np.shape(dataSet)
    #the choice of the best feature is driven by Reduction in RSS error from mean
    S = errType(dataSet)
    bestS = np.inf; bestIndex = 0; bestValue = 0
    #循環(huán)所有的特征
    for featIndex in range(n-1):
        #循環(huán)該特征下的所有特征值
        for splitVal in set(dataSet[:,featIndex]):
            mat0, mat1 = binSplitDataSet(dataSet, featIndex, splitVal)
            #如果更具這個特征值分成的兩類有一個小與預先給定值,說明分類太偏,則不考慮
            if (np.shape(mat0)[0] < tolN) or (np.shape(mat1)[0] < tolN): continue
            newS = errType(mat0) + errType(mat1)
            if newS < bestS:
                bestIndex = featIndex
                bestValue = splitVal
                bestS = newS
    #if the decrease (S-bestS) is less than a threshold don't do the split
    if (S - bestS) < tolS:
        return None, leafType(dataSet) #exit cond 2
    mat0, mat1 = binSplitDataSet(dataSet, bestIndex, bestValue)
    if (np.shape(mat0)[0] < tolN) or (np.shape(mat1)[0] < tolN):  #exit cond 3
        return None, leafType(dataSet)
    return bestIndex,bestValue              

#創(chuàng)建樹
def createTree(dataSet, leafType=regLeaf, errType=regErr, ops=(1,4)):   
    feat, val = chooseBestSplit(dataSet, leafType, errType, ops)       
    if feat == None: return val                                        
    retTree = {}
    retTree['spInd'] = feat
    retTree['spVal'] = val
    lSet, rSet = binSplitDataSet(dataSet, feat, val)
    retTree['left'] = createTree(lSet, leafType, errType, ops)
    retTree['right'] = createTree(rSet, leafType, errType, ops)
    return retTree


myDat = loadDataSet('ex0.txt')
myMat = np.mat(myDat)
result = createTree(myMat)
print result

結(jié)果:

{'spInd': 1, 'spVal': matrix(` 0`.`39435`), 'right': {'spInd': 1, 'spVal': matrix(` 0`.`197834`), 'right': -0.023838155555555553, 'left': 1.0289583666666666}, 'left': {'spInd': 1, 'spVal': matrix(` 0`.`582002`), 'right': 1.980035071428571, 'left': {'spInd': 1, 'spVal': matrix(` 0`.`797583`), 'right': 2.9836209534883724, 'left': 3.9871631999999999}}}

結(jié)果的意思是:第幾個特征,以多大作為特征值分開,分成左右,依次分下去。

這個算法很好,但是對數(shù)據(jù)的分類太過于高,容易造成過擬合。因此要采用剪枝技術(shù)。

通過降低決策樹的復雜度來避免過擬合的過程稱為剪枝。

#判斷obj是否是一個子樹
def isTree(obj):
    return (type(obj).__name__=='dict')

#用于坍塌處理,當測試數(shù)據(jù)集是空是,則取整個樹的平均值
def getMean(tree):
    if isTree(tree['right']): tree['right'] = getMean(tree['right'])
    if isTree(tree['left']): tree['left'] = getMean(tree['left'])
    return (tree['left']+tree['right'])/2.0

#剪枝函數(shù)
def prune(tree, testData):
    
    #如果測試數(shù)據(jù)集為空,則坍塌處理
    if np.shape(testData)[0] == 0: return getMean(tree)   
    
    #如果左或者右是樹,則把測試數(shù)據(jù)集根據(jù)決策樹進行分割
    if (isTree(tree['right']) or isTree(tree['left'])):
        lSet, rSet = binSplitDataSet(testData, tree['spInd'], tree['spVal'])
    
    #如果左側(cè)是樹,則把數(shù)據(jù)集和子樹帶入繼續(xù)找
    if isTree(tree['left']): tree['left'] = prune(tree['left'], lSet)
    #同理
    if isTree(tree['right']): tree['right'] =  prune(tree['right'], rSet)
    #if they are now both leafs, see if we can merge them
    #如果左右都是節(jié)點,則計算節(jié)點誤差
    if not isTree(tree['left']) and not isTree(tree['right']):
        lSet, rSet = binSplitDataSet(testData, tree['spInd'], tree['spVal'])
        #計算不合并的誤差
        errorNoMerge = sum(np.power(lSet[:,-1] - tree['left'],2)) + sum(np.power(rSet[:,-1] - tree['right'],2))
        treeMean = (tree['left']+tree['right'])/2.0
        #計算將當前兩個葉子節(jié)點合并后的誤差
        errorMerge = sum(np.power(testData[:,-1] - treeMean,2))
        if errorMerge < errorNoMerge:
            print "merging"
            #可以合并就返回平均值
            return treeMean
        #不可以合并就返回樹,不變
        else: return tree
    else: return tree

一般來說都是預剪枝和后剪枝合并使用

模型樹

每個節(jié)點是一個線性模型

其他基本一樣:

#對數(shù)據(jù)集進行線性回歸
def linearSolve(dataSet):
    m,n = np.shape(dataSet)
    X = np.mat(np.ones((m,n))); Y = np.mat(np.ones((m,1)))
    #有一列是常數(shù)項,因此要多出一列放置常數(shù)項
    X[:,1:n] = dataSet[:,0:n-1]; Y = dataSet[:,-1]
    xTx = X.T*X
    if np.linalg.det(xTx) == 0.0:
        raise NameError('This matrix is singular, cannot do inverse,\n\
        try increasing the second value of ops')
    ws = xTx.I * (X.T * Y)
    return ws,X,Y

#產(chǎn)生針對該數(shù)據(jù)集的線性模型
#相當于上面的regLeaf函數(shù)
def modelLeaf(dataSet):
    ws,X,Y = linearSolve(dataSet)
    return ws

#產(chǎn)生針對該數(shù)據(jù)集的線性模型,并計算誤差返回
#相當于上面的regErr函數(shù),計算模型的誤差,如果分后和不分的誤差差不多則選擇不分
def modelErr(dataSet):
    ws,X,Y = linearSolve(dataSet)
    yHat = X * ws
    return sum(np.power(Y - yHat,2))

模型樹回歸很好,而且可以用作預測

另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。

文章標題:學習日志---樹回歸(回歸樹,模型樹)-創(chuàng)新互聯(lián)
鏈接URL:http://muchs.cn/article28/eiicp.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供ChatGPT、網(wǎng)頁設計公司營銷型網(wǎng)站建設、網(wǎng)站設計、網(wǎng)站改版面包屑導航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設