随机森林相关概念介绍
随机森林
随机森林是由许多决策树构成,是一种有监督学习方法,可以用于分类和回归,通过合并汇总来自个体决策树的结果来进行预测,采用多数选票作为分类结果,采用预测结果平均值作为回归结果。
“随机”是针对森林中的每一颗决策树,有两种含义:
1. 数据采样随机
构建决策树的训练数据集通过有放回的随机采样,并且只会选择一定百分比的样本,这样可以在数据集合存在噪声点、异常点的情况下,有些决策树的构造过程中不会选择到这些噪声点、异常点从而达到一定的泛化作用在一定程度上抑制过拟合;
2. 特征随机
训练集会包含一系列特征,随机选择一部分特征进行决策树的构建。通过这些差异点来训练的每一颗决策树都会学习输入与输出的关系。
那么既然是树结构,根节点和叶子节点又是如何选择的呢? 下面将会介绍几个数学原理来一起学习一下。
1. 信息熵
信息熵可以用来度量信息源的不确定度。熵越大表明数据集的不确定度越高,数据集越不纯;熵越小表明数据集的不确定度越低,数据集越纯。所以在选取根节点时,尽量选取熵小的特征值作为根节点。

目标熵计算公式:
其中A为数据集的数据量,i为特征的类别,Ai为某种特征类别的数据量,B为特征类别下的目标数据量,B与Ai相等,j为某特征下的目标类别,Bj为某特征类别下某目标类别的数据量。
计算得到两个信息熵之后,就可以计算信息增益。能够提供最大信息增益的特征将会被用于划分子集,信息增益的计算公式为:
信息增益 = 目标熵 - 熵(目标,特征) 这种做法通常也称为ID3算法;
C4.5 算法
C4.5算法,是对ID3算法的一个改进,因为数据集中一旦出现了没有实际意义的ID列,根据信息增益计算而来的结果就会不太准确。
C4.5 算法采用信息增益率作为衡量数据集纯度的标准,信息增益率的计算公式为:
信息增益率 = 信息增益/特征自身的熵
基尼系数 — CART算法

Gini系数越高说明纯度越低,Gini系数越低说明纯度越高,每次选择Gini系数最小的特征作为节点,采用Gini系数衡量标准的决策树也称为CART(分类回归树)
ID3、C4.5、CART的使用场景比较
- ID3只能用于离散型变量,这是由于ID3算法倾向于选择分支多的特征作为节点,这是该算法的一个缺陷,对于连续性变量而言,切割之后就会有较多的分支,所以ID3不能用于连续性变量。
- C4.5可以处理对连续变量进行切割的情况,因为C4.5算法可以通过分母中特征的熵进行惩罚。
- CART,由于其构建时每次都会对特征进行二值划分,因此也可以很好地应用于连续性变量。
PySpark 实操
from pyspark.sql import SparkSession
from pyspark.sql.functions import rand
spark = SparkSession.builder.appName('randomForest').getOrCreate()
# 读取数据文件
dfInfo = spark.read.csv('Social_Network_Ads.csv', inferSchema=True,header=True)
# 将类别变量性别转换成数值形式
from pyspark.ml.feature import StringIndexer
from pyspark.ml.feature import VectorAssembler
genderIndexer = StringIndexer(inputCol='Gender', outputCol='genderIndex').fit(dfInfo)
dfInfo = genderIndexer.transform(dfInfo)
# 将所有的输入列组装成新列,新列向量充当模型的输入特征
dfInfoAssembler = VectorAssembler(inputCols=['genderIndex','Age','EstimatedSalary'],outputCol='features')
dfInfo = dfInfoAssembler.transform(dfInfo)
dfInfo.select(['features', 'Purchased']).show(10,False)
dfInfoModel = dfInfo.select(['features', 'Purchased'])
# 划分数据集
training,test = dfInfoModel.randomSplit([0.75,0.25])
# 构建和训练随机森林模型
from pyspark.ml.classification import RandomForestClassifier
rfModel = RandomForestClassifier(labelCol='Purchased').fit(training)
# 获取模型做出的预测
testRslt = rfModel.transform(test)
#testRslt.filter(testRslt['Purchased'] == 1).filter(testRslt['prediction'] == 1).\
# select(['Purchased','prediction','probability']).show(100,False)
# 使用混淆矩阵评估模型性能[[TP,FN],[TN,FP]]
TP = testRslt.filter(testRslt['prediction'] == 1).filter(testRslt['Purchased'] == 1).count()
FN = testRslt.filter(testRslt['prediction'] == 0).filter(testRslt['Purchased'] == 1).count()
TN = testRslt.filter(testRslt['prediction'] == 0).filter(testRslt['Purchased'] == 0).count()
FP = testRslt.filter(testRslt['prediction'] == 1).filter(testRslt['Purchased'] == 0).count()
# 计算准确率 (TP+TN)/(TP+TN+FP+FN)
acc =(TP+TN)/(TP+TN+FP+FN)
# 计算召回率 TP/(TP+TN)
recall = TP/(TP+TN)
print('手动计算准确率 acc[{}]'.format(acc))
# 评估预测的结果
from pyspark.ml.evaluation import MulticlassClassificationEvaluator
from pyspark.ml.evaluation import BinaryClassificationEvaluator
acc2 = MulticlassClassificationEvaluator(labelCol='Purchased', metricName='accuracy').evaluate(testRslt)
# AUC为roc曲线下的面积,AUC越接近与1.0说明检测方法的真实性越高
auc = BinaryClassificationEvaluator(labelCol='Purchased').evaluate(testRslt)
print('Spark评估模型准确率 acc[{}], auc[{}]'.format(acc2,auc))

版权声明:本文为weixin_43790705原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。