zoukankan      html  css  js  c++  java
  • 决策树学习——回归树

      回归树也是一种决策树,不过它处理的数据标签不是属于分类的,也就是说它的标签是一个连续随机的值,比如说对一个城市的房价的预测,每个月的房价都是随机波动的值,不像分类任务,要将所有数据根据标签进行分类。

    重要参数、属性、接口

    criterion:回归树衡量分枝质量的指标,支持的标准有三种:

    1)输入"mse"使用均方误差mean squared error(MSE),父节点和叶子节点之间的均方误差的差额将被用来作为 特征选择的标准,这种方法通过使用叶子节点的均值来最小化L2损失

    2)输入“friedman_mse”使用费尔德曼均方误差,这种指标使用弗里德曼针对潜在分枝中的问题改进后的均方误差
    3)输入"mae"使用绝对平均误差MAE(mean absolute error),这种指标使用叶节点的中值来最小化L1损失

    属性中最重要的依然是feature_importances_,接口依然是apply, fit, predict, score最核心。

      其中N是样本数量,i是每一个数据样本,fi是模型回归出的数值,yi是样本点i实际的数值标签。所以MSE的本质, 其实是样本真实数据与回归结果的差异。在回归树中,MSE不只是我们的分枝质量衡量指标,也是我们最常用的衡量回归树回归质量的指标,当我们在使用交叉验证,或者其他方式获取回归树的结果时,我们往往选择均方误差作为我们的评估(在分类树中这个指标是score代表的预测准确率)。在回归中,我们追求的是,MSE越小越好。 然而,回归树的接口score默认返回的是R平方,并不是MSE。R平方被定义如下:

     

       其中u是残差平方和(MSE * N),v是总平方和,N是样本数量,i是每一个数据样本,fi是模型回归出的数值,yi 是样本点i实际的数值标签。y帽是真实数值标签的平均数。R平方可以为正为负(如果模型的残差平方和远远大于模型的总平方和,模型非常糟糕,R平方就会为负,所以R平方越接近1越好),而均方误差永远为正。 值得一提的是,虽然均方误差永远为正,但是sklearn当中使用均方误差作为评判标准时,却是计算”负均方误 差“(neg_mean_squared_error)。这是因为sklearn在计算模型评估指标的时候,会考虑指标本身的性质,均 方误差本身是一种误差,所以被sklearn划分为模型的一种损失(loss),因此在sklearn当中,都以负数表示。真正的均方误差MSE的数值,其实就是neg_mean_squared_error去掉负号的数字。

     交叉验证:

      交叉验证是用来观察模型的稳定性的一种方法,我们将数据划分为n份,依次使用其中一份作为测试集,其他n-1份 作为训练集,多次计算模型的精确性来评估模型的平均准确程度。训练集和测试集的划分会干扰模型的结果,因此用交叉验证n次的结果求出的平均值,是对模型效果的一个更好的度量。

    from sklearn.datasets import load_boston 
    from sklearn.model_selection import cross_val_score  #导入交叉验证模型
    from sklearn.tree import DecisionTreeRegressor
    
    boston = load_boston() 
    regressor = DecisionTreeRegressor(random_state=0)
    cross_val_score(regressor, boston.data, boston.target, cv=10        
                    ,scoring = "neg_mean_squared_error"    #采用负均方根误差作为评分标准
                   )

    10次交叉验证结果的MSE。

     利用回归树拟合正弦波形:

    利用python人为生成一组训练数据X,y。X代表一组正弦函数的横坐标离散点,y是对应X的函数值,通过人为加入噪声模拟实际采集的数据,将这组数据放入回归树训练,可以得到拟合的曲线:

    import numpy as np 
    from sklearn.tree import DecisionTreeRegressor
    import matplotlib.pyplot as plt
    
    rng = np.random.RandomState(1)     #随机数生成种子
    X = np.sort(5 * rng.rand(80,1), axis=0) 
       #生成0-5的随机数并进行排序,(80,1)只是为了数据二维,满足fit接口的参数要求(数#据必须是二维的)
    y = np.sin(X).ravel() 
     #raval用来给y降维,sklearn处理的是单标签问题,也就是标签必须是一维的 
    y[::5] += 3 * (0.5 - rng.rand(16)) #给y人为的增加噪声,模拟采集的非理想数据
    
    regr_1 = DecisionTreeRegressor(max_depth=2)  #两种深度的回归树,比较预测结果
    regr_2 = DecisionTreeRegressor(max_depth=5) 
    regr_1.fit(X, y) 
    #fit里面X必须是二维数据,y必须是一维标签,这就是前面生成X,y时为什么要升维降维操作
    regr_2.fit(X, y)
    
    X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis] 
    #产生测试数据0-5之间,步长为0,01,[:, np.newaxis]用于升维,测试数据也和X一样#要变为二维
    y_1 = regr_1.predict(X_test) 
    y_2 = regr_2.predict(X_test)
    
    plt.figure()
    plt.scatter(X, y, s=20, edgecolor="black",c="darkorange", label="data") 
     # s散点的大小,edgecolor边缘线的颜色,c点填充颜色
    plt.plot(X_test, y_1, color="cornflowerblue",label="max_depth=2", linewidth=2)
    plt.plot(X_test, y_2, color="yellowgreen", label="max_depth=5", linewidth=2)
    plt.xlabel("data") 
    plt.ylabel("target") 
    plt.title("Decision Tree Regression") 
    plt.legend() 
    plt.show() 

     散点是训练的数据(模拟采集的散点),可以看到两种深度的拟合的曲线,显然深度为5的绿色曲线将噪声更多的考虑到其中,实际情况中过拟合也就由此诞生,训练时考虑的噪声细节比较多,导致拟合的曲线在用于测试集时反而效果不好。

  • 相关阅读:
    树的直径
    POJ3264 Balanced Lineup
    [mock]10月11日
    POJ1062 昂贵的聘礼
    POJ3295 Tautology
    [topcoder]TopographicalImage
    POJ1753 Flip Game
    [leetcode]Copy List with Random Pointer
    [leetcode]Candy
    [leetcode]Gas Station
  • 原文地址:https://www.cnblogs.com/victorywr/p/12805581.html
Copyright © 2011-2022 走看看