随机森林算法的简单总结及python实现

2024-08-27 20:08

本文主要是介绍随机森林算法的简单总结及python实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 随机森林是数据挖掘中非常常用的分类预测算法,以分类或回归的决策树为基分类器。算法的一些基本要点:

  *对大小为m的数据集进行样本量同样为m的有放回抽样;

        *对K个特征进行随机抽样,形成特征的子集,样本量的确定方法可以有平方根、自然对数等;

        *每棵树完全生成,不进行剪枝;

        *每个样本的预测结果由每棵树的预测投票生成(回归的时候,即各棵树的叶节点的平均)


  著名的Python机器学习包scikit learn的文档对此算法有比较详尽的介绍: http://scikit-learn.org/stable/modules/ensemble.html#random-forests

  出于个人研究和测试的目的,基于经典的Kaggle 101 泰坦尼克号乘客的数据集,建立模型并进行评估。比赛页面及相关数据集的下载:https://www.kaggle.com/c/titanic

  泰坦尼克号的沉没,是历史上非常著名的海难。突然感到,自己面对的不再是冷冰冰的数据,而是用数据挖掘的方法,去研究具体的历史问题,也是饶有兴趣。言归正传,模型的主要的目标,是希望根据每个乘客的一系列特征,如性别、年龄、舱位、上船地点等,对其是否能生还进行预测,是非常典型的二分类预测问题。数据集的字段名及实例如下:


PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
103Braund, Mr. Owen Harrismale2210A/5 211717.25 S
211Cumings, Mrs. John Bradley (Florence Briggs Thayer)female3810PC 1759971.2833C85C
313Heikkinen, Miss. Lainafemale2600STON/O2. 31012827.925 S
411Futrelle, Mrs. Jacques Heath (Lily May Peel)female351011380353.1C123S
503Allen, Mr. William Henrymale35003734508.05 S

值得说明的是,SibSp是指sister brother spouse,即某个乘客随行的兄弟姐妹、丈夫、妻子的人数,Parch指parents,children


下面给出整个数据处理及建模过程,基于ubuntu+python 3.4 ( anaconda科学计算环境已经集成一系列常用包,pandas numpy sklearn等,这里强烈推荐)

懒得切换输入法,写的时候主要的注释都是英文,中文的注释是后来补充的 :-)

