IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> Python机器学习日记(十二) -> 正文阅读

[人工智能]Python机器学习日记(十二)

树回归

?树回归的有点事可以对复杂和非线性的数据建模,缺点则是结果不易理解,使用于数值型和标称型数据。

一般来说树的构建算法是ID3,每次选取当前最佳的特征来分割数据,并按该特征的所有可能的取值来切分。如果一个特征有4种取值,那么数据将被截成4份。另一种是二元切分法,每次把数据集切成两份,如果数据的某特征值等于切分所要求的值,那么这些数据就进入左子树,反之进入右子树。ID3算法还不能直接处理连续型特征,需要转换成离散型。但这种准换过程会破坏连续性变量的内在性质。二元切分法易于对书构建过程进行调整已处理连续型特征。

下面实观CART算法和回归树。回归树叶节点的数据类型不是离散型而是连续性。

使用一部分字典来存储树的数据结构,包含以下四个元素:

1.待切分的特征

2、待切分的特征值

3.右子树,当不需要切分时,也可以是个单值

4.左子树,与右子树类似

首先建立树节点:

class treeNode():
    def __init__(self,feat,val,right,left):
        featureToSplitOn = feat
        valueOfSplit = val
        rightBranch = right
        leftBranch  =left
"""
用来建立树节点
"""

这里会构建两种树,第一种是回归树,期每个叶节点包含单个值。第二种是模型树,期每个叶节点包含一个线性方程。

先给出一些共用代码,函数createTree()的伪代码如下:

找到最佳的待切分特征:

? ?如果该节点不能再分,将该节点存为叶节点

? ?执行二元切分

? ?在右子树调用createTree()方法

? ?在左子树调用createTree()方法

from numpy import *

def loadDataSet(filename):
    dataMat = []
    fr = open(filename)
    for line in fr.readlines():
        curLine = line.strip().split('\t')
        fltLine = map(float,curLine)
        dataMat.append(fltLine)
    return dataMat

def regLeaf(dataSet):
    return mean(dataSet[:,-1])
#负责生成叶节点。当chooseBestSplit()函数确定不再对数据进行切分时,将调用该函数
#来得到叶节点的模型,该模型其实就是目标变量的均值

def regErr(dataSet):
    return var(dataSet[:,-1]) * shape(dataSet)[0]
#该函数在给定数据上计算目标变量的平方误差。

def chooseBestSplit(dataSet, leafType=regLeaf, errType=regErr, ops=(1,4)):
    tolS = ops[0]; tolN = ops[1]
#用于控制函数的停止时机,其中tols是容许的误差下降值,tolN是切分的最少样本数
    #如果所有目标变量的值相同:退出并返回值
    if len(set(dataSet[:,-1].T.tolist()[0])) == 1:
        return None, leafType(dataSet)
#如果找不到好的二元切分,该函数将返回None斌同时调用creeatTree()方法来产生叶节点
    m,n = shape(dataSet)
    #最佳特性的选择是通过减少平均值的RSS误差来实现的
    S = errType(dataSet)
    bestS = inf; bestIndex = 0; bestValue = 0
    for featIndex in range(n-1):
        for splitVal in set(dataSet[:,featIndex]):
            mat0, mat1 = binSplitDataSet(dataSet, featIndex, splitVal)
            if (shape(mat0)[0] < tolN) or (shape(mat1)[0] < tolN): continue
            newS = errType(mat0) + errType(mat1)
            if newS < bestS:
                bestIndex = featIndex
                bestValue = splitVal
                bestS = newS
                #如果减少(S-BESTS)小于阈值,则不执行分割。
    if (S - bestS) < tolS:
        return None, leafType(dataSet)
    mat0, mat1 = binSplitDataSet(dataSet, bestIndex, bestValue)
    if (shape(mat0)[0] < tolN) or (shape(mat1)[0] < tolN):
        return None, leafType(dataSet)
    return bestIndex,bestValue
#返回要拆分的最好的特征,并且该特征值会用做该拆分的值


def binSplitDataSet(dataSet,feature,value):
    mat0 = dataSet[nonzero(dataSet[:,feature]>value)[0],:][0]
    mat1 = dataSet[nonzero(dataSet[:, feature] <= value)[0], :][0]
    return mat0,mat1
"""
该函数有三个参数,数据集合,待切分的特征和该特征的某个值
在给定特征和特征值的情况下,该函数通过数组过滤方式将上述数据集合切分的到两个子集并返回
"""


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
"""
这个函数有四个参数:数据集和其他三个可选参数,这些可选参数决定了树的类型
leafType给出建立叶节点的函数
errType代表误差计算函数
ops是一个包含树构建所需要其他参数的元组
该函数是一个递归函数,首先尝试将数据集分成两部分,切分由函数chooseBestSplit()来完成
如果满足停止条件,chooseBestSplit()将返回None和某模型的值。
如果构建的是回归树,该模型是一个常数。如果是模型树,其模型是一个线性方程。
如果不满足停止条件,chooseBestSplit()将创建一个新的字典并将数据集分成两份,在这两份数据集上
分别继续递归调用createTree()函数
"""

testMat = mat(eye(4))
print(testMat)
print("-----------------------------------")
mat0,mat1 = binSplitDataSet(testMat,1,0.5)
print(mat0)
print("-----------------------------------")
print(mat1)

