随机森林(Random Forest)原理小结

本博客中使用到的完整代码请移步至: 我的github:https://github.com/qingyujean/Magic-NLPer,求赞求星求鼓励~~~

集成学习系列文章:

集成学习原理小结(AdaBoost & lightGBM demo)
梯度提升树(GBDT)原理小结
XGBoost使用
随机森林(Random Forest)原理小结


接着上一章节的决策树模型,接下来会介绍一些基于决策树的,具有代表性的集成模型,如随机森林(RF),GBDT,XGBoost以及lightGBM

本章主要介绍随机森林(Random Forest,简写RF),RF是bagging集成模型的扩展变体,所以前面会简要介绍一些关于bagging的内容,后面会有专门的“集成学习”的章节来重点介绍bagging相关内容。

1. bagging

bagging是并行式集成学习方法的著名代表。

bagging希望集成中的个体学习器尽可能 相互独立,而这在现实任务中几乎无法做到,更简单方便的实现是 使基学习器具有较大差异 ,或者说使得基学习器更具有 “多样性”

bagging基学习器的多样性通过“样本扰动”达到,而这是通过”自主采样法“(bootstrap sampling)实现

bootstrap sampling:
给定包含m个样本的数据集D,每次随机、有放回的挑选一个样本,执行m次,最后得到一个包含m个样本的数据集D’。一个样本在m次采样中始终不被抽取到的概率是 ( 1 − 1 m ) m (1-\frac{1}{m})^m (1m1)m,而 l i m m → ∞ ( 1 − 1 m ) m → 1 e ≈ 0.368 lim_{m\rightarrow\infty}(1-\frac{1}{m})^m \rightarrow\frac{1}{e}\approx0.368 limm(1m1)me10.368,即初始训练集中有63.2%的样本会出现在采样集中。

bagging对分类任务使用简单投票法,对回归任务使用简单平均法

从偏差-方差分解角度看,bagging主要关注降低方差

2. 随机森林(RF)

random forest:an ensemble of decision trees.

The idea behind a random forest is to average multiple (deep) decision trees that individually suffer from high variance, to build a more robust model that has a better generalization performance and is less susceptible to overfitting.(塑料英翻:随机森林背后的思想是平均多个(深)决策树,这些树各自遭受高方差,建立一个更稳健的模型,具有更好的泛化性能,并且不太容易被过度拟合。)

random forest是bagging的扩展变体。在以决策树为基学习器构建bagging集成的基础上,进一步在决策树训练过程中引入“随机属性选择”

传统决策树在选择划分属性时,是在当前节点的属性集合k中选择一个最优属性;而在RF中,是先从该节点的属性集合中随机选择含有d个属性的子集,然后从该子集中选择一个最优属性用于划分。一般地,推荐 d = l o g 2 k d=log_2k d=log2k或者 d = k d=\sqrt{k} d=k

简单来说,bagging基学习器的多样性来自于“样本扰动”,而RF除了“样本扰动”,还增加了“属性扰动”,而这使得最终基学习器之间的差异度进一步增加,从而使得最终的集成模型的泛化性能进一步提升。

RF 与 bagging的比较:

  • 随机森林的 收敛性 与bagging相似,其实性能相对较差,因为引入了属性扰动,个体的性能往往有所降低,但随着基学习器的个数增加,随机森林能收敛到更低的泛化误差
  • 因为是考察的属性的子集,所以RF的 训练效率 常优于bagging。

RF中决策树采用的是CART决策树作为基学习器

2.1 RF 分类

RF分类算法

RF在可解释性上不能同传统决策树相提并论,但是它的一大优势不用太关注选择好的超参数。RF相比单个决策树,对噪声或者异常值十分具有鲁棒性,因而RF通常亦不需要剪枝。在实践中唯一需要关心的参数就是the number of trees: nn越大,RF分类器的性能越好,同时其计算代价也越大

当然,如果需要,像bootstrap sample的采样数m,以及再每次split时随机选取的属性子集的数目d,这些超参数也是可以优化的。可以通过这些参数来控制RF的bias-variance trade-off。

属性子集d,越小,个体树的性能有所降低,但整个RF模型会越健壮。d越大,属性随机性会降低,容易过拟合。

减小采样数m,能增加个体树之间的多样性,因为一个样本被包含在bootstrap sample里的概率变小了。所以减小m可以增加RF的随机性,这将有助于降低过拟合风险。然而,更小的m将会使得RF的整体性能降低,使得training和test 性能之间的有小的gap,有更低的test performance。相反的,增大m会引起一定程度的过拟合,因为bootstrap sample以及后续的个体决策树会变得彼此更相似,他们会更加接近的学习拟合原始训练数据集。

