科学网

 找回密码
  注册

tag 标签: 随机森林

相关帖子

版块 作者 回复/查看 最后发表

没有相关内容

相关日志

[转载]用随机森林预测NBA球员打什么么位置
rbwxy197301 2017-1-21 10:00
用随机森林预测NBA球员打什么么位置? 雪姬 2017-01-16 8:11:19 机器学习 评论(1) 文 | Jurgen 译者 | Cup 目的 用NBA球员的统计数据来预测他们所打的位置。 方式 决策树和随机森林 引言 众所周知,篮球队分为大前锋、小前锋、得分后卫、控球后卫和中锋五个位置,虽然现在无位置篮球正在兴起,但是我们还是可以用球员的历史数据来预测它的位置。在这里我们就是要对球员进行一个多分类,方法选用经典的决策树和它们的集成方法——随机森林。接下来我们先看一下这五个位置各有什么特点,当然你可能比我更清楚这些内容,但是我们也不是在做无用功,注意加重的文字,我们就从这些里面选择特征。 中锋 中锋一般都是整支球队中最高的,能够进行激烈的身体对抗,负责篮板和阻拦,得分方式主要靠勾手、跳投和扣篮。 平均身高:6’11.25” 平均体重:257 lbs 控球后卫 控卫一般都是最矮的球员,应该具有优秀的过人能力和控球能力,而不是作为主要投手。一般控卫都是在攻防转换中带球过场的那个人,在进攻和防守之间控制好球权。优秀的控卫在助攻和抢断上数据很好看。 平均身高:6’2 平均体重:189 lbs 得分后卫 得分后卫一般比控卫要高一点但还是要比前锋矮,他的定位是全队的最佳投手,在其他队友的掩护下投篮得分,也要足够灵活分担控卫的职责。 平均身高:6’5.25” 平均体重:209 lbs 小前锋 小前锋被视为是进攻时的全能球员,既要足够强转可以在内线对抗又要足够灵活足够在外线驰骋,能够在外线和内线都具有较强的得分能力。 平均身高:6’7.75” 平均体重:225 lbs 大前锋 大前锋是一个既要身体高大强壮,还要有一定的速度,能够积极进攻并抢得篮板。 平均身高:6’9.5” 平均体重:246 lbs 变量 我们选择了15个变量来进行预测分析: 场均得分 Points per Game 真实投篮命中得分 True Shooting Score 进攻篮板 Offensive Rebounds 防御篮板 Defensive Rebounds 总篮板 Total Rebounds 助攻 Assists 盖帽 Blocks 失误 Turn Overs 团队利用Team Play Usage 进攻等级 Offensive Ratings 防守等级 Defensive Ratings 进攻胜利贡献 Offensive Win Shares 防守胜利贡献 Defensive Win Shares 胜利贡献 Win Shares 抢断 Steals 可视化 在分析之前,我们先来看一些变量在不同位置中的分布,从而判断什么变量可以帮助我们区分不同的位置。以下几个可视化的图表显示了这15个变量的分布。可以清晰地发现,中锋和大前锋在篮板和盖帽的数量上独领风骚,这就很可能成为决策树的分支变量。更加显著的是助攻数据,看到这里我认为要获得一个高的预测准确度还是容易达到的。 数据汇总 分布 热力图(按变量) 热力图(按位置) 决策树和随机森林分类器 适度拟合的决策树 决策树类似于一个向你问问题的机器。比如我们有一个新球员,要预测他的位置。决策树就会问:“它的总篮板数是多少”,然后你给它一个答案,它向你问的下一个问题是基于上一个问题的答案,直到他问的问题足够多以后他不会再问了而是告诉你这个球员会打什么位置。决策树很好理解而且做出来的图也很直观。 混淆矩阵显示中锋和大前锋预测正确率在50%左右,因为这两个位置往往可替代性很强,混淆的部分也很大。我们也看到了控卫的预测正确率有80%。做的这里我就想随机森林的结果一定会更好。 过拟合的决策树 过拟合是指一个模型训练的程度过头了,导致这了模型把很多因为抽样所带来的随机因素考虑进去,从而导致模型的泛化能力差,在决策树中主要是没有进行剪枝的问题。可以从图中看出这个决策树的分支很多,数比较深。而混淆矩阵显示模型的预测准确率变差了。从方差—偏差权衡的角度来看,过拟合往往是因为过于注重控制偏差,反而使方差超过了最优水平。 随机森林 随机森林是把很多的决策树组合在一起的集成算法,在下面我们可以看到在模型集成的过程中加入了随机因素,所以综合称之为随机森林。 第一种随机因素是指我们在训练模型时用的是自助采样法随机抽取出来的样本子集,这样可以使得我们的预测更为稳定并减少过拟合的风险。 第二种随机因素是构建决策树并选择最优特征划分样本时,在一个随机抽取的特征子集中选择最优特征。这样可以集成更多的树,降低方差。 在展示结果之前,我们先来剖析一下模型的训练过程。我们确定要集成的决策树数目为T,第一步是为每一棵树随机抽取一个样本子集,一般为样本全集的2/3。第二步是在树的每个节点上随机抽取m个特征作为特征子集。第三步是树的生成,在每个节点上选择一个最佳的特征进行分支。在下一个节点上继续随机选择m个特征重复以上步骤。 在我做的过程当中,我只注重调整两个影响力最大的参数,就是ntree和ntry,ntree就是指数的数目T,mtry就是指随机抽取的样本子集的大小m。 调参 对于第一个参数T我设置为180,这个图 展示了每个参数值对应的最小袋外误差。 对于参数m我设置为9,从下图袋外误差中可以看出当m=9的时候误差最小。 从混淆矩阵显示结果来看,随机森林的预测结果明显优于决策树,尤其是控球后卫的预测结果较好,但是对大前锋和得分后卫的预测精度就有些下降了。我的数据集还是有些太少,如果我们用更多的数据,随机森林的效果必然有更高的提升。在我下一步的计划中,我想从50个赛季中抓取数据,然后做一个类似的分析看看最终结果如何。 结论 这篇博客是利用NBA球员的历史数据来预测球员的位置,我用的是决策树和它的集成算法随机森林。结果显示随机森林表现得更好一点,但是提升空间也很大。 译者注:从混淆矩阵结果来看并没有预想的那么好,另外作者明明在介绍各种位置的时候着重介绍了身高和体重的问题却没有将其加入特征全集中,也有特征选用少的原因。有兴趣的朋友可以进一步尝试扩大数据集和特征集以求更好的结果。 以下是代码集,作者用的是R语言。 36大数据(www.36dsj.com)成立于2013年5月,是中国访问量最大的大数据网站。36大数据(微信号:dashuju36)以独立第三方的角度,为大数据产业生态图谱上的需求商 、应用商、服务商、技术解决商等相关公司及从业人员提供全球资讯、商机、案例、技术教程、项目对接、创业投资及专访报道等服务。 End. 转载请注明来自36大数据(36dsj.com): 36大数据 » 用随机森林预测NBA球员打什么么位置? http://www.36dsj.com/archives/74901
个人分类: 研究方法|2736 次阅读|0 个评论
加州大学戴维斯分校Leo Breiman and Adele Cutler的随机森林页面
betterkai 2014-3-23 10:08
导论 该部分给出随机森林的一个简要概述,以及对该方法一些特性进行评价。 概述 我们假设读者已经理解单个分类树的结构。随机森林可以生成许多分类树。通过对输入向量中的新对象进行分类,记下森林中每棵树的输入向量。每棵树都会给出一个分类,我们把这个分类当做树的投票。在森林的所有树中,选择选票最多的分类作为分类结果。 每棵树按照下述要求来生成: ①假设训练集中的实例数量为 N ,那么样本 N 中的实例是从训练集中有放回随机抽样得到的。该样本将会作为树的训练集。 ②假设共有 M 个输入变量,由用户指定数字 m ( mM ),随机从 M 中选出 m 个变量,并在 m 个变量中选取最佳分裂作为树的分裂节点。 m 值在森林生成过程中保持固定不变。 ③每棵树都得到最大程度的生长,没有进行修剪。 随机森林的原始论文表明,随机森林的误差取决于以下两点: ① 随机森林中任意两棵树的相关性。相关性的增加会增大随机森林的误差。 ② 随机森林中任意一棵独立树的强度。低错误率的树是强分类器。独立树的强度越大,随机森林的错误率越小。 m 越小,树的相关性和强度就越小,反之则越大。因此最优的 m 在一定范围内是存在的。使用下面的 oob 误差率可以迅速找到最优的 m 值。这是随机森林中唯一比较敏感的可调参数。 随机森林的特点 ① 在当前的算法中,拥有极好的精度。 ② 可以有效地用于大数据中。 ③ 可以在不删除变量的情况下,处理成千上万个变量。 ④ 可以估计出在分类中变量的重要程度。 ⑤ 可以在森林生成过程中,生成一个泛化误差的内部无偏估计。 ⑥ 能有效地评估缺失数据,并且在大量数据缺失的情况下保持一定精度。 ⑦ 能够平衡不平衡数据集中的分类误差。 ⑧ 生成的森林能够保存下来用于其它的数据。 ⑨ 随机森林的原型计算出变量和分类之间的相关信息。 ⑩ 可计算实例之间的亲近度,用于聚类、定位异常值,以及可拓展地给出数据的视图。 11 可用于未标记数据的无监督聚类、数据预览和异常值监测。 12 可以一种实验方法,用于探测变量间的相互影响。 评论 随机森林不会过拟合。你可以运行尽可能多的树。随机森林运行速度快,运行一个拥有 50,000 个实例和一百个变量的数据集,在一个 800MHz 的机器上生成 100 棵树只用 11 分钟。对于大数据集,主要的内存需求是存储数据本身和三个相同维度的整数数组。如果计算接近性,则需要数倍的存储空间。 随机森林如何运行 理解和使用不同选项,以及关于随机森林如何计算是非常有用的。大多数选项取决于随机森林生成的两个数据对象。 考虑到当前的树的训练集是通过有放回的抽样得到的,大概有三分之一的实例被遗漏在样本之外。在这些树组成森林的过程中,这个 oob ( out-of-bag ,袋外)数据用来对分类错误做无偏估计。 oob 也可以用来估计变量的重要性。 在所有的树建立之后, 所有的数据将会减少 ,并且将会计算每一对实例的亲近度。如果两个实例占据同一个末端节点,它们的亲近度就会增加 1 。在运行结束的时候,亲近度将会通过划分树的数量而被标准化。亲近度被用来替代缺失数据,定位异常点,产生启发性的低维度数据视图。 oob ( out-of-bag ,袋外)误差估计 在随机森林中,不需要交叉验证或者使用一个独立的测试集来对测试集误差进行无偏估计。随机森林可以在运行过程中进行如下的内部估计。 每一棵树通过对原始数据进行不同的 bootstrap 抽样得到样本而被建立起来。大概有三分之一的实例被忽略在 bootstrap 样本之外,这些实例没有用在建立第 k 棵决策树中。 记下每一个被忽略在第 k 棵决策树之外的实例,用该树对这些实例进行分类。通过这种方式, 大概三分之一的树中的每一个实例得到一个测试集分类 。在运行结束的时候,对于袋外的实例 n ,得到最多投票的类别称为 j 。 j 不等于 n 的真实类别的数量在所有袋外实例中的比例成为袋外误差估计。这在许多测试中被证明是无偏的。 变量重要性 在森林的每一棵树生成的过程中,记下袋外实例,计算投给正确分类的投票数量。现在随机变更变量 m 在袋外实例中的比重,在树中记下这些实例。用不包含袋外数据的正确分类投票数量,减去在袋外变更变量 m 中正确分类的投票数量。在森林的所有树中,这个数字的平均值就是变量 m 的初始重要性评分。 如果树与树之间,该分数的值是相互独立的,那么可以通过一个标准计算式来计算标准误差。在树之间,这些分数的相关性已经被计算为大量的数据集,并且已经被证实相当低。因此,我们可以用经典方法来计算标准误差,用初始分数除以对应的标准误差,得到 z 分数,假设正态分布的情况下,分配一个显著性水平给 z 分数。 如果变量的个数十分庞大,森林可以将所有变量运行一遍,其后只运行最重要的变量。 考虑每个实例在所有的树中处于袋外的情况,用不包含袋外数据的正确分类投票比例,减去在变更变量 m 中分类正确的投票比例。这是该实例对于变量 m 的最终重要性评分,该值用于图像程序 RAFT ( http://www.stat.berkeley.edu/~breiman/RandomForests/cc_graphics.htm )中。 基尼重要性 一个节点在变量 m 上的每次分裂,两个得到的子节点的基尼杂质标准要小于父节点。在森林的所有树的每一个独立变量中,增加了的基尼给出了一个快速评价重要性的指标,这和变更比重的重要性评价相当一致。 相互作用 相互作用的定义是变量 m 和 k 在一个变量分裂的时候是相互作用的,也就是说,在一棵树中, m 使得 k 的分裂的可能性要么增大要么减小。对森林中的每棵树,实现的方法是基于基尼值 g ( m )的。对每棵树和每两个变量进行排名,在所有树中,它们排名的绝对差异是平均的。 这些数字的计算也是在这样的假设下进行,即两个变量是相互独立的,以前一个减去后一个。一个大的整数说明,一个变量的分裂即阻止了另一个相反变量的分裂。这是一个实验过程,其结论应谨慎地得到确认。现在已经在一些数据集上得到测试。 来源网址: http://www.stat.berkeley.edu/~breiman/RandomForests/cc_home.htm
个人分类: 随机森林|1 次阅读|0 个评论
[转载]随机决策森林——OpenCV类CvRTrees使用实例
jiandanjinxin 2013-10-25 16:38
本文介绍:OpenCV机器学习库MLL中随机森林Random Trees的使用 参考文献: 1. Breiman, Leo (2001). Random Forests. Machine Learning 2. Random Forests网站 不熟悉MLL的参考此文: OpenCV机器学习库MLL OpenCV的机器学习算法都比较简单:train ——predict class CV_EXPORTS_W CvRTrees : public CvStatModel { public: CV_WRAP CvRTrees(); virtual ~CvRTrees(); virtual bool train( const CvMat* trainData, int tflag, const CvMat* responses, const CvMat* varIdx=0, const CvMat* sampleIdx=0, const CvMat* varType=0, const CvMat* missingDataMask=0, CvRTParams params=CvRTParams() ); virtual bool train( CvMLData* data, CvRTParams params=CvRTParams() ); virtual float predict( const CvMat* sample, const CvMat* missing = 0 ) const; virtual float predict_prob( const CvMat* sample, const CvMat* missing = 0 ) const; CV_WRAP virtual bool train( const cv::Mat trainData, int tflag, const cv::Mat responses, const cv::Mat varIdx=cv::Mat(), const cv::Mat sampleIdx=cv::Mat(), const cv::Mat varType=cv::Mat(), const cv::Mat missingDataMask=cv::Mat(), CvRTParams params=CvRTParams() ); CV_WRAP virtual float predict( const cv::Mat sample, const cv::Mat missing = cv::Mat() ) const; CV_WRAP virtual float predict_prob( const cv::Mat sample, const cv::Mat missing = cv::Mat() ) const; CV_WRAP virtual cv::Mat getVarImportance(); CV_WRAP virtual void clear(); virtual const CvMat* get_var_importance(); virtual float get_proximity( const CvMat* sample1, const CvMat* sample2, const CvMat* missing1 = 0, const CvMat* missing2 = 0 ) const; virtual float calc_error( CvMLData* data, int type , std::vectorfloat* resp = 0 ); // type in {CV_TRAIN_ERROR, CV_TEST_ERROR} virtual float get_train_error(); virtual void read( CvFileStorage* fs, CvFileNode* node ); virtual void write( CvFileStorage* fs, const char* name ) const; CvMat* get_active_var_mask(); CvRNG* get_rng(); int get_tree_count() const; CvForestTree* get_tree(int i) const; protected: virtual std::string getName() const; virtual bool grow_forest( const CvTermCriteria term_crit ); // array of the trees of the forest CvForestTree** trees; CvDTreeTrainData* data; int ntrees; int nclasses; double oob_error; CvMat* var_importance; int nsamples; cv::RNG* rng; CvMat* active_var_mask; }; 使用CvRTrees类,来对手写体数据作分类 // Example : random forest (tree) learning // Author : Toby Breckon, toby.breckon@cranfield.ac.uk // Copyright (c) 2011 School of Engineering, Cranfield University // License : LGPL - http://www.gnu.org/licenses/lgpl.html #include cv.h // opencv general include file #include ml.h // opencv machine learning include file #include stdio.h using namespace cv; // OpenCV API is in the C++ "cv" namespace /******************************************************************************/ // global definitions (for speed and ease of use) //手写体数字识别 #define NUMBER_OF_TRAINING_SAMPLES 3823 #define ATTRIBUTES_PER_SAMPLE 64 #define NUMBER_OF_TESTING_SAMPLES 1797 #define NUMBER_OF_CLASSES 10 // N.B. classes are integer handwritten digits in range 0-9 /******************************************************************************/ // loads the sample database from file (which is a CSV text file) int read_data_from_csv(const char* filename, Mat data, Mat classes, int n_samples ) { float tmp; // if we can't read the input file then return 0 FILE* f = fopen( filename, "r" ); if( !f ) { printf("ERROR: cannot read file %s\n", filename); return 0; // all not OK } // for each sample in the file for(int line = 0; line n_samples; line++) { // for each attribute on the line in the file for(int attribute = 0; attribute (ATTRIBUTES_PER_SAMPLE + 1); attribute++) { if (attribute 64) { // first 64 elements (0-63) in each line are the attributes fscanf(f, "%f,", tmp); data.atfloat(line, attribute) = tmp; // printf("%f,", data.atfloat(line, attribute)); } else if (attribute == 64) { // attribute 65 is the class label {0 ... 9} fscanf(f, "%f,", tmp); classes.atfloat(line, 0) = tmp; // printf("%f\n", classes.atfloat(line, 0)); } } } fclose(f); return 1; // all OK } /******************************************************************************/ int main( int argc, char** argv ) { for (int i=0; i argc; i++) std::coutargv std::endl; // lets just check the version first printf ("OpenCV version %s (%d.%d.%d)\n", CV_VERSION, CV_MAJOR_VERSION, CV_MINOR_VERSION, CV_SUBMINOR_VERSION); //定义训练数据与标签矩阵 Mat training_data = Mat(NUMBER_OF_TRAINING_SAMPLES, ATTRIBUTES_PER_SAMPLE, CV_32FC1); Mat training_classifications = Mat(NUMBER_OF_TRAINING_SAMPLES, 1, CV_32FC1); //定义测试数据矩阵与标签 Mat testing_data = Mat(NUMBER_OF_TESTING_SAMPLES, ATTRIBUTES_PER_SAMPLE, CV_32FC1); Mat testing_classifications = Mat(NUMBER_OF_TESTING_SAMPLES, 1, CV_32FC1); // define all the attributes as numerical // alternatives are CV_VAR_CATEGORICAL or CV_VAR_ORDERED(=CV_VAR_NUMERICAL) // that can be assigned on a per attribute basis Mat var_type = Mat(ATTRIBUTES_PER_SAMPLE + 1, 1, CV_8U ); var_type.setTo(Scalar(CV_VAR_NUMERICAL) ); // all inputs are numerical // this is a classification problem (i.e. predict a discrete number of class // outputs) so reset the last (+1) output var_type element to CV_VAR_CATEGORICAL var_type.atuchar(ATTRIBUTES_PER_SAMPLE, 0) = CV_VAR_CATEGORICAL; double result; // value returned from a prediction //加载训练数据集和测试数据集 if (read_data_from_csv(argv , training_data, training_classifications, NUMBER_OF_TRAINING_SAMPLES) read_data_from_csv(argv , testing_data, testing_classifications, NUMBER_OF_TESTING_SAMPLES)) { /********************************步骤1:定义初始化Random Trees的参数******************************/ float priors ); CvRTrees* rtree = new CvRTrees; rtree-train(training_data, CV_ROW_SAMPLE, training_classifications, Mat(), Mat(), var_type, Mat(), params); // perform classifier testing and report results Mat test_sample; int correct_class = 0; int wrong_class = 0; int false_positives = {0,0,0,0,0,0,0,0,0,0}; printf( "\nUsing testing database: %s\n\n", argv ); for (int tsample = 0; tsample NUMBER_OF_TESTING_SAMPLES; tsample++) { // extract a row from the testing matrix test_sample = testing_data.row(tsample); /********************************步骤3:预测*********************************************/ result = rtree-predict(test_sample, Mat()); printf("Testing Sample %i - class result (digit %d)\n", tsample, (int) result); // if the prediction and the (true) testing classification are the same // (N.B. openCV uses a floating point decision tree implementation!) if (fabs(result - testing_classifications.atfloat(tsample, 0)) = FLT_EPSILON) { // if they differ more than floating point error = wrong class wrong_class++; false_positives ++; } else { // otherwise correct correct_class++; } } printf( "\nResults on the testing database: %s\n" "\tCorrect classification: %d (%g%%)\n" "\tWrong classifications: %d (%g%%)\n", argv , correct_class, (double) correct_class*100/NUMBER_OF_TESTING_SAMPLES, wrong_class, (double) wrong_class*100/NUMBER_OF_TESTING_SAMPLES); for (int i = 0; i NUMBER_OF_CLASSES; i++) { printf( "\tClass (digit %d) false postives %d (%g%%)\n", i, false_positives , (double) false_positives *100/NUMBER_OF_TESTING_SAMPLES); } // all matrix memory free by destructors // all OK : main returns 0 return 0; } // not OK : main returns -1 return -1; } /******************************************************************************/
2217 次阅读|0 个评论
用随机森林模型替代常用的回归和分类模型
热度 6 lixinhai 2013-9-27 16:57
随机森林模型有着惊人的准确性,可以替代一般线性模型(线性回归、方差分析等)和广义线性模型(逻辑斯蒂回归、泊松回归等)等等。 我2012年在人民大学组织的R语言会议上介绍了随机森林的用法(报告文件在 http://cos.name/wp-content/uploads/2012/05/17-lixinhai-random-forest.pdf )。以后不时有人给我写信交流模型使用心得,索要数据和代码。我感觉当时的介绍不太充分。正巧《应用昆虫学报》的主编戈峰老师邀我写一篇统计方法的稿件,我便把随机森林的基本原理和应用案例重新细化,形成一篇文章( http://www.ent-bull.com.cn/viewmulu.aspx?qi_id=1031mid=31191xuhao=42 )。文章的R语言代码显示效果不好(没有颜色,断行多),我便把文章和代码放到这个博客上。 文章正文(引用: 李欣海 . 2013. 随机森林模型在分类与回归分析中的应用 . 应用昆虫学报 , 50 , 1190-1197 ) 前言 随机森林( Random Forest )是一种基于分类树( classification tree )的算法( Breiman , 2001 )。这个算法需要模拟和迭代,被归类为机器学习中的一种方法。经典的机器学习模型是神经网络( Hopfield , 1982 ),有半个多世纪的历史了。神经网络预测精确,但是计算量很大。上世纪八十年代 Breiman 等人发明了分类和回归树( Classification and Regression Tree 简称 CART )的算法( Breiman et al . , 1984 ),通过反复二分数据进行分类或回归,计算量大大降低。 2001 年 Breiman 和 Cutler 借鉴贝尔实验室的 Ho 所提出的随机决策森林( random decision forests )( Ho , 1995 , 1998 )的方法,把分类树组合成随机森林( Breiman , 2001 ),即在变量(列)的使用和数据(行)的使用上进行随机化,生成很多分类树,再汇总分类树的结果。后来 Breiman 在机器学习杂志上发表了他和 Cutler 设计的随机森林的算法( Breiman , 2001 )。这篇文章被大量引用(根据 Google Scholar ,该文章至 2013 年被引用 9000 多次),成为机器学习领域的一个里程碑。 随机森林在运算量没有显著提高的前提下提高了预测精度。随机森林对多元公线性不敏感,结果对缺失数据和非平衡的数据比较稳健,可以很好地预测多达几千个解释变量的作用( Breiman , 2001 ),被誉为当前最好的算法之一( Iverson et al . , 2008 )。在机器学习的诸多算法中,随机森林因高效而准确而备受关注,在各行各业得到越来越多的应用( e.g Cutler et al. , 2007 ; Genuer et al . , 2010 )。 随机森林的算法最初以 FORTRUN 语言编码( Liaw , 2012 )。现在可以通过 R 语言或 SAS 等工具实现。 R 语言是一种用于统计分析和绘图的语言和操作环境( R Development Core Team , 2013 )。它是自由、免费、源代码开放的软件,近年来已经成为国际学术领域应用最广的统计工具。在国内, R 语言也在迅速普及。本文基于 R 语言介绍随机森林的应用。 R 语言中有两个软件包可以运行随机森林,分别是 randomForest ( Liaw , 2012 )和 party 。本文介绍 randomForest 的用法。 本文面向没有或只有初步 R 语言基础的生态学工作者,以三个案例,通过运行案例中给出的 R 语言代码,读者可以运行随机森林的算法,进行分类或回归分析,得到变量的重要性、模型的误差等指标,并可以进行预测。 Breiman 发表随机森林后,有若干文章深入探讨其算法( Biau , 2012 ),变量的比较( Archer and Kirnes , 2008 ; Groemping , 2009 )和变量间的交互作用( Winham et al . , 2012 )等。本文旨在介绍随机森林的应用方法,不涉及其本身的算法,也不涉及同其他平行方法的比较。 1 随机森林的原理 同其他模型一样,随机森林可以解释若干自变量( X1 、 X2 、 ... 、 Xk )对因变量 Y 的作用。如果因变量 Y 有 n 个观测值,有 k 个自变量与之相关;在构建分类树的时候,随机森林会随机地在原数据中重新选择 n 个观测值,其中有的观测值被选择多次,有的没有被选到,这是 Bootstrap 重新抽样的方法。同时,随机森林随机地从 k 个自变量选择部分变量进行分类树节点的确定。这样,每次构建的分类树都可能不一样。一般情况下,随机森林随机地生成几百个至几千个分类树,然后选择重复程度最高的树作为最终结果( Breiman , 2001 )。 2 随机森林的应用 随机森林可以用于分类和回归。当因变量 Y 是分类变量时,是分类;当因变量 Y 是连续变量时,是回归。自变量 X 可以是多个连续变量和多个分类变量的混合。在下面 3 个案例中,判别分析和对有无数据的分析是分类问题,对连续变量 Y 的解释是回归问题。 2.1 在判别分析中的应用 判别分析( discriminant analysis )是在因变量 Y 的几个分类水平明确的条件下,根据若干自变量判别每个观测值的类型归属问题的一种多变量统计分析方法。判别与分类在统计学概念上有所交叉,在本文中不强调两者的区别。案例 1 中有 3 种昆虫( A 、 B 和 C )形态接近,不过可以通过 4 个长度指标( L1 、 L2 、 L3 和 L4 )进行种类的识别。具体数据如表 1 。 表 1 3 种昆虫及其用于分类的 4 个量度指标 Table 1 The four length indices for classifying threeinsect species 物种 Species 量度 ( Length ) L1 L2 L3 L4 A 16 27 31 33 A 15 23 30 30 A 16 27 27 26 A 18 20 25 23 A 15 15 31 32 A 15 32 32 15 A 12 15 16 31 B 8 23 23 11 B 7 24 25 12 B 6 25 23 10 B 8 45 24 15 B 9 28 15 12 B 5 32 31 11 C 22 23 12 42 C 25 25 14 60 C 34 25 16 52 C 30 23 21 54 C 25 20 11 55 C 30 23 21 54 C 25 20 11 55 通过运行下列 R 语言代码,可以得到随机森林的结果 RF1 。 R 语言中的“ # ”表示注释,其后面的语句不被执行。当随机森林用于分类时,其结果 RF1 包含混淆矩阵( confusionmatrix )(表 2 ),显示判别分析的错误率。 install.packages(randomForest) # 安装随机森林程序包(每台计算机只需安装一次) library(randomForest) # 调用随机森林程序包(每次运行都要调用) insect - read.csv(d:/data/insects.csv, header = TRUE) # 从硬盘读入数据到对象 insect RF1 - randomForest(insect , insect , importance=TRUE, ntree=10000) # 运行随机森林模型 RF1 # 显示模型结果,包括误差率和混淆矩阵(表 2 ) 其中 insect 是一个包含 5 个变量 20 个记录的数据表。 insect 表示昆虫的量度,是一个 4 乘以 20 的矩阵; insect 表示昆虫的物种类别,是 20 个物种名组成的一个向量。表 2 显示模型对 A 的判别错误率为 28.6% ,对 B 和 C 的判别错误率为 0 。 表 2 随机森林(用于分类时)的混淆矩阵显示昆虫分类误差 Table2 Random Forest outputs a confusion matrix showing the classification error ​ A B C 分类误差 Class error A 5 2 0 0.286 B 0 6 0 0 C 0 0 7 0 注:每行表示实际的类别,每列表示随机森林判定的类别。 The row indicates real classification;the column indicates predicted classification. 随机森林的结果内含判别函数,可以用下列代码根据新的量度判断昆虫的物种类别。 new.data - data.frame(L1=20, L2=50, L3=30, L4=20) # 一个新的昆虫的量度 predict(RF1, new.data, type=prob) # 判别该量度的昆虫归类为 A 、 B 和 C 的概率 predict(RF1, new.data, type=response) # 判别该量度的昆虫的类别 在该案例中,该量度判别为 A 、 B 和 C 的概率分别为 82.4% 、 9.4% 和 8.2% 。随机森林将其判别为 A 。 2.2 对有无数据的分析 对于有或无、生或死、发生或不发生等二分变量的分析,一般用逻辑斯蒂回归( logistic regression )的方法。逻辑斯蒂回归实质上是对因变量 Y 作两个分类水平的判别。逻辑斯蒂回归对自变量的多元共线性非常敏感,要求自变量之间相互独立。随机森林则完全不需要这个前提条件。 Breiman 在 2001 年发表了具有革命意义的文章,批判了当前主流的统计学方法,指出经典模型如逻辑斯蒂回归经常给出不可靠的结论,而随机森林准确而可靠。 案例 2 以朱鹮为例,说明该方法的具体应用。朱鹮的巢址选择受环境变量的影响( Li et al. , 2006 , 2009 ; 翟天庆和李欣海, 2012 )。假设朱鹮选择一个地方营巢的概率取决于下列自变量:土地利用类型(森林、草地、灌丛或农田等)、海拔、坡度、温度、降水、人类干扰指数等。该问题的因变量为朱鹮 1981 年至 2008 年间的 532 个巢( Y=1 ),以及在朱鹮巢区的系统选择的(等间距) 2538 个点( Y=0 )(图 3A );自变量为这 3070 个地点对应的 8 个环境变量。应用随机森林对朱鹮巢址选择进行分析的 R 语言代码如下: ibis - read.csv('d:/data/ibis.csv', header = TRUE) # 从硬盘读入数据 ibis$use - as.factor(ibis$use) # 定义巢址选择与否( 0 或 1 )为分类变量。这是因变量 Y 。 ibis$landcover - as.factor(ibis$landcover) # 定义土地利用类型为分类变量 RF2 - randomForest(ibis , ibis , importance=TRUE, ntree=1000) # 运行随机森林 varImpPlot(RF2) # 图示自变量对的巢址选择的重要性 图 1 随机森林对影响朱鹮巢址选择的自变量的重要性进行排序 * Fig. 1 Ranking variable importance thatassociated with nest site selection of the crested ibis by Random Forest*. *MeanDecreaseAccuracy 衡量把一个变量的取值变为随机数,随机森林预测准确性的降低程度。该值越大表示该变量的重要性越大 。 MeanDecreaseGini 通过基尼( Gini )指数计算每个变量对分类树每个节点上观测值的异质性的影响,从而比较变量的重要性。该值越大表示该变量的重要性越大。 prec_ann 是年总降水量; t_ann 是年平均温度; elevation 是海拔; GDP 是国内生产总值; landcover 是土地利用类型; slope 是坡度; pop 是人口密度; footprint 是人类干扰指数。 从图 1 可以看到不同指标指示的变量重要性会略有差距,但是差距不会很大。 随机森林可以给出每个自变量对因变量的作用。下列 R 代码给出海拔对巢址选择的影响,结果在图 2 中,表示中等程度的海拔最适宜营巢。 partialPlot(RF2, ibis, elevation, 0, main='' , xlab='Elevation (m)', ylab=Variable effect) 图 2 随机森林算出的海拔对朱鹮巢址选择的影响 Fig. 2 Partial effect of elevation onnest site selection of the crested ibis. 随机森林可以通过下列代码预测任何地点朱鹮营巢的概率(图 3 ) pred - predict(RF2, ibis, type=prob)# 计算原数据 ibis 中 3070 个地点被朱鹮选择营巢的概率 # 绘制图 3A plot(ibis$x, ibis$y, type = n, xlab = ' 经度 Longitude', ylab = ' 纬度 Latitude') # 绘制坐标轴 for (i in 1:length(ibis$x)){ # 循环语句,从 1 到 3070 if(ibis$use !=1) points(ibis$x , ibis$y , col =grey80, cex = .8, pch = 19) # 非营巢点为灰色 if(ibis$use ==1) points(ibis$x , ibis$y , col = black, cex = .8, pch = 19) # 营巢点为黑色 } # 绘制图 3B ,颜色深的营巢概率高 plot(ibis$x, ibis$y, type = n, xlab = ' 经度 Longitude', ylab = ' 纬度 Latitude') # 绘制坐标轴 for (iin 1:length(ibis$x)){ # 循环语句,从 1 到 3070 图 3 A 朱鹮的巢址(黑色)和对照点(灰色); B 随机森林算出的每个点朱鹮选择营巢的概率(深色概率高) Fig.3 A. the nest site ofthe crested ibis (black dots) and the pseudo-absence points (grey dots); B. theprobability of nest site selection of the crested ibis calculated by RandomForest (dark color means higher probability) 2.3 回归分析 当因变量 Y 为连续变量时,随机森林通过一组自变量 X 对 Y 进行解释,类似经典的回归分析。 案例 3 依旧以朱鹮为例,介绍随机森林在回归分析上的应用。朱鹮是依赖湿地的鸟类,其生境可以分为一个个相邻的集水区。每个集水区内朱鹮的巢数同集水区的环境变量相关。用环境变量(包括连续变量和分类变量两个类型)解释集水区内朱鹮的巢数,可以被看作为一个回归的问题。下列代码读取数据并显示数据前 6 行: sheds - read.csv('d:/data/watersheds4.csv', header=T) # 读取数据 head(sheds) # 显示数据 sheds 的前 6 行,如表 3 所示。 NA 表示缺失值。 表 3 朱鹮栖息地每个集水区内朱鹮的巢数以及环境变量 Table 3 The number of nests andenvironmental variables for every watershed in the habitat of the crested ibis Nests Elevation Footprint Temperature Rice_paddy Water_body Wetland Elev_SD 1 597.83 44.54 14.02 0.14 0.52 0.07 197.54 0 588.74 32.41 14.09 0.15 0.08 0.01 148.32 0 513.84 NA 14.66 0 0.16 0 28.84 5 609.33 30.2 14.29 1.17 1.03 1.21 184.58 0 NA 35.88 13.32 0.18 0.17 0.03 NA 2 651.08 47.62 14.41 1.11 0.34 0.38 121.37 对于缺失数据, R 语言的 randomForest 软件包通过 na.roughfix 函数用中位数(对于连续变量)或众数(对于分类变量)来进行替换。 Dat.fill - na.roughfix(sheds) # 用中位数或众数替代缺失值 RF3 -randomForest(Nests ~ Elevation + Footprint + Temperature + Rice_paddy +Water_body + Wetland + Elev_SD, data=Dat.fill, ntree=5000, importance=TRUE,na.action=na.roughfix, mtry=3) # 运行随机森林 RF3 # 模型结果,显示残差的平方,以及解释变异(环境变量 X 对巢数 Y 的解释)的百分率 mtry 指定分类树每个节点用来二分数据的自变量的个数。如果 mtry 没有被指定,随机森林用缺省值。对于分类(判别)分析( Y 是分类变量),缺省值是自变量总数的平方根;如果是回归分析( Y 是连续变量),缺省值是自变量总数的 1/3 。 3 讨论 本文以三个案例介绍了随机森林的具体应用。随机森林结构比较复杂,但是它却极端易用,需要的假设条件(如变量的独立性、正态性等)比逻辑斯蒂回归等模型要少得多。它也不需要检查变量的交互作用和非线性作用是否显著。在大多数情况下模型参数的缺省设置可以给出最优或接近最优的结果。使用者可以调节 mtry 的取值来检查模型的缺省值受否给出误差最小的结果。使用者也可以指定所用的分类树的数量。在计算负荷可以接受的情况下分类树的数量越大越好。图 4 可以帮助使用者判断最小的分类树的数量,以便节省计算时间。 目前,人们已经对多种机器学习的模型进行了比较( e.g. Li and Wang , 2013 ; Kampichler et al . , 2010 ),随机森林经常独占鳌头( Kampichler et al . , 2010 ; Li et al . , 2012 )。随机森林通过产生大量的分类树,建立若干自 变量 X 和一个因变量 Y 的关系。随机森林的优点是:它的学习过程很快。在处理很大的数据时,它依旧非常高效。随机森林可以处理大量的多达几千个的自变量( Breiman , 2001 )。现有的随机森林算法评估所有变量的重要性,而不需要顾虑一般回归问题面临的多元共线性的问题。它包含估计缺失值的算法,如果有一部分的资料遗失,仍可以维持一定的准确度。随机森林中分类树的算法自然地包括了变量的交互作用( interaction )( Cutler, et al . , 2007 ),即 X1 的变化导致 X2 对 Y 的作用发生改变。交互作用在其他模型中(如逻辑斯蒂回归)因其复杂性经常被忽略。随机森林对离群值不敏感,在随机干扰较多的情况下表现稳健。随机森林不易产生对数据的过度拟合( overfit )( Breiman , 2001 ),然而这点尚有争议( Elith and Graham , 2009 )。 随机森林通过袋外误差( out-of-bag error )估计模型的误差。对于分类问题,误差是分类的错误率;对于回归问题,误差是残差的方差。随机森林的每棵分类树,都是对原始记录进行有放回的重抽样后生成的。每次重抽样大约 1/3 的记录没有被抽取( Liaw , 2012 )。没有被抽取的自然形成一个对照数据集。所以随机森林不需要另外预留部分数据做交叉验证,其本身的算法类似交叉验证,而且袋外误差是对预测误差的无偏估计( Breiman , 2001 )。 随机森林的缺点是它的算法倾向于观测值较多的类别(如果昆虫 B 的记录较多,而且昆虫 A 、 B 和 C 间的差距不大,预测值会倾向于 B )。另外,随机森林中水平较多的分类属性的自变量(如土地利用类型 20 个类别)比水平较少的分类属性的自变量(气候区类型 10 个类别)对模型的影响大( Deng et al . , 2011 )。总之,随机森林功能强大而又简单易用,相信它会对各行各业的数据分析产生积极的推动作用。 参考文献 Breiman L. 2001. Random forests. Machine Learning, 45, 5-32 Hopfield JJ. 1982. Neural networks and physical systems withemergent collective computational abilities. Proceedings of the NationalAcademy of Sciences of the United States of America-Biological Sciences, 79,2554-2558 Breiman L, Friedman JH, Olshen RA, Stone CJ. 1984. Classificationand Regression Trees. Chapman and Hall. Ho TK. 1995. Random Decision Forest. in Proceedings of the 3rdInternational Conference on Document Analysis and Recognition. 278-282. Ho TK. 1998. The random subspace method for constructing decisionforests. in IEEE Transactions on Pattern Analysis and Machine Intelligence.832-844. Breiman L. 2001. Statistical modeling: The two cultures.Statistical Science, 16, 199-215 Iverson LR, Prasad AM, Matthews SN, Peters M. 2008. Estimatingpotential habitat for 134 eastern US tree species under six climate scenarios.Forest Ecology and Management, 254, 390-406 Cutler DR, Edwards TC, Jr., Beard KH, Cutler A, Hess KT. 2007.Random forests for classification in ecology. Ecology, 88, 2783-2792 Genuer R, Poggi JM, Tuleau-Malot C. 2010. Variable selection usingrandom forests. Pattern Recognition Letters, 31, 2225-2236 Liaw A.2012. Package randomForest. R Development Core Team. 2013. R: A Language and Environment forStatistical Computing. R Foundation for Statistical Computing. Biau G. 2012. Analysis of a random forests model. Journal ofMachine Learning Research, 13, 1063-1095 Archer KJ, Kirnes RV. 2008. Empirical characterization of randomforest variable importance measures. Computational Statistics DataAnalysis, 52, 2249-2260 Groemping U. 2009. Variable importance assessment in regression:linear regression versus random forest. American Statistician, 63, 308-319 Winham S, Wang X, de Andrade M, Freimuth R, Colby C, Huebner M, BiernackaJ. 2012. Interaction detection with random forests in high-dimensional data.Genetic Epidemiology, 36, 142-142 Hosmer Jr DW, Lemeshow S. 1989. Applied Logistic Regression. JohnWiley Sons. Li XH, Tian HD, Li DM. 2009. Why the crested ibis declined in themiddle twentieth century. Biodiversity and Conservation, 18, 2165-2172 Li XH, Li DM, Ma ZJ, Schneider DC. 2006. Nest site use by crestedibis: dependence of a multifactor model on spatial scale. Landscape Ecology,21, 1207-1216 Zhai TQ ( 翟天庆 ) , Li XH ( 李欣海 ). 2012. Climate change induced potential range shift of thecrested ibis based on ensemble models. Acta Ecologica Sinica ( 生态学报 ), 32, 2361-2370 (in Chinese) Li XH, Wang Y. 2013. Applying various algorithms for speciesdistribution modeling. Integrative Zoology, 8, 124-135 Kampichler C, Wieland R, Calmé S, Weissenberger H, Arriaga-WeissS. 2010. Classification in conservation biology: A comparison of five machine-learningmethods. Ecological Informatics, 5, 441-450 Li XH, Tian HD, Li RQ, Song ZM, Zhang FC, Xu M, Li DM. 2012.Vulnerability of 208 endemic or endangered species in China to the effects ofclimate change Regional Environmental Change, DOI: 10.1007/s10113-10012-10344-z Elith J, Graham CH. 2009. Do they? How do they? Why do theydiffer? On finding reasons for differing performances of species distributionmodels. Ecography, 32, 66-77 Deng H, Runger G, Tuv E. 2011. Bias of importance measures formulti-valued attributes and solutions. in Proceedings of the 21st InternationalConference on Artificial Neural Networks (ICANN).
91263 次阅读|10 个评论
随机森林(Random Forest)模型
热度 5 lixinhai 2012-9-23 00:55
随机森林是一种比较新的机器学习模型。经典的机器学习模型是神经网络,有半个多世纪的历史了。神经网络预测精确,但是计算量很大。上世纪八十年代 Breiman 等人发明分类树的算法 ( Breiman et al. 1984 ) ,通过反复二分数据进行分类或回归,计算量大大降低。 2001 年 Breiman 把分类树组合成随机森林 ( Breiman 2001a ) ,即在变量(列)的使用和数据(行)的使用上进行随机化,生成很多分类树,再汇总分类树的结果。随机森林在运算量没有显著提高的前提下提高了预测精度。随机森林对多元公线性不敏感,结果对缺失数据和非平衡的数据比较稳健,可以很好地预测多达几千个解释变量的作用 ( Breiman 2001b ) ,被誉为当前最好的算法之一 ( Iverson et al. 2008 ) 。 今年 5 月在人大组织的 R 语言会议上,我用朱鹮的例子介绍了随机森林的原理和应用。有些同学要求拷贝演讲材料。这个材料在统计之都( http://cos.name )上有。为了更方便地下载,我把它放在这里 Random Forest.pdf 。 这个 pdf 共 25 页,首先是原理,然后列举 R 的两个运行随机森林包,后面有数据格式、代码和结果。随机森林完成两个任务:回归( y 为连续变量时)和判别( y 为分类变量时)。这两个的任务的代码略有不同。这个材料对于要编代码运行随机森林模型的人有用。没有任何理论基础的人(但是需要有R的知识),看过这个 pdf 后,可以应用上面的代码运行随机森林,解释因变量的贡献,进行预测。本人强烈建议使用者首先阅读Breiman在2001年发表的两篇文章(见参考文献),然后再应用这个模型。随机森林对数据前提条件的要求(正态性、独立性等)比广义线性模型等要宽松得多,应用前景非常广阔。 参考文献 Breiman, L. 2001a. Random forests. Machine Learning 45 :5-32. Breiman, L. 2001b. Statistical modeling: The two cultures. Statistical Science 16 :199-215. Breiman, L., J. H. Friedman, R. A. Olshen, and C. J. Stone 1984. Classification and Regression Trees. Chapman and Hall, New York. Iverson, L. R., A. M. Prasad, S. N. Matthews, and M. Peters. 2008. Estimating potential habitat for 134 eastern US tree species under six climate scenarios. Forest Ecology and Management 254 :390-406.
60443 次阅读|11 个评论

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-6-3 17:45

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部