01 树与森林
在构建决策树的时候,可以让树进行完全生长,也可以通过参数控制树的深度或者叶子节点的数量,通常完全生长的树会带来过拟合问题。过拟合一般由数据中的噪声和离群点导致,一种解决过拟合的方法是进行剪枝,去除树的一些杂乱的枝叶。
实际应用中,一般可用随机森林来代替,随机森林在决策树的基础上,会有更好的表现,尤其是防止过拟合。
在机器学习算法中,有一类算法比较特别,叫组合算法(Ensemble),即将多个基算法(Base)组合起来使用。每个基算法单独预测,最后的结论由全部基算法进行投票(用于分类问题)或者求平均(包括加权平均,用于回归问题)。
组合算法中,一类是Bagging(装袋),另一类是Boosting(提升),随机森林便是Bagging中的代表。使用多颗树进行单独预测,最后的结论由这些树预测结果的组合共同来决定,这也是“森林”名字的来源。每个基分类器可以很弱,但最后组合的结果通常能很强,这也类似于:“三个臭皮匠顶个诸葛亮”的思想。
上面文章换一种理解,即为:掌握了随机森林,基本上可以处理很多常见的机器学习问题。由此可见,组合算法在很多时候,其预测的性能都会优于单独的算法,这也正是随机森林的魅力所在。
02 处处随机
多个人组成的团队,是不是一定就强于一个人呢?团队的产出并不能把每个人的力量相加,并非和“众人拾柴火焰高”的道理一样。要让团队的总产出高于单个人的产出,那必须是每个人都有其它人不具备的知识或者能力,如果大家都是完全相同的知识或者能力,在解决难题上并没有帮助。假设对一个数据的预测,大家的结论都是1,最后组合结论依然是1,没有任何改变。对预测准确率,没有任何提升。
这也是“森林”前面还有“随机”这个修饰词的原因,随机就是让每个颗树不一样,如果都一样,组合后的效果不会有任何提升。假设每颗树不一样,单独预测错误率大概都是40%(够弱了吧,很多时候都会犯错),但三颗树组合的后的错误率就变成了35.2%(至少一半以上(两颗树)同时犯错结果才会犯错),其计算方法为:
3个全错(一种情况) + 2个错1个对(3种组合):
1 0.4^3 + 3 0.4^2 * (1-0.4)^1 = 0.352
因此,随机森林算法中,“随机”是其核心灵魂,“森林”只是一种简单的组合方式而已。随机森林在构建每颗树的时候,为了保证各树之间的独立性,通常会采用两到三层的随机性。
从数据抽样开始,每颗树都随机地在原有数据的基础上进行有放回的抽样。假定训练数据有1万条,随机抽取8千条数据,因为是有放回的抽样,可能原数据中有500条被抽了两次,即最后的8千条中有500条是重复的数据。每颗树都进行独立的随机抽样,这样保证了每颗树学习到的数据侧重点不一样,保证了树之间的独立性。
抽取了数据,就可以开始构建决策分支了,在每次决策分支时,也需要加入随机性,假设数据有20个特征(属性),每次只随机取其中的几个来判断决策条件。假设取4个属性,从这4个特征中来决定当前的决策条件,即忽略其它的特征。取特征的个数,通常不能太小,太小了使得单颗树的精度太低,太大了树之间的相关性会加强,独立性会减弱。通常取总特征的平方根,或者log2(特征数)+1,在scikit-learn的实现中,支持sqrt与log2,而spark还支持onethird(1/3)。
在结点进行分裂的时候,除了先随机取固定个特征,然后选择最好的分裂属性这种方式,还有一种方式,就是在最好的几个(依然可以指定sqrt与log2)分裂属性中随机选择一个来进行分裂。scikit-learn中实现了两种随机森林算法,一种是RandomForest,另外一种是ExtraTrees,ExtraTrees就是用这种方式。在某些情况下,会比RandomForest精度略高。
总结起来,使用随机性的三个地方:
因此,理解了这几个地方的随机性,以及随机性是为了保证各个基算法模型之间的相互独立,从而提升组合后的精度。当然,还需要保证每个基分类算法不至于太弱,至少要强于随机猜测,即错误率不能高于0.5。
03 sklearn与mllib
scikit-learn和spark中都实现了随机森林,但各自有些细小的区别。
在scikit-learn中,同样只是简单几行代码即可:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# sklearn_rf.py
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
df = pd.read_csv('sklearn_data.csv')
train, test = df.query("is_date != -1"), df.query("is_date == -1")
y_train, X_train = train['is_date'], train.drop(['is_date'], axis=1)
X_test = test.drop(['is_date'], axis=1)
model = RandomForestClassifier(n_estimators=50,
criterion='gini',
max_features="sqrt",
min_samples_leaf=1,
n_jobs=4,
)
model.fit(X_train, y_train)
print model.predict(X_test)
print zip(X_train.columns, model.feature_importances_)
|
调用RandomForestClassifier时的参数说明:
从前面的随机森林构建过程来看,随机森林的每颗树之间是独立构建的,而且尽量往独立的方向靠,不依赖其它树的构建,这一特点,在当前的大数据环境下,尤其被人喜爱,因为它能并行,并行,并行……。
能完全并行的算法,一定会被人们追捧,在资源够的情况下,可以同时并行构建大量的决策树。scikit-learn虽然是单机版本,不能做分布式,但也可以利用单机的多枋来并行。
spark中,更是能发挥分布式的特点了:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
from pprint import pprint
from pyspark import SparkContext
from pyspark.mllib.tree import RandomForest
from pyspark.mllib.regression import LabeledPoint
sc = SparkContext()
data = sc.textFile('spark_data.csv').map(lambda x: x.split(',')).map(lambda x: (float(x[0]), int(x[1]), int(x[2]), float(x[3]), int(x[4]), int(x[5])))
train = data.filter(lambda x: x[5]!=-1).map(lambda v: LabeledPoint(v[-1], v[:-1]))
test = data.filter(lambda x: x[5]==-1)#.map(lambda v: LabeledPoint(v[-1], v[:-1]))
model = RandomForest.trainClassifier(train,
numClasses=2,
numTrees=50,
categoricalFeaturesInfo={1:2, 2:2, 4:3},
impurity='gini',
maxDepth=5,
)
print 'The predict is:', model.predict(test).collect()
print 'The Decision tree is:', model.toDebugString()
|
和决策树版本相比,唯一的变化,就是将DecistionTree换成了RandomForest,另外增加了一个指定树颗数的参数:numTrees=50。
而和scikit-learn版本相比,spark中会通过categoricalFeaturesInfo={1:2, 2:2, 4:3}参数指定第5个属性(工作属性)具有3种不同的类别,因此spark在划分的时候,是按类别变量进行处理。而scikit-learn中,依然当成连续的变量处理,所以在条件判断的时候,才会有house
当有多个最优分割的时候,spark与scikit-learn在选择上也有区别,spark会按属性顺序进行选择,而scikit-learn会随机选择一个。这也是导致scikit-learn在多次运行中会输出0和1的问题。
scikit-learn中,还可以输出参数重要性,这也是决策树和随机森林的优点之一(目前pyspark还不支持输入参数重要性):
1
2
|
# scikit-learn中
print zip(X_train.columns, model.feature_importances_)
|
[(‘height’, 0.25), (‘house’,’car’, 0.0), (‘handsome’, 0.60), (‘job’, 0.0)]
04 特点与应用
随机森林基本上继承决策树的全部优点,只需做很少的数据准备,其他算法往往需要数据归一化。决策树能处理连续变量,还能处理离散变量,当然也能处理多分类问题,多分类问题依然还是二叉树。决策树就是if-else语句,区别只是哪些条件写在if,哪些写在else,因此易于理解和解释。
决策树的可解释性强 ,你可以打印出整个树出来,从哪个因素开始决策,一目了然。但随机森林的可解释性就不强了。所谓可解释性,就是当你通过各种调参进行训练,得出一个结论,你老大来问你,这个结论是怎么得出来的?你说是模型自己训练出来的,老大又问了,比如举一条具体的数据,你说一说得出结论的过程呢?因为随机森林引入了随机取特征,而且是由多颗树共同决定,树一旦多了,很难说清楚得出结论的具体过程。虽然可以打印每颗树的结构,但很难分析。
虽然不好解释,但它解决了决策树的过拟合问题,使模型的稳定性增加,对噪声更加鲁棒,从而使得整体预测精度得以提升。
因为随机森林能计算参数的重要性,因此也可用于对数据的降维,只选取少量几维重要的特征来近似表示原数据。同理,在数据有众多的特征时,也可以用于特征选择,选择关键的特征用于算法中。
随机森林还有天生的并行性,可以很好的处理大规模数据,也可以很容易的在分布式环境中使用。
最后,在大数据环境下,随着森林中树的增加,最后生成的模型可能过大,因为每颗树都是完全生长,存储了用于决策的全部数据,导致模型可能达到几G甚至几十G。如果用于在线的预测,光把模型加载到内存就需要很长时间,因此比较适合离线处理。
数据分析咨询请扫描二维码
CDA持证人Louis CDA持证人基本情况 我大学是在一个二线城市的一所普通二本院校读的,专业是旅游管理,非计算机非统计学。毕业之 ...
2024-12-18最近,知乎上有个很火的话题:“一个人为何会陷入社会底层”? 有人说,这个世界上只有一个分水岭,就是“羊水”;还有人说,一 ...
2024-12-18在这个数据驱动的时代,数据分析师的技能需求快速增长。掌握适当的编程语言不仅能增强分析能力,还能帮助分析师从海量数据中提取 ...
2024-12-17在当今信息爆炸的时代,数据分析已经成为许多行业中不可或缺的一部分。想要在这个领域脱颖而出,除了热情和毅力外,你还需要掌握 ...
2024-12-17数据分析,是一项通过科学方法处理数据以获取洞察并支持决策的艺术。无论是在商业环境中提升业绩,还是在科研领域推动创新,数据 ...
2024-12-17在数据分析领域,图表是我们表达数据故事的重要工具。它们不仅让数据变得更加直观,也帮助我们更好地理解数据中的趋势和模式。相 ...
2024-12-16在当今社会,我们身处着一个飞速发展、变化迅猛的时代。不同行业在科技进步、市场需求和政策支持的推动下蓬勃发展,呈现出令人瞩 ...
2024-12-16在现代商业世界中,数据分析师扮演着至关重要的角色。他们通过解析海量数据,为企业战略决策提供有力支持。要有效完成这项任务, ...
2024-12-16在当今数据爆炸的时代,数据分析师是组织中不可或缺的导航者。他们通过从大量数据中提取可操作的洞察力,帮助企业在竞争激烈的市 ...
2024-12-16在现代企业中,数据分析师扮演着至关重要的角色。他们不仅负责处理和分析大量的数据,还需要将这些分析结果转化为切实可行的商业 ...
2024-12-16在当今的大数据时代,数据分析已经成为推动企业战略的重要组成部分。无论是金融、医疗、零售,还是制造业,各个行业对数据分析的 ...
2024-12-16在当今这个以数据为驱动力的时代,数据分析领域正在迅速扩展与发展。随着大数据、人工智能和机器学习技术的不断进步,数据分析已 ...
2024-12-16在信息爆炸和数据驱动的时代,数据分析专业是否值得一选成为许多人思考的议题。无论是刚刚迈入大学校门的新生,还是考虑职业转型 ...
2024-12-16适合数据分析专业学生的实习岗位有很多,以下是一些推荐: 阿里巴巴数据分析岗位实习:适合经济、统计学、数学及计算机专业的 ...
2024-12-16在数据科学领域,探索实习机会是一个理想的学习和成长方式。实习不仅可以提供宝贵的实践经验,还能帮助学生发展关键的数据分析技 ...
2024-12-16在当今信息驱动的时代,数据分析不仅成为了企业决策的重要一环,还催生了各种职业机会。从技术到业务,数据分析专业的就业岗位种 ...
2024-12-16在现代企业中,数据分析师被誉为“数据探险家”,他们通过揭示隐藏在数据背后的故事,帮助公司优化业务策略和做出明智的决策。然 ...
2024-12-16在大数据崛起的时代,数据分析师被誉为企业的“幕后英雄”。他们通过解读数据,揭示隐藏的真相,为企业战略提供重要的指导。这份 ...
2024-12-16在这个信息大爆炸的时代,数据分析师成为了企业中的“福尔摩斯”,他们能够从庞杂的数据中提取关键洞察,为业务发展提供坚实支持 ...
2024-12-16在这个数据为王的现代社会,数据分析师如同企业的导航员,洞悉数据背后所隐藏的商业机会和战略优势。然而,成为一名优秀的数据分 ...
2024-12-16