一般的,the size of the bootstrap sample m 就选择为与原始训练数据集相等的值(sklearn中也是这么实现的)。这往往就能提供一个较好的bias-variance tradeoff。而关于每次split时的属性子集数 d ,一般取的比属性总数小,sklearn中的实现是默认取值为 d = m d=\sqrt{m} d=m ,m表示训练集中特征总数。

demo示例:
数据集:鸢尾花,使用RandomForestClassifier实现分类:

from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
import numpy as np

from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt

iris = datasets.load_iris()
print(iris['data'].shape, iris['target'].shape) # (150, 4) (150,)
X = iris.data[:,[2,3]]
y = iris.target
print('Class labels:', np.unique(y))
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1, stratify=y)
print(X_train.shape, y_train.shape)

输出:

(150, 4) (150,)
Class labels: [0 1 2]
(105, 2) (105,)

训练,并绘制分类决策边界:

forest = RandomForestClassifier(criterion='gini', # 划分准则
								n_estimators=25, # 25个基学习器(决策树)
								random_state=1, 
								n_jobs=2) # 并行执行
forest.fit(X_train, y_train)
X_combined = np.vstack((X_train, X_test))
y_combined = np.hstack((y_train, y_test))
plot_decision_regions(X_combined, y_combined, classifier=forest, test_idx=range(105,150))
plt.xlabel('petal length')
plt.ylabel('petal width')
plt.legend(loc='upper left')
plt.show()

分类决策边界

2.2 特征重要性

Using a random forest, we can measure the feature importance as the averaged impurity decrease computed from all decision trees in the forest, without making any assumptions about whether our data is linearly separable or not.(可通过计算所有树的 平均不纯度减少值 来衡量特征重要性)。

此功能在sklearn中已实现好,使用时,先在sklearn中训练好一个RandomForestClassifier后,然后就可以调用feature_importances_ 属性来获得特征重要性。

使用RandomForestClassifier作为特征选择器,获得重要的特征后,只拿那些重要的特征去训练接下来的模型,此时RF是作为data pipeline中的特征抽取步骤。

demo示例:
数据集:白酒数据,共有13个特征,使用RandomForestClassifier训练,然后调用feature_importances_属性获得特征重要性:

# Wine dataset and rank the 13 features by their respective importance measures
df_wine = pd.read_csv(data_dir+'wine.data', 
                      header=None,
                      names=['Class label', 'Alcohol', 'Malic acid', 'Ash', 'Alcalinity of ash', 'Magnesium',
                               'Total phenols', 'Flavanoids', 'Nonflavanoid phenols', 'Proanthocyanins', 'Color intensity', 
                               'Hue', 'OD280/OD315 of diluted wines', 'Proline'])
print('Class labels', np.unique(df_wine['Class label']))
print('numbers of features:', len(df_wine.keys())-1)
df_wine.head()

输出:

Class labels [1 2 3]
numbers of features: 13

白酒数据

X, y = df_wine.iloc[:, 1:].values, df_wine.iloc[:, 0].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0, stratify=y)
X_train.shape

输出:

(124, 13)
feat_labels = df_wine.columns[1:]
forest = RandomForestClassifier(n_estimators=200, random_state=1)
forest.fit(X_train, y_train)
importances = forest.feature_importances_
print(len(importances))
importances

输出:

13
array([0.11535953, 0.02485979, 0.01367936, 0.0206145 , 0.03254997,
       0.04019533, 0.18793917, 0.01096301, 0.02611948, 0.13488692,
       0.06345939, 0.13440744, 0.19496612])
"""
numpy.argsort(a, axis=-1, kind=’quicksort’, order=None)
功能: 将矩阵a在指定轴axis上排序,并返回排序后的下标
参数: a:输入矩阵, axis:需要排序的维度
返回值: 输出排序后的下标
"""
indices = np.argsort(importances)[::-1] # 取反后是从大到小
indices

输出:

array([12,  6,  9, 11,  0, 10,  5,  4,  8,  1,  3,  2,  7])
for i in range(X_train.shape[1]):
    print("%2d) %-*s %f" % (i + 1, 30, feat_labels[indices[i]], importances[indices[i]]))

