AnyMath 文档
Notebook

确定随机森林模型的影响要素

导言

在现代数据分析中,预测连续量的任务在各种应用领域中占据中心位置,从经济学和生物信息学到汽车工程和能源。 解决此类问题最广泛使用的方法之一是Random Forest,这是Leo Breiman在2001年提出的集成机器学习算法。

随机森林是回归树的集合,每个回归树都基于源数据的独立样本。 这里的基本元素是回归树,一种"决策树"类型的分层结构,在节点处,特征空间被顺序划分为更均匀的区域。 整合是基于这样一个想法,即将许多简单模型组合成一个组合可以比单独使用它们中的任何一个更高的准确性和稳定性预测。

构建决策树时的一个单独问题是数据中存在缺失值。 采用代理拆分机制来解决。 当由于遗漏而无法通过主要特征进行最佳分区时,算法会自动选择替代特征,其分区尽可能模仿原始特征。

此示例显示了在构建回归随机林时选择分区条件的策略。 该分析解决了识别对模型的预测能力做出最大贡献的关键预测因子的问题,这证明了它们必须包含在最终训练数据集中的理由。

初始数据

我们将附加必要的文件和库。

In [ ]:
# EngeePkg.purge()
# import Pkg
# Pkg.add(["DataFrames", "XLSX", "CategoricalArrays", "MLJ", "MLJDecisionTreeInterface", "StableRNGs", "EvoTrees", "DecisionTree", "Statistics", "Random", "PyPlot"])
using DataFrames, XLSX, CategoricalArrays, MLJ, MLJDecisionTreeInterface, StableRNGs, EvoTrees, DecisionTree, Statistics, Random, PyPlot
foreach(include, filter(contains(r"\.jl$"), readdir()))

包含乘用车特性的数据集用于分析。 作为研究的一部分,正在建立一个回归模型,根据以下参数预测燃料消耗:

*气缸数;
*发动机排量;
*电源;
*车辆重量;
*加速时间;
*发行年份;
*原产国。

In [ ]:
X = XLSX.readdata("автомобили.xlsx系列", "Sheet1", "A:G")
X = DataFrame(X[2:end, :], Symbol.(X[1, :])) 
Out[0]:
406×7 DataFrame
381 rows omitted
RowЦилиндровОбъёмМощностьМассаРазгонГодСтрана
AnyAnyAnyAnyAnyAnyAny
1830713035041270USA
28350165369311.570USA
3831815034361170USA
4830415034331270USA
58302140344910.570USA
6842919843411070USA
784542204354970USA
8844021543128.570USA
9845522544251070USA
10839019038508.570USA
114133115309017.570France
128350165414211.570USA
13835115340341170USA
⋮⋮⋮⋮⋮⋮⋮⋮
3956181110294516.482USA
39662628530151782USA
397415692258514.582USA
3986232112283514.782USA
399414496266513.982Japan
40041358423701382USA
401415190295017.382USA
402414086279015.682USA
40349752213024.682Germany
404413584229511.682USA
405412079262518.682USA
406411982272019.482USA

载燃料消耗数据。

In [ ]:
расход_ = XLSX.readdata("支出。xlsx系列", "Sheet1", "A:A") 
费用=解析。(Float64,flow_[2:结束])
Out[0]:
406-element Vector{Float64}:
  18.0
  15.0
  18.0
  16.0
  17.0
  15.0
  14.0
  14.0
  14.0
  15.0
 NaN
 NaN
 NaN
   ⋮
  25.0
  38.0
  26.0
  22.0
  32.0
  36.0
  27.0
  27.0
  44.0
  32.0
  28.0
  31.0

部分车辆缺乏油耗数据。 这将在进一步的计算中考虑到。

确定唯一要素值的数量

让我们从数据集中确定每个要素的唯一值的数量。

In [ ]:
对于名称中的列(X)
    try
        X[!,column]=[getdata(val)for Val in X[!,栏目]]
    catch e
        X[!,列]=categorical(X[!,列])
    end
end
unique=[length(unique(skipmissing(X[!,列])))对于名称中的列(X)]
Out[0]:
7-element Vector{Int64}:
   5
  83
  94
 356
  96
  13
   7

让我们使用条形图比较唯一值。