# -*- coding: utf-8 -*-
"""
@author: kim
"""from model import * #载入基分类器的代码#ETL:same procedure to training set and test set
training=pd.read_csv('train.csv',index_col=0)
test=pd.read_csv('test.csv',index_col=0)
SexCode=pd.DataFrame([1,0],index=['female','male'],columns=['Sexcode'])  #将性别转化为01
training=training.join(SexCode,how='left',on=training.Sex)
training=training.drop(['Name','Ticket','Embarked','Cabin','Sex'],axis=1) #删去几个不参与建模的变量,包括姓名、船票号,船舱号
test=test.join(SexCode,how='left',on=test.Sex)
test=test.drop(['Name','Ticket','Embarked','Cabin','Sex'],axis=1)
print('ETL IS DONE!')#MODEL FITTING
#===============PARAMETER AJUSTMENT============
min_leaf=1
min_dec_gini=0.0001
n_trees=5
n_fea=int(math.sqrt(len(training.columns)-1))
#=============================================='''
BEST SCORE:0.83
min_leaf=30
min_dec_gini=0.001
n_trees=20
'''#ESSEMBLE BY RANDOM FOREST
FOREST={}
tmp=list(training.columns)
tmp.pop(tmp.index('Survived'))
feaList=pd.Series(tmp)
for t in range(n_trees):
#    fea=[]feasample=feaList.sample(n=n_fea,replace=False)#select feature fea=feasample.tolist()fea.append('Survived')
#        feaNew=fea.append(target)subset=training.sample(n=len(training),replace=True) #generate the dataset with replacementsubset=subset[fea]
#    print(str(t)+' Classifier built on feature:')
#    print(list(fea))FOREST[t]=tree_grow(subset,'Survived',min_leaf,min_dec_gini) #save the tree#MODEL PREDICTION
#======================
currentdata=training
output='submission_rf_20151116_30_0.001_20'
#======================prediction={}
for r in currentdata.index:#a rowprediction_vote={1:0,0:0}row=currentdata.get(currentdata.index==r)for n in range(n_trees):tree_dict=FOREST[n] #a treep=model_prediction(tree_dict,row)prediction_vote[p]+=1vote=pd.Series(prediction_vote)prediction[r]=list(vote.order(ascending=False).index)[0]#the vote result
result=pd.Series(prediction,name='Survived_p')
#del prediction_vote
#del prediction#result.to_csv(output)t=training.join(result,how='left')
accuracy=round(len(t[t['Survived']==t['Survived_p']])/len(t),5)
print(accuracy)

上述是随机森林的代码,如上所述,随机森林是一系列决策树的组合,决策树每次分裂,用Gini系数衡量当前节点的“不纯净度”,如果按照某个特征的某个分裂点对数据集划分后,能够让数据集的Gini下降最多(显著地减少了数据集输出变量的不纯度),则选为当前最佳的分割特征及分割点。代码如下:


# -*- coding: utf-8 -*-
"""
@author: kim
"""import pandas as pd
import numpy as np
#import sklearn as sk
import mathdef tree_grow(dataframe,target,min_leaf,min_dec_gini):tree={} #renew a treeis_not_leaf=(len(dataframe)>min_leaf)if is_not_leaf:fea,sp,gd=best_split_col(dataframe,target)if gd>min_dec_gini:tree['fea']=featree['val']=sp
#            dataframe.drop(fea,axis=1) #1116 modifiedl,r=dataSplit(dataframe,fea,sp)l.drop(fea,axis=1)r.drop(fea,axis=1)tree['left']=tree_grow(l,target,min_leaf,min_dec_gini)tree['right']=tree_grow(r,target,min_leaf,min_dec_gini)else:#return a leafreturn leaf(dataframe[target])else:return leaf(dataframe[target])return treedef leaf(class_lable):tmp={}for i in class_lable:if i in tmp:tmp[i]+=1else:tmp[i]=1s=pd.Series(tmp)s.sort(ascending=False)return s.index[0]def gini_cal(class_lable):p_1=sum(class_lable)/len(class_lable)p_0=1-p_1gini=1-(pow(p_0,2)+pow(p_1,2))return ginidef dataSplit(dataframe,split_fea,split_val):left_node=dataframe[dataframe[split_fea]<=split_val]right_node=dataframe[dataframe[split_fea]>split_val]return left_node,right_nodedef best_split_col(dataframe,target_name):best_fea=''#modified 1116best_split_point=0 col_list=list(dataframe.columns)col_list.remove(target_name)gini_0=gini_cal(dataframe[target_name])n=len(dataframe)gini_dec=-99999999for col in col_list:node=dataframe[[col,target_name]]unique=node.groupby(col).count().indexfor split_point in unique: #unique valueleft_node,right_node=dataSplit(node,col,split_point)if len(left_node)>0 and len(right_node)>0:gini_col=gini_cal(left_node[target_name])*(len(left_node)/n)+gini_cal(right_node[target_name])*(len(right_node)/n)if (gini_0-gini_col)>gini_dec:                 gini_dec=gini_0-gini_col#decrease of impuritybest_fea=col                    best_split_point=split_point           #print(col,split_point,gini_0-gini_col)return best_fea,best_split_point,gini_decdef model_prediction(model,row): #row is a dffea=model['fea']val=model['val']left=model['left']right=model['right']if row[fea].tolist()[0]<=val:#get the valuebranch=leftelse:branch=rightif ('dict' in str( type(branch) )):prediction=model_prediction(branch,row)else:prediction=branchreturn prediction

实际上,上面的代码还有很大的效率提升的空间,数据集不是很大的情况下,如果选择一个较大的输入参数,例如生成100棵树,就会显著地变慢;同时,将预测结果提交至kaggle进行评测,发现在测试集上的正确率不是很高,比使用sklearn里面相应的包进行预测的正确率(0.77512)要稍低一点 :-(  如果要提升准确率,两个大方向: 构造新的特征;调整现有模型的参数。

这里是抛砖引玉,欢迎大家对我的建模思路和算法的实现方法提出修改意见。


转自:http://blog.csdn.net/lo_cima/article/details/50533010


这篇关于随机森林算法的简单总结及python实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1112652

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig