【机器学习基础】数学推导+纯Python实现机器学习算法26:随机森林
Python机器学习算法实现
Author:louwill
Machine Learning Lab
自从第14篇文章结束,所有的单模型基本就讲完了。而后我们进入了集成学习的系列,整整花了5篇文章的篇幅来介绍集成学习中最具代表性的Boosting框架。从AdaBoost到GBDT系列,对XGBoost、LightGBM和CatBoost作了较为详细的了解。本文作为集成学习的最后一篇文章,来介绍与Boosting框架有所不同的Bagging框架。
Bagging与随机森林
Bagging是并行式集成学习方法最典型的代表框架。其核心概念在于自助采样(Bootstrap Sampling),给定包含m个样本的数据集,有放回的随机抽取一个样本放入采样集中,经过m次采样,可得到一个和原始数据集一样大小的采样集。我们可以采样得到T个包含m个样本的采样集,然后基于每个采样集训练出一个基学习器,最后将这些基学习器进行组合。这便是Bagging的主要思想。Bagging与Boosting图示如下:
可以清楚的看到,Bagging是并行的框架,而Boosting则是序列框架(但也可以实现并行)。
有了之前多篇关于决策树的基础以及前述关于Bagging基本思想的阐述,随机森林(Random Forest)就没有太多难以理解的地方了。所谓随机森林,就是有很多棵决策树构建起来的森林,因为构建过程中的随机性,故而称之为随机森林。随机森林算法是Bagging框架的一个典型代表。
关于构建决策树的过程,可以参考前述第4~5篇,这里不做重复阐述。因为基础的推导工作都是前述章节都已完成,这里我们可以直接阐述随机森林的算法过程,简单来说就是两个随机性。具体如下:
假设有M个样本,有放回的随机选择M个样本(每次随机选择一个放回后继续选)。
假设样本有N个特征,在决策时的每个节点需要分裂时,随机地从这N个特征中选取n个特征,满足n<<N,从这n个特征中选择特征进行节点分裂。
基于抽样的M个样本n个特征按照节点分裂的方式构建决策树。
按照1~3步构建大量决策树组成随机森林,然后将每棵树的结果进行综合(分类使用投票法,回归可使用均值法)。
所以,当我们熟悉了Bagging的基本思想和决策树构建的过程后,随机森林就很好理解了。
随机森林算法实现
本文我们使用numpy来手动实现一个随机森林算法。随机森林算法本身是实现思路我们是非常清晰的,但其原始构建需要大量搭建决策树的工作,比如定义树节点、构建基本决策树、在基本决策树基础上构建分类树和回归树等。这些笔者在前述章节均已实现过,这里不再重复。
在此基础上,随机森林算法的构建主要包括随机选取样本、随机选取特征、构造森林并拟合其中的每棵树、基于每棵树的预测结果给出随机森林的预测结果。
导入相关模块并生成模拟数据集。
import numpy as np
# 该模块为自定义模块,封装了构建决策树的基本方法
from ClassificationTree import *
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
# 树的棵数
n_estimators = 10
# 列抽样最大特征数
max_features = 15
# 生成模拟二分类数据集
X, y = make_classification(n_samples=1000, n_features=20, n_redundant=0, n_informative=2,random_state=1, n_clusters_per_class=1)
rng = np.random.RandomState(2)
X += 2 * rng.uniform(size=X.shape)
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
print(X_train.shape, y_train.shape, X_test.shape, y_test.shape)
定义第一个随机性,行抽样选取样本:
# 自助抽样选择训练数据子集
def bootstrap_sampling(X, y):X_y = np.concatenate([X, y.reshape(-1,1)], axis=1)np.random.shuffle(X_y)n_samples = X.shape[0]sampling_subsets = []for _ in range(n_estimators):# 第一个随机性,行抽样idx1 = np.random.choice(n_samples, n_samples, replace=True)bootstrap_Xy = X_y[idx1, :]bootstrap_X = bootstrap_Xy[:, :-1]bootstrap_y = bootstrap_Xy[:, -1]sampling_subsets.append([bootstrap_X, bootstrap_y])return sampling_subsets
然后基于分类树构建随机森林:
trees = []
# 基于决策树构建森林
for _ in range(n_estimators):tree = ClassificationTree(min_samples_split=2, min_impurity=0,max_depth=3)trees.append(tree)
定义训练函数,对随机森林中每棵树进行拟合。
# 随机森林训练
def fit(X, y):# 对森林中每棵树训练一个双随机抽样子集n_features = X.shape[1]sub_sets = bootstrap_sampling(X, y)for i in range(n_estimators):sub_X, sub_y = sub_sets[i]# 第二个随机性,列抽样idx2 = np.random.choice(n_features, max_features, replace=True)sub_X = sub_X[:, idx2]trees[i].fit(sub_X, sub_y)trees[i].feature_indices = idx2print('The {}th tree is trained done...'.format(i+1))
我们将上述过程进行封装,分别定义自助抽样方法、随机森林训练方法和预测方法。完整代码如下:
class RandomForest():def __init__(self, n_estimators=100, min_samples_split=2, min_gain=0,max_depth=float("inf"), max_features=None):# 树的棵树self.n_estimators = n_estimators# 树最小分裂样本数self.min_samples_split = min_samples_split# 最小增益self.min_gain = min_gain# 树最大深度self.max_depth = max_depth# 所使用最大特征数self.max_features = max_featuresself.trees = []# 基于决策树构建森林for _ in range(self.n_estimators):tree = ClassificationTree(min_samples_split=self.min_samples_split, min_impurity=self.min_gain,max_depth=self.max_depth)self.trees.append(tree)# 自助抽样def bootstrap_sampling(self, X, y):X_y = np.concatenate([X, y.reshape(-1,1)], axis=1)np.random.shuffle(X_y)n_samples = X.shape[0]sampling_subsets = []for _ in range(self.n_estimators):# 第一个随机性,行抽样idx1 = np.random.choice(n_samples, n_samples, replace=True)bootstrap_Xy = X_y[idx1, :]bootstrap_X = bootstrap_Xy[:, :-1]bootstrap_y = bootstrap_Xy[:, -1]sampling_subsets.append([bootstrap_X, bootstrap_y])return sampling_subsets# 随机森林训练def fit(self, X, y):# 对森林中每棵树训练一个双随机抽样子集sub_sets = self.bootstrap_sampling(X, y)n_features = X.shape[1]# 设置max_featureif self.max_features == None:self.max_features = int(np.sqrt(n_features))for i in range(self.n_estimators):# 第二个随机性,列抽样sub_X, sub_y = sub_sets[i]idx2 = np.random.choice(n_features, self.max_features, replace=True)sub_X = sub_X[:, idx2]self.trees[i].fit(sub_X, sub_y)# 保存每次列抽样的列索引,方便预测时每棵树调用self.trees[i].feature_indices = idx2print('The {}th tree is trained done...'.format(i+1))# 随机森林预测def predict(self, X):y_preds = []for i in range(self.n_estimators):idx = self.trees[i].feature_indicessub_X = X[:, idx]y_pred = self.trees[i].predict(sub_X)y_preds.append(y_pred)y_preds = np.array(y_preds).Tres = []for j in y_preds:res.append(np.bincount(j.astype('int')).argmax())return res
基于上述随机森林算法封装来对模拟数据集进行训练并验证:
rf = RandomForest(n_estimators=10, max_features=15)
rf.fit(X_train, y_train)
y_pred = rf.predict(X_test)
print(accuracy_score(y_test, y_pred))
0.78
sklearn也为我们提供了随机森林算法的api,我们也尝试一下与numpy手写的进行效果对比:
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(max_depth=3, random_state=0)
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
print(accuracy_score(y_test, y_pred))
0.8
可以看到sklearn的预测结果要略高于我们手写的结果。当然我们的训练结果还可以经过调参进一步提高。随机森林调参可参考sklearn官方文档,这里略过。
参考资料:
机器学习 周志华
往期精彩:
数学推导+纯Python实现机器学习算法25:CatBoost【机器学习基础】数学推导+纯Python实现机器学习算法25:CatBoost
数学推导+纯Python实现机器学习算法24:LightGBM
数学推导+纯Python实现机器学习算法23:kmeans聚类
数学推导+纯Python实现机器学习算法22:最大熵模型
数学推导+纯Python实现机器学习算法21:马尔科夫链蒙特卡洛
数学推导+纯Python实现机器学习算法20:LDA线性判别分析
数学推导+纯Python实现机器学习算法19:PCA降维
数学推导+纯Python实现机器学习算法18:奇异值分解SVD
数学推导+纯Python实现机器学习算法17:XGBoost
数学推导+纯Python实现机器学习算法16:Adaboost
数学推导+纯Python实现机器学习算法15:GBDT
数学推导+纯Python实现机器学习算法14:Ridge岭回归
数学推导+纯Python实现机器学习算法13:Lasso回归
数学推导+纯Python实现机器学习算法12:贝叶斯网络
数学推导+纯Python实现机器学习算法11:朴素贝叶斯
数学推导+纯Python实现机器学习算法10:线性不可分支持向量机
数学推导+纯Python实现机器学习算法8-9:线性可分支持向量机和线性支持向量机
数学推导+纯Python实现机器学习算法7:神经网络
数学推导+纯Python实现机器学习算法6:感知机
数学推导+纯Python实现机器学习算法5:决策树之CART算法
数学推导+纯Python实现机器学习算法4:决策树之ID3算法
数学推导+纯Python实现机器学习算法3:k近邻
数学推导+纯Python实现机器学习算法2:逻辑回归
数学推导+纯Python实现机器学习算法1:线性回归
往期精彩回顾适合初学者入门人工智能的路线及资料下载机器学习及深度学习笔记等资料打印机器学习在线手册深度学习笔记专辑《统计学习方法》的代码复现专辑
AI基础下载机器学习的数学基础专辑获取一折本站知识星球优惠券,复制链接直接打开:https://t.zsxq.com/yFQV7am本站qq群1003271085。加入微信群请扫码进群:
【机器学习基础】数学推导+纯Python实现机器学习算法26:随机森林相关推荐
- 【机器学习基础】数学推导+纯Python实现机器学习算法30:系列总结与感悟
Python机器学习算法实现 Author:louwill Machine Learning Lab 终于到了最后的总结.从第一篇线性回归的文章开始到现在,已经接近有两年的时间了.当然,也不是纯写这3 ...
- 【机器学习基础】数学推导+纯Python实现机器学习算法24:HMM隐马尔可夫模型
Python机器学习算法实现 Author:louwill Machine Learning Lab HMM(Hidden Markov Model)也就是隐马尔可夫模型,是一种由隐藏的马尔可夫链随机 ...
- 【机器学习基础】数学推导+纯Python实现机器学习算法28:CRF条件随机场
Python机器学习算法实现 Author:louwill Machine Learning Lab 本文我们来看一下条件随机场(Conditional Random Field,CRF)模型.作为概 ...
- 【机器学习基础】数学推导+纯Python实现机器学习算法27:EM算法
Python机器学习算法实现 Author:louwill Machine Learning Lab 从本篇开始,整个机器学习系列还剩下最后三篇涉及导概率模型的文章,分别是EM算法.CRF条件随机场和 ...
- 【机器学习基础】数学推导+纯Python实现机器学习算法25:CatBoost
Python机器学习算法实现 Author:louwill Machine Learning Lab 本文介绍GBDT系列的最后一个强大的工程实现模型--CatBoost.CatBoost与XGBoo ...
- 【机器学习基础】数学推导+纯Python实现机器学习算法24:LightGBM
Python机器学习算法实现 Author:louwill Machine Learning Lab 第17讲我们谈到了竞赛大杀器XGBoost,本篇我们来看一种比XGBoost还要犀利的Boosti ...
- 【机器学习基础】数学推导+纯Python实现机器学习算法23:kmeans聚类
Python机器学习算法实现 Author:louwill Machine Learning Lab 聚类分析(Cluster Analysis)是一类经典的无监督学习算法.在给定样本的情况下,聚类分 ...
- 【机器学习基础】数学推导+纯Python实现机器学习算法22:最大熵模型
Python机器学习算法实现 Author:louwill Machine Learning Lab 最大熵原理(Maximum Entropy Principle)是一种基于信息熵理论的一般原理,在 ...
- 【机器学习基础】数学推导+纯Python实现机器学习算法21:马尔可夫链蒙特卡洛...
Python机器学习算法实现 Author:louwill Machine Learning Lab 蒙特卡洛(Monte Carlo,MC)方法作为一种统计模拟和近似计算方法,是一种通过对概率模型随 ...
最新文章
- linux服务器文件后缀名,linux服务器备份网站程序并下载到本地(自动)
- SpringBoot: SpringBoot里面创建导出Excel的接口(亲测)
- TypeScript里get属性的实现
- 小程序【笔记002】逻辑层简介
- 编写一个可动态注入Spring 容器的工具类
- 当子元素设置position absolute的时,父元素必须设置position属性
- SAP FICO模块
- 【经验分享】卡方检验实战--检验次日留存率与用户分类的独立性
- 找电影最强攻略,最全资源站
- CIFAR10 代码分析详解——cifar10_train.py
- donet 微服务开发 学习-熔断降级 Polly
- 语言模型数据集 (周杰伦专辑歌词)
- 看完就学会系列,小小一篇文章教会你利用Python网络爬虫抓取王者荣耀图片(建议收藏)
- 服务器系统才有卷影副本吗,windows server 2019没有适合具有卷影副本的卷
- python编写程序计算三角形的面积_编程题:编写程序输入三角形的3条边长,计算并输出三角形的面积。...
- LTE RACH过程
- 【Spring Cloud 基础设施搭建系列】Spring Cloud Demo项目 Spring Cloud Config Client 失败快速响应与超时重试
- MAC 电脑怎么找到 host 文件
- java 音频类型转换(spark聊天)
- java swing 自定义标题栏,缩放窗口,阴影窗口