[[1. 0. 0. 0.]
?[0. 1. 0. 0.]
?[0. 0. 1. 0.]
?[0. 0. 0. 1.]]
-----------------------------------
[[0. 1. 0. 0.]]
-----------------------------------
[[1. 0. 0. 0.]]

?

testMat创建了一个简单的矩阵,下面是按照指定列的某个值来切分该矩阵。

chooseBestSplit()函数的伪代码如下:该函数的目标是找到数据集切分的最佳位置,他遍历所有的特征及其可能的取值来找到谁误差最小化的切分阈值。

对每个特征值:??

? ?对每个特征值:

? ? ?将数据集切分成两份

? ? ?计算切分的误差

? ? ?如果当前误差小于当前最小误差,那么将当前切分设定为最佳切分并更新最小误差

返回最佳切分的特征和阈值

看一下代码的实际效果,从数据中生成一颗回归树。?

myDat = loadDataSet('F:\python\machinelearninginaction\Ch09\ex00.txt')
myMat = mat(myDat)
print(createTree(myMat))

{'spInd': 0, 'spVal': 0.48813, 'left': 1.0180967672413792, 'right': -0.04465028571428572}

myDat1 = loadDataSet('F:\python\machinelearninginaction\Ch09\ex0.txt')
myMat1 = mat(myDat1)
print(createTree(myMat1))

{'spInd': 1, 'spVal': 0.39435, 'left': {'spInd': 1, 'spVal': 0.582002, 'left': {'spInd': 1, 'spVal': 0.797583, 'left': 3.9871632, 'right': 2.9836209534883724}, 'right': 1.980035071428571}, 'right': {'spInd': 1, 'spVal': 0.197834, 'left': 1.0289583666666666, 'right': -0.023838155555555553}}
?

现在已经完成了回归树的构建,下面将介绍树剪枝技术,它通过对决策树剪枝来达到更好的预测效果。


树剪枝

通过降低决策树的复杂度来避免过拟合的过程称为剪枝。

预剪枝这里不多做介绍敏著要讨论一下更理想化的剪枝方法-后剪枝

伪代码如下:

基于已有的树切分测试数据:
   如果存在任意子集市一棵树,则在该子集递归剪枝过程
   计算当前两个叶节点合并后的误差
   计算不合并的误差
   如果合并会降低误差的话,就将叶节点合并
def isTree(obj):
    import types
    return (type(obj).__name__ == 'dict')


'''
用于测试输入变量是否为一棵树,也就是判断当前处理的节点是否是叶节点
'''


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


'''
该函数是一个递归函数,从上往下遍历树直到叶节点为止。
如果找到两个叶节点,计算它们的平均值
该函数对树进行塌陷处理(机返回树平均值)
'''


def prune(tree, testData):
    # 如果测试集为空,则对树进行塌陷处理
    if shape(testData)[0] == 0: return getMean(tree)
    # 判断某个分支是子树还是节点
    if (isTree(tree['right']) or isTree(tree['left'])):
        lSet, rSet = binSplitDataSet(testData, tree['spInd'], tree['spVal'])
    # 处理左子树
    if isTree(tree['left']): tree['left'] = prune(tree['left'], lSet)
    # 处理右子树
    if isTree(tree['right']): tree['right'] = prune(tree['right'], rSet)
    if not isTree(tree['left']) and not isTree(tree['right']):
        #如果不是子树则进行合并
        lSet, rSet = binSplitDataSet(testData, tree['spInd'], tree['spVal'])
        # 计算没有合并的误差
        errorNoMerge = np.sum(np.power(lSet[:, -1] - tree['left'], 2)) + np.sum(
            np.power(rSet[:, -1] - tree['right'], 2))
        # 计算合并的均值
        treeMean = (tree['left'] + tree['right']) / 2.0
        # 计算合并的误差
        errorMerge = np.sum(np.power(testData[:, -1] - treeMean, 2))
        if errorMerge < errorNoMerge:
            return treeMean
        else:
            return tree
    else:
        return tree
'''
有两个参数:待剪枝的树和剪枝所需的测试数据集
'''

myDat = loadDataSet('F:\python\machinelearninginaction\Ch09\ex00.txt')
myMat = mat(myDat)
#print(createTree(myMat))
myDat1 = loadDataSet('F:\python\machinelearninginaction\Ch09\ex0.txt')
myMat1 = mat(myDat1)
#print(createTree(myMat1))
myMat2 = loadDataSet('F:\python\machinelearninginaction\Ch09\ex2.txt')
myTree = createTree(myMat2,ops=(0,1))
#为了创建所有可能中最大的树
#输入以下命令导入测试数据:
myDatTest = loadDataSet('F:\python\machinelearninginaction\Ch09\ex2test.txt')
myMat2Test = mat(myDatTest)
#输入以下命令执行剪枝过程
prune(myTree,myMat2Test)

出现报错:TypeError: list indices must be integers or slices, not tuple

我服了,跟书上一样也不对,copy网上的代码也不对,为啥人家能运行出来啊,我真是无语。

找不出来为啥,放弃

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-10-27 12:50:24  更:2021-10-27 12:53:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 8:31:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码