In [ ]:
图1=图。酒吧(1:长度(唯一),唯一, 
    title = "唯一值数",
    ylabel = "唯一值",
    xticks=(1:长度(唯一),名称(X)[1:结束]),
    ylims=(0,最大值(唯一)*1.1),
    xrotation = 45,
    legend = false,
    bar_width = 0.7,
    color = :steelblue)
显示(图1)

该图显示唯一特征值的数量存在显着差异。 这样的差异在使用用于在随机森林树的节点处选择分裂变量的标准算法时产生偏置估计的风险,因此,要形成回归树的合奏,必须考虑到特征之间的关

回归树合奏的形成

为了评估特征重要性的指标,有必要训练由回归树组成的合奏,同时考虑到特征之间的关系。 让我们创建一个训练样本。

In [ ]:
X_matrix = zeros(Float64, nrow(X), ncol(X))
col_names = names(X)

for (j, col) in enumerate(eachcol(X))
    if eltype(col) <: String || eltype(col) <: CategoricalValue
        unique_vals = unique(col)
        val_to_num = Dict(val => i for (i, val) in enumerate(unique_vals))
        X_matrix[:, j] = [Float64(val_to_num[x]) for x in col]
    else
        X_matrix[:, j] = Float64.(col)
    end
end

train_idx=。!伊斯南。(费用)
X_train = X_matrix[train_idx, :]
y_train=流量[train_idx]

println("训练样本大小:$(size(X_train,1))行")
println("属性数:$(size(X_train,2))")
训练样本量:398行
标志数目:7

让我们完成合奏训练。

In [ ]:
Random.seed!(1)
树=200
树木,yHat_train=build_forest(y_train,X_train,0,树木,0.632,-1,5,2)
valid_pred_idx = .!isnan.(yHat_train)
if sum(valid_pred_idx) > 0
    R2 = cor(y_train[valid_pred_idx], yHat_train[valid_pred_idx])^2
    println("R² = ", R2)
end
R² = 0.8713331235365577

判定系数的值 这表明模型解释了目标变量相对于平均值的87%的传播。

属性影响的评估

特征的影响是通过重新排列合奏树之间的样本外观测值来估计的。

In [ ]:
重要性=排列_importance(树,X_train,y_train,5);

意义 важность 它是一个1×7向量,包含初始特征影响的估计值。 所获得的估计的一个特征是对具有大量唯一值的特征没有偏见。 让我们比较所获得的指标的影响的迹象。

In [ ]:
图2=图。bar(重要性, 
    title = "迹象影响的指标",
    xlabel = "迹象",
    ylabel = "影响",
    xticks=(1:长度(唯一),名称(X)[1:结束]),
    ylims=(0,最大值(重要性)*1.1),
    xrotation = 45,
    legend = false,
    bar_width = 0.7,
    color = :steelblue)
显示(图2)

较高的估计值对应于较有影响力的预测变量。 根据条形图,汽车的制造年份具有最大的预测价值,其次是汽车的重量。

让我们以颜色矩阵的形式显示特征关系的估计值。

In [ ]:
график3 = imshow(predAssociation, cmap="viridis", aspect="auto", interpolation="nearest")
title("特征关系的评估")
colorbar(label="的关系")
PyPlot.xticks(0:length(col_names)-1, col_names, rotation=45, ha="right")
PyPlot.yticks(0:length(col_names)-1, col_names)
显示(图3)
PyObject <matplotlib.image.AxesImage object at 0x7f317892a990>

关系的预测度量是表征用于划分观测值的决策规则之间的相似程度的指标。 此度量的最大值是为最佳代理拆分而实现的。

矩阵元素允许我们得出特征之间关系强度的结论:较高的值表示相应特征之间的相关性较强。

结论

此示例演示了一种构建回归随机林的方法,重点是正确选择有影响力的要素。 使用一组汽车特性的示例,解决了预测油耗的问题-汽车行业的典型问题,其中模型的准确性影响工程解决方案。
代理拆分机制使得能够正确地处理数据间隙并构建特征关系矩阵,从而对数据中的依赖关系结构提供有意义的解释。

所提出的方法是普遍的,适用于广泛的领域:从机械工程到生物信息学。 主要的实际结论是,在选择分区标准时正确考虑变量的性质,可以提高预测的准确性,并获得关于不受统计偏差影响的因素的显着性的有意义的结论。