输出:

 1) Proline                        0.194966
 2) Flavanoids                     0.187939
 3) Color intensity                0.134887
 4) OD280/OD315 of diluted wines   0.134407
 5) Alcohol                        0.115360
 6) Hue                            0.063459
 7) Total phenols                  0.040195
 8) Magnesium                      0.032550
 9) Proanthocyanins                0.026119
10) Malic acid                     0.024860
11) Alcalinity of ash              0.020615
12) Ash                            0.013679
13) Nonflavanoid phenols           0.010963

绘图:

plt.title('Feature Importance')
plt.bar(range(X_train.shape[1]), importances[indices], align='center')
plt.xticks(range(X_train.shape[1]), feat_labels[indices], rotation=90)
plt.xlim([-1, X_train.shape[1]])
plt.tight_layout()
plt.show()

特征重要性

2.3 RF 回归

The basic random forest algorithm for regression is almost identical to the random forest algorithm for classification, the only difference is that we use the MSE criterion to grow the individual decision trees, and the predicted target variable is calculated as the average prediction over all decision trees.(几乎很RF分类器一样,只是使用 MSE 作为生成个体决策树的标准,预测时将所有树的结果进行求平均来获得最终的预测结果值。)

demo示例:
数据集:房价预测,使用RandomForestRegressor实现回归:

from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error

df = pd.read_csv(data_dir+'housing.data.txt',
                 header=None,
                 sep='\s+',
                 names= ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV'])
df.head()

输出:
房价数据

X = df.iloc[:, :-1].values
y = df['MEDV'].values
X_train, X_test, y_train, y_test =train_test_split(X, y, test_size=0.2, random_state=1)
print(X_train.shape, y_train.shape)

输出:

(404, 13) (404,)

训练:

forest = RandomForestRegressor(n_estimators=100, criterion='mse', random_state=1, n_jobs=-1)
forest.fit(X_train, y_train)

y_train_pred = forest.predict(X_train)
y_test_pred = forest.predict(X_test)
print('MSE train: %.3f, test: %.3f' % (mean_squared_error(y_train, y_train_pred), mean_squared_error(y_test, y_test_pred)))

输出:

MSE train: 1.237, test: 8.916

3. 模型评价

优点:

  • 训练可以并行化,训练速度快
  • 训练后,可以给出各个特征对于输出的重要性/贡献程度
  • 决策树和RF具有尺度不变性,不需要做feature scaling
  • RF中的基学习器(决策树)不需要剪枝
  • 不需要太多的调参,唯一需要关注的就是RF中基学习器的个数n_estimator
  • 样本扰动+属性扰动增加了随机性,使得RF不像决策树那样容易过拟合,模型方差小,泛化能力强
  • RF对异常值/缺失值不敏感,十分具有鲁棒性

缺点:

  • 在某些噪音比较大的样本集上,RF模型容易陷入过拟合。
  • 值划分比较多的特征容易对RF的决策产生更大的影响,从而影响拟合的模型的效果。

完整代码

完整代码请移步至: 我的github:https://github.com/qingyujean/Magic-NLPer,求赞求星求鼓励~~~

参考

  • [1] 机器学习(西瓜书) 周志华
  • [2] Python_Machine_Learning_2nd_Edition
  • 11
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
随机森林回归Random Forest Regression)是一种基于随机森林算法的回归模型在随机森林回归中,通过构建多个决策树(树的数量由用户指定),然后对这些决策树的预测结果进行平均得到最终的预测结果。 在随机森林中,每个决策树都是基于不同的随机样本和随机特征构建的。这样做的目的是为了增加模型的多样性,减少过拟合的风险。对于特征数较少的数据,随机性的发挥可能不太好,导致效果不太好。 随机森林回归模型还有一个变式,即extra trees。在extra trees中,对于袋外数据(Out-of-Bag,简称OOB)的所有样本的特征进行加入噪声干扰,然后再次计算袋外数据误差。这个过程可以提高模型的鲁棒性和泛化能力。 需要注意的是,随机森林回归模型不能给出一个连续的输出,而且也不能做出超越训练集数据范围的预测。这可能会导致在训练含有某些特定噪声的数据时出现过拟合的情况。 总结来说,随机森林回归通过构建多个决策树并对它们的预测结果进行平均,来得到最终的预测结果。它的随机性可以提高模型的鲁棒性,但对于特征数较少的数据效果可能不太好。另外,随机森林回归模型不能给出连续的输出,并且不能做出超越训练集数据范围的预测。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [RF模型(随机森林模型)详解](https://blog.csdn.net/weixin_55073640/article/details/123658369)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值