机器学习算法系列
第一章 Python/Spark 分类模型-逻辑回归知识点详细总结
第三章 分类模型-随机森林知识点详细总结
第四章 分类模型-支持向量机SVM知识点详细总结
第五章 关联分析-apriori算法知识点详细总结
目录
前言
本章节内容主要介绍
随机森林
,集成学习、随机森林工作原理、特征重要性、随机森林参数说明并附上部分代码、随机森林优缺点。
一、
随机森林简介
它是多重决策树的组合,而不只是一棵决策树。随机森林算法下决策树的数量越多,泛化的结果更好。随机森林可作分类也可作回归。它属于机器学习中的集成学习一类。
“随机”二字理解:
1)样本随机采样;
2)属性随机选择;
随机森林是建立在决策树的基础上,关于决策树的基础知识有兴趣的可先看上一篇:
第二章 分类模型-决策树知识点详细总结_助教评分问题,构造决策树分类模型_柯努力的博客-CSDN博客
二、
了解什么是集成学习
集成学习是将多个模型进行组合来解决单一的预测问题。原理是生成多个分类器模型,独立地学习并作出预测。这些预测最后结合起来得到预测结果,因此和单独分类器的结果相比,结果一样或更好。
随机森林是集成学习的一个分支,因为它依靠于决策树的集成。
三、
随机森林工作原理(构建过程)
1. 从原始训练集中使用Bootstraping方法随机有放回采样取出m个样本,共进行n次采样。生成n个训练集。
2. 对n个训练集,我们分别训练n个决策树模型。
3. 对于单个决策树模型,假设训练样本特征的个数为n,那么每次分裂时根据信息增益/信息增益比/基尼指数,选择最好的特征进行分裂。
4. 每棵树都已知这样分裂下去,知道该节点的所有训练样例都属于同一类。在决策树的分裂过程中不需要剪枝。
5. 将生成的多颗决策树组成随机森林。对于分类问题,按照多棵树分类器投票决定最终分类结果;对于回归问题,由多颗树预测值的均值决定最终预测结果。
假设随机森林中有100棵决策树,那么,我们需要将新样本数据输入到100棵树中,然后,看每棵树返回的分类结果是什么,如果是分类问题,则根据投票原则,少数服从多数来确定新样本最终的类别。如果是回归问题,则取100棵树预测值的均值作为最终的预测值。
如:假设新样本可能有两种类别取值:0和1,使用规模为100的随机森林模型发现,有90棵树预测的类别是1,10棵树预测的结果是0,那么,少数服从多数,新样本的类别会判断为1。
参考:
https://zhuanlan.zhihu.com/p/180067849
四、
特征重要性
随机森林中的特征重要性表示在该特征上拆分的所有节点的基尼不纯度减少的总和。我们可以使用它来尝试找出随机森林认为最重要的预测变量,特征重要性可以让我们更好地洞察问题。
五、
随机森林分类
模型参数说明
Python sklearn参数说明,
随机森林中的超参数既可以用来提高模型的预测能力,也可以加快建模的速度。
n_estimators |
树的数目 |
Int, 默认10 |
criterion |
特征选择标准 |
默认”gini”,即CART算法; gini or entopy |
splitter |
特征划分标准 |
默认“best”; a)”best”:在所有特征中找到最好划分点,适合样本量不大的时候; b)”random”:随机的在部分划分点中找局部最优的划分点,适合样本数据量非常大; |
max_features |
划分数据集时考虑的最多的特征值数量 |
【int, float,string or None】,默认”auto”
|
max_depth |
决策树最大深度 |
Int or None, 默认None; 数据少或特征少的时候可以不管这个值,如果模型样本量、特征多的情况下,可以尝试限制; 常用的可以取值10-100之间,目的是解决过拟合; |
min_samples_split |
内部节点(即判断条件)再划分所需最小样本数 |
【int, float】。默认为2。
如果节点样本数少于min_samples_split,则不会继续尝试选择最优特征来划分。若样本数量级非常大,推荐增大这个值。 |
min_samples_leaf |
叶子节点(即分类)最少样本数 |
【int, float】 默认为1
限制叶子节点最少的样本数,如果叶子节点数目小于样本数,则会和兄弟节点一起被剪枝 |
min_weight_fraction_leaf |
叶子节点(即分类)最小的样本权重和 |
【float】。这个值限制了叶子节点所有样本权重和的最小值,如果小于这个值,则会和兄弟节点一起被剪枝。默认是0,就是不考虑权重问题,所有样本的权重相同。 |
max_leaf_nodes |
最大叶子节点数 |
【int, None】默认值None,限制最大叶子节点数,防止过拟合; 如果加了限制,算法会建立在最大叶子节点数内最优的决策树。如果特征不多,可以不考虑这个值,但是如果特征多,可以加限制,具体的值可以通过交叉验证得到。 |
class_weight |
样本类别权重 |
【dict, list of dicts, balanced】默认None,指定样本各类别的权重,主要是为了防止训练集某些类别的样本过多,导致训练的决策树过于偏向这些类别. “balanced”:自动计算,样本量少的类别对应的样本权重会高; 注意,对于多输出(包括多标记),应为其自己的dict中的每个列的每个类定义权重。例如,对于四类多标签分类权重应为[{0:1,1:1},{0:1,1:5},{0:1,1:1},{0:1,1: 1}]而不是[{1:1},{2:5},{3:1},{4:1}]。 |
min_inpurity_split |
信息增益的阀值(已弃用) |
策树在创建分支时,信息增益必须大于这个阈值,否则不分裂。 |
min_impurity_decrease |
节点划分最小不纯度 |
【float】。默认值为0。限制决策树的增长,节点的不纯度(基尼系数,信息增益,均方差,绝对差)必须大于这个阈值,否则该节点不再生成子节点。 |
random_state |
|
默认是None,【int, randomSate instance, None】 |
presort |
|
布尔型,默认是False,表示在进行拟合之前,是否预分数据来加快树的构建。 对于数据集非常庞大的分类,presort=true将导致整个分类变得缓慢;当数据集较小,且树的深度有限制,presort=true才会加速分类。 |
Spark scala随机森林参数说明
setLabelCol |
设置标签列 |
标签列的名称 |
setFeaturesCol |
设置特征列 |
训练集DF中存储特征数据的列名 |
numTrees |
决策树的个数 |
整型,默认20,增加决策树的个数会降低预测结果的方差,这样在测试时会有更高的accuracy。训练时间大致与numTrees呈线性增长关系。 |
setImpurity |
不纯度函数 |
字符串,默认是”gini”, “gini”or “entropy” |
setMaxBins |
离散化”连续特征”的最大划分数 |
整型,默认32,离散连续性变量时最大的分箱数,增加maxBins允许考虑更多分割候选项并进行细粒度分割决策, 但同时也增加了计算代价。
|
setMaxDepth |
树的最大深度 |
整型,默认5,更深的树木更具表现力(可能允许更高的准确性),但训练成本更高,容易过拟合。 但由于其它终止条件或者是被剪枝的缘故,最终的决策树的深度可能要比maxDepth小 |
setMinInfoGain |
一个节点分裂的最小信息增益 |
值为[0,1],最小信息增益(设置阈值),小于该值将不再继续分叉 |
setMinInstancesPerNode |
每个节点包含的最小样本数 |
如果某个节点的样本数量小于该值,则该节点将不再被分叉。(设置阈值) |
setSeed |
随机种子 |
长整型 |
numClasses |
类的数量 |
|
Algo |
决策树类型 |
分类或回归 |
setMaxMemoryInMB |
收集足够统计信息的内存量 |
默认值为256 MB,以允许决策算法在大多数情况下工作。增加maxMemoryInMB可以通过允许更少的数据传递来加快训练速度(如果内存可用)。但是,随着maxMemoryInMB增长,可能会有减少的回报,因为每次迭代的通信量可以与maxMemoryInMB成比例。 |
subsamplingRate |
学习决策树的训练数据的分数 |
此参数与训练树基础算法(使用RandomForest和GradientBoostedTrees)最相关,其中对原始数据进行子采样非常有用。对于训练单个决策树,该参数不太有用,因为训练实例的数量通常不是主要约束。 |
setPredictionCol |
预测结果存储列 |
默认是”predict” |
setProbabilityCol |
类别预测结果的条件概率存储列 |
默认是”probability” |
setRawPredictionCol |
原始的算法预测结果存储列 |
默认是”rawPrediction” |
Scala语言,随机森林调用及参数示例代码:
import org.apache.spark.ml.classificationRandomForestClassifier val rf = new RandomForestClassifier(). setLabelCol(“indexedLabel”). setFeaturesCol(“indexedFeatures”). setNumTrees(numTrees). setMaxBins(maxBins). setMaxDepth(maxDepth). setImpurity(impurity) |
六、
随机森林优缺点
优点:
- 实现比较简单,模型泛化能力强
- 容易实现并行化
- 对于不平衡的数据集来说,它可以平衡误差
- 如果有很大一部分的特征遗失,仍可以维持准确度
- 在训练过程中,能够检测到feature间的互相影响
- 训练速度快,能够得到特征重要性排序
- 能够处理很高维度(feature很多)的数据,并且不用做特征选择(因为特征子集是随机选择的)
- 抗过拟合能力:通过平均决策树,降低过拟合的风险性
- 只有在半数以上的基分类器出现差错时才会做出错误的预测:随机森林非常稳定,即使数据集中出现了一个新的数据点,整个算法也不会受到过多影响,它只会影响到一颗决策树,很难对所有决策树产生影响。
缺点:
- 比决策树算法更复杂,计算成本更高
- 对于小数据或者低维数据(特征较少的数据),可能不能产生很好的分类。(处理高维数据,处理特征遗失数据,处理不平衡数据是随机森林的长处)
- 无法控制模型内部的运行。只能在不同的参数和随机种子之间进行尝试。
- 随机森林在解决回归问题时,并没有像它在分类中表现的那么好,这是因为它并不能给出一个连续的输出。当进行回归时,随机森林不能够做出超越训练集数据范围的预测,这可能导致在某些特定噪声的数据进行建模时出现过度拟合
七、
应用领域
- 预测疾病的风险和病患者的易感性
- 做市场营销模拟的建模,统计客户来源,保留和流失
八、
随机森林代码
scala代码:
val labelIndexer = new StringIndexer().
setInputCol("label").
setOutputCol("indexedLabel").
fit(data)
// Automatically identify categorical features, and index them.
// Set maxCategories so features with > 4 distinct values are treated as continuous.
val featureIndexer = new VectorIndexer().
setInputCol("features").
setOutputCol("indexedFeatures").
setMaxCategories(4).
fit(data)
// Split the data into training and test sets (30% held out for testing)
val Array(trainingData, testData) = data.randomSplit(Array(0.7, 0.3))
// Train a RandomForest model.
val rf = new RandomForestClassifier().
setLabelCol("indexedLabel").
setFeaturesCol("indexedFeatures").
setNumTrees(numTrees).
setMaxBins(maxBins).
setMaxDepth(maxDepth).
setImpurity(impurity)
// Convert indexed labels back to original labels.
val labelConverter = new IndexToString().
setInputCol("prediction").
setOutputCol("predictedLabel").
setLabels(labelIndexer.labels)
// Chain indexers and forest in a Pipeline
val pipeline = new Pipeline().
setStages(Array(labelIndexer, featureIndexer, rf, labelConverter))
// Train model. This also runs the indexers.
val model = pipeline.fit(trainingData)