随机森林原理&sklearn实现

原理

  1. 定义
    随机森林就是通过集成学习的思想将多棵树集成的一种算法,它的基本单元是决策树,
    而它的本质属于机器学习的一大分支------集成学习(Ensemble Learning)方法。
    随机森林的名称中有两个关键词,一个是"随机",一个就是"森林"。
复制代码
随机森林应该是机器学习算法时最先接触到的集成算法,集成学习的家族:
Bagging:  个体评估器之间不存在强依赖关系,一系列个体学习器可以并行生成。
           代表算法:随机森林(Random Forest)
Boosting:个体学习器之间存在强依赖关系,一系列个体学习器基本都需要串行生成。
            代表算法:AdaBoost、GBDT、XGBoost、LightGBM
  1. 随机森林的生成

     每棵树的按照如下规则生成:

    1)如果训练集大小为N,对于每棵树而言,

    随机且有放回地从训练集中的抽取 N个训练样本(这种采样方式称为bootstrap sample方法),作为该树的训练集;

    2)如果每个样本的特征维度为M,指定一个常数m<<M,

    随机地从M个特征中选取m个特征子集,每次树进行分裂时,从这m个特征中选择最优的;

    3)每棵树都尽最大程度的生长,并且没有剪枝过程。

  2. 随机森林分类效果(错误率)与两个因素有关

森林中任意两棵树的相关性:相关性越大,错误率越大;

森林中每棵树的分类能力:每棵树的分类能力越强,整个森林的错误率越低。

复制代码
减小**特征选择个数m**,树的相关性和分类能力也会相应的降低;
增大m,两者也会随之增大。
所以关键问题是**如何选择最优的m**(或者是范围),这也是随机森林唯一的一个参数。
  1. 随机森林的优点:
    1)模型随机性强,不易overfit
    抗噪性强,表示对异常点不敏感
    2)处理高维数据相对更快(相对于决策树)
    3)树状结构,模型可解释性高,可以告诉你每个特征的重要性
    缺点:
    1)模型往往过于General ,不具备处理过于困难样本的能力
    打个比方:三个学渣放在一起可能有所进步,但是对于过于困难的问题可能也无法解决

实例

python 复制代码
# 参考:  https://blog.csdn.net/HRMEMEDA/article/details/125678213

import pandas as pd
import numpy as np
import seaborn as sns

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OrdinalEncoder
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn import ensemble
from sklearn.model_selection import cross_val_score
from sklearn.metrics import roc_curve, auc

import matplotlib.pyplot as plt

# %matplotlib inline
plt.rcParams['font.size'] = 24

# 数据准备
data = sns.load_dataset('titanic')  # 导入泰坦尼克号生还数据
# data

# 数据预处理
data.replace(to_replace=r'^\s*$', value=np.nan, regex=True, inplace=True)  # 把各类缺失类型统一改为NaN的形式
data.isnull().mean()
del data['deck']  # 删除'deck'列
del data['who']
del data['adult_male']
del data['class']
del data['alone']

data['age'].fillna(np.mean(data.age), inplace=True)  # 年龄特征使用均值对缺失值进行填补
data['embarked'].fillna(data['embarked'].mode(dropna=False)[0], inplace=True)  # 文本型特征视同众数进行缺失值填补

x = data.drop(['alive', 'survived', 'embark_town'], axis=1)  # 取出用于建模的特征列X
label = data['survived']  # 取出标签列Y

oe = OrdinalEncoder()  # 定义特征转化函数
# 把需要转化的特征都写进去
x[['sex', 'embarked']] = oe.fit_transform(x[['sex', 'embarked']])
x.head()

# 划分训练集、测试集
xtrain, xtest, ytrain, ytest = train_test_split(x, label, test_size=0.3)
xtrain.head()

"""
随机森林所有超参数
sklearn.ensemble.RandomForestClassifier (n_estimators=100, criterion='gini', max_depth=None, min_samples_split=2, min_samples_leaf=1, 
                                         min_weight_fraction_leaf=0.0, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0, 
                                         min_impurity_split=None, class_weight=None, random_state=None, bootstrap=True, oob_score=False, 
                                         n_jobs=None, verbose=0, warm_start=False)
"""

# 下面把随机森林与单个决策树的拟合效果放在一起对比

# 单颗决策树
clf = DecisionTreeClassifier(class_weight='balanced', random_state=37)
clf = clf.fit(xtrain, ytrain)  # 拟合训练集
score_c = clf.score(xtest, ytest)  # 输出测试集准确率

# 随机森林
rfc = RandomForestClassifier(class_weight='balanced', random_state=37)
rfc = rfc.fit(xtrain, ytrain)
score_r = rfc.score(xtest, ytest)

# 决策树 预测测试集
y_test_proba_clf = clf.predict_proba(xtest)
false_positive_rate_clf, recall_clf, thresholds_clf = roc_curve(ytest, y_test_proba_clf[:, 1])
# 决策树 AUC指标
roc_auc_clf = auc(false_positive_rate_clf, recall_clf)

# 模型效果

# 随机森林 预测测试集
y_test_proba_rfc = rfc.predict_proba(xtest)
false_positive_rate_rfc, recall_rfc, thresholds_rfc = roc_curve(ytest, y_test_proba_rfc[:, 1])
# 随机森林 AUC指标
roc_auc_rfc = auc(false_positive_rate_rfc, recall_rfc)

# 画图 画出俩模型的ROC曲线
plt.plot(false_positive_rate_clf, recall_clf, color='blue', label='AUC_clf=%0.3f' % roc_auc_clf)
plt.plot(false_positive_rate_rfc, recall_rfc, color='orange', label='AUC_rfc=%0.3f' % roc_auc_rfc)
plt.legend(loc='best', fontsize=15, frameon=False)
plt.plot([0, 1], [0, 1], 'r--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.ylabel('Recall')
plt.xlabel('Fall-out')
plt.show()

# 调参
# 定义空列表,用来存放每一个基学习器数量所对应的AUC值
superpa = []
# 循环200次
for i in range(200):
    rfc = ensemble.RandomForestClassifier(n_estimators=i + 1, class_weight='balanced', random_state=37, n_jobs=10)
    rfc = rfc.fit(xtrain, ytrain)  # 拟合模型

    y_test_proba_rfc = rfc.predict_proba(xtest)  # 预测测试集
    false_positive_rate_rfc, recall_rfc, thresholds_rfc = roc_curve(ytest, y_test_proba_rfc[:, 1])
    roc_auc_rfc = auc(false_positive_rate_rfc, recall_rfc)  # 计算模型AUC

    superpa.append(roc_auc_rfc)  # 记录每一轮的AUC值

print(max(superpa), superpa.index(max(superpa)))  # 输出最大的AUC值和其对应的轮数
plt.figure(figsize=[20, 5])
plt.plot(range(1, 201), superpa)
plt.show()
相关推荐
Asize6 小时前
146. LRU 缓存
算法
Asize6 小时前
543. 二叉树的直径
算法
lemon_sjdk6 小时前
ObjectProperty
java·开发语言·算法
Zentceh7 小时前
AI-ISP在夜视机芯中的应用:从传统ISP到PixelClean全彩夜视的进化
人工智能·科技·算法·计算机视觉·车载系统·视频·智能硬件
xier_ran7 小时前
【infra之路】AWQ 详解:激活感知权重保护,让 W4A16 量化精度超越 GPTQ
线性代数·算法·机器学习·量化·infra
亦皓ai7 小时前
AI时代后端工程(二):AI把代码写得越来越快,我却越来越不敢让它直接开工了
人工智能·算法·机器学习·搜索引擎·transformer
玖玥拾9 小时前
LeetCode 392 判断子序列
笔记·算法·leetcode
重生之后端学习10 小时前
239. 滑动窗口最大值[困难]✅
java·数据结构·算法·leetcode·职场和发展
fpcc10 小时前
算法和数据结构—动态规划法
数据结构·算法·动态规划
星星.72213 小时前
C++算法竞赛|二分查找与二分答案:边界模板、浮点二分、STL
数据结构·c++·算法