集成模型——随机森林

本文的数据集和上一篇一样,是美国个人收入信息。在上一篇末尾提到了随机森林算法,这一篇就介绍随机森林。

Ensemble Models

随机森林是一种集成模型(Ensemble Models),集成模型结合了多个模型然后创建了一个精度更高的模型

  • 下面我们创建两个决策树,他们的参数不相同,然后计算他们的预测精度:
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import roc_auc_score

columns = ["age", "workclass", "education_num", "marital_status", "occupation", "relationship", "race", "sex", "hours_per_week", "native_country"]

clf = DecisionTreeClassifier(random_state=1, min_samples_leaf=75)
clf.fit(train[columns], train["high_income"])

clf2 = DecisionTreeClassifier(random_state=1, max_depth=6)
clf2.fit(train[columns], train["high_income"])

predictions = clf.predict(test[columns])
print(roc_auc_score(predictions, test["high_income"]))

predictions = clf2.predict(test[columns])
print(roc_auc_score(predictions, test["high_income"]))
‘‘‘
0.784853009097
0.771031199892
‘‘‘

Combining Our Predictions

  • 当我们有多个分类器的时候,我们可以将其预测结果做成矩阵形式,如下:

  • 然后采用多数表决的方式生成最终的预测结果(当然其实有很多的生成最终结果的方式),此时分类器的个数要大于2,并且最好是奇数,因为是偶数的话,还要写一个规则来打破平局。

  • 由于上面我们只生成了两个决策树,因此我们采用另一种方法来生成最终结果:我们不用predict 函数,而用predict_proba 函数来生成每个样本属于0和1的概率,像下面这样:

  • 然后我们只采用每个分类器预测结果的第而列(属于1的概率),然后求平均。
predictions = clf.predict_proba(test[columns])[:,1]
predictions2 = clf2.predict_proba(test[columns])[:,1]
combined = (predictions + predictions2) / 2
rounded = numpy.round(combined)

print(roc_auc_score(rounded, test["high_income"]))
‘‘‘
0.789959895266
‘‘‘

Why Ensembling Works

  • 对比这三个精度:第一棵树{0.784853009097},第二棵树{0.771031199892},集成树{0.789959895266}.发现集成的决策树的精度要好于任何一棵单独的树,这就是集成模型的强大之处。

The more “diverse“, or dissimilar, the models used to construct an ensemble, the stronger the combined predictions will be (assuming that all models have about the same accuracy).

  • 结合一个精度相当的逻辑回归模型和一个决策树模型的效果会比结合两个参数一样的决策树的效果要好,因为他们的机制相差很大,各自有各自的优点,结合这些优点才会创造更好的模型。
  • 结合两个精度相差很大的模型并不会提升整体的精度,比如结合0.75和0.86的模型的精度会介于这两者之间。解决精度有差距的方法就是加权,对不同的模型赋予不同的重要性。

Bagging

如果不加修改,那么这些树的都相同,那么就不会得到提升。而随机森林(random forest)就是与上面一样的一个集成模型,其中的random就是暗示修改。随机森林做了两个修改bagging 和andom feature subsets.随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。

  • 根据下列算法而建造每棵树:

用N来表示训练用例(样本)的个数,M表示特征数目。输入特征数目m,用于确定决策树上一个节点的决策结果;其中m应远小于M。从N个训练用例(样本)中以有放回抽样的方式,取样N次,形成一个训练集(即bootstrap取样),并用未抽到的用例(样本)作预测,评估其误差。 对于每一个节点,随机选择m个特征,决策树上每个节点的决定都是基于这些特征确定的。根据这m个特征,计算其最佳的分裂方式。 每棵树都会完整成长而不会剪枝(Pruning,这有可能在建完一棵正常树状分类器后会被采用)。

  • bagging :从N个训练用例(样本)中以有放回抽样的方式,取样N次,形成一个训练集(即bootstrap取样)
tree_count = 10

# Each "bag" will have 60% of the number of original rows.
bag_proportion = .6

predictions = []
for i in range(tree_count):
    # We select 60% of the rows from train, sampling with replacement.
    # We set a random state to ensure we‘ll be able to replicate our results.
    # We set it to i instead of a fixed value so we don‘t get the same sample every loop.
    # That would make all of our trees the same.
    bag = train.sample(frac=bag_proportion, replace=True, random_state=i)

    # Fit a decision tree model to the "bag".
    clf = DecisionTreeClassifier(random_state=1, min_samples_leaf=75)
    clf.fit(bag[columns], bag["high_income"])

    # Using the model, make predictions on the test data.
    predictions.append(clf.predict_proba(test[columns])[:,1])
combined = numpy.sum(predictions, axis=0) / 10
rounded = numpy.round(combined)

print(roc_auc_score(rounded, test["high_income"]))
‘‘‘
0.785415640465
‘‘‘

Selecting Random Features

  • random feature subsets:对于每一个节点,随机选择m个特征,决策树上每个节点的决定都是基于这些特征确定的。根据这m个特征,计算其最佳的分裂方式。
# Create the dataset that we used 2 missions ago.
data = pandas.DataFrame([
    [0,4,20,0],
    [0,4,60,2],
    [0,5,40,1],
    [1,4,25,1],
    [1,5,35,2],
    [1,5,55,1]
    ])
data.columns = ["high_income", "employment", "age", "marital_status"]

# Set a random seed to make results reproducible.
numpy.random.seed(1)

# The dictionary to store our tree.
tree = {}
nodes = []

# The function to find the column to split on.
def find_best_column(data, target_name, columns):
    information_gains = []

    # Insert your code here.

    for col in columns:
        information_gain = calc_information_gain(data, col, "high_income")
        information_gains.append(information_gain)

    # Find the name of the column with the highest gain.
    highest_gain_index = information_gains.index(max(information_gains))
    highest_gain = columns[highest_gain_index]
    return highest_gain

# The function to construct an id3 decision tree.
def id3(data, target, columns, tree):
    unique_targets = pandas.unique(data[target])
    nodes.append(len(nodes) + 1)
    tree["number"] = nodes[-1]

    if len(unique_targets) == 1:
        if 0 in unique_targets:
            tree["label"] = 0
        elif 1 in unique_targets:
            tree["label"] = 1
        return

    best_column = find_best_column(data, target, columns)
    column_median = data[best_column].median()

    tree["column"] = best_column
    tree["median"] = column_median

    left_split = data[data[best_column] <= column_median]
    right_split = data[data[best_column] > column_median]
    split_dict = [["left", left_split], ["right", right_split]]

    for name, split in split_dict:
        tree[name] = {}
        id3(split, target, columns, tree[name])

# Run the id3 algorithm on our dataset and print the resulting tree.
id3(data, "high_income", ["employment", "age", "marital_status"], tree)
print(tree)
def find_best_column(data, target_name, columns):
    information_gains = []

    # Select two columns randomly.
    cols = numpy.random.choice(columns, 2)

    for col in cols:
        information_gain = calc_information_gain(data, col, "high_income")
        information_gains.append(information_gain)

    highest_gain_index = information_gains.index(max(information_gains))

    # Get the highest gain by indexing cols.
    highest_gain = cols[highest_gain_index]

    return highest_gain

id3(data, "high_income", ["employment", "age", "marital_status"], tree)
print(tree)
  • 重点就是cols = numpy.random.choice(columns, 2)这一句,表达了每次长树时随机的选择两个属性作为分裂候选。

Random Subsets In Scikit-Learn

  • 上面自己写随机森林参数选择比较复杂,在scikit-learn这个包中DecisionTreeClassifier已经实现了这项功能,通过一个splitter参数,将其设置为”random”,将max_features设置为为”auto”,如果我们有N个特征,那么会选择一个特征子集(大小为N开根号)。
# We‘ll build 10 trees
tree_count = 10

# Each "bag" will have 70% of the number of original rows.
bag_proportion = .7

predictions = []
for i in range(tree_count):
    # We select 80% of the rows from train, sampling with replacement.
    # We set a random state to ensure we‘ll be able to replicate our results.
    # We set it to i instead of a fixed value so we don‘t get the same sample every time.
    bag = train.sample(frac=bag_proportion, replace=True, random_state=i)

    # Fit a decision tree model to the "bag".
    clf = DecisionTreeClassifier(random_state=1, min_samples_leaf=75, splitter="random", max_features="auto")
    clf.fit(bag[columns], bag["high_income"])

    # Using the model, make predictions on the test data.
    predictions.append(clf.predict_proba(test[columns])[:,1])

combined = numpy.sum(predictions, axis=0) / 10
rounded = numpy.round(combined)

print(roc_auc_score(rounded, test["high_income"]))
‘‘‘
0.789767997764
‘‘‘

Putting It All Together

  • 从上面的结果显示,使用特征子集的方式的精度要比放回抽样的精度好。在sklearn中实现了随机森林算法:RandomForestClassifier以及RandomForestRegressor。
from sklearn.ensemble import RandomForestClassifier

clf = RandomForestClassifier(n_estimators=10, random_state=1, min_samples_leaf=75)
clf.fit(train[columns], train["high_income"])

predictions = clf.predict(test[columns])
print(roc_auc_score(predictions, test["high_income"]))
‘‘‘
0.791634978035
‘‘‘

Parameter Tweaking

与决策树相同随机森林也可以通过调整参数得到更高的精度,随机森林的参数如下,前四个参数和决策树的参数相同,第五个参数

  • min_samples_leaf
  • min_samples_split
  • max_depth
  • max_leaf_nodes
  • n_estimators : 随机森林中决策树的个数
  • bootstrap – defaults to True. Bootstrap aggregation is another name

    for bagging(是否要采用放回抽样)。

from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(n_estimators=150, random_state=1, min_samples_leaf=75)

clf.fit(train[columns], train["high_income"])

predictions = clf.predict(test[columns])
print(roc_auc_score(predictions, test["high_income"]))
‘‘‘
0.793788646293
‘‘‘

Reducing Overfitting

  • 随机森林算法降低了决策树算法的过拟合程度,因为一棵树过你喝了,但是有100棵树平均下来,就可以忽略这个噪声。
clf = RandomForestClassifier(n_estimators=150, random_state=1, min_samples_leaf=75)
clf.fit(train[columns], train["high_income"])

predictions = clf.predict(train[columns])
print(roc_auc_score(predictions, train["high_income"]))

predictions = clf.predict(test[columns])
print(roc_auc_score(predictions, test["high_income"]))
‘‘‘
0.794137608735
0.793788646293
‘‘‘
  • 发现训练集和测试集的性能相当,表示过拟合很小。

When To Use Random Forests

随机森林的优点有:

  • 对于很多种数据集,它都可以产生高准确度的分类器。
  • 它可以处理大量的输入变量。
  • 它可以在决定类别时,评估变量的重要性。
  • 在构造森林时,它可以在内部对于一般化后的误差产生无偏的估计。
  • 它包含一个好方法可以估计遗失的数据,并且,如果有很大一部分的数据遗失,仍可以维持准确度。
  • 它提供一个实验方法,可以去侦测variable interactions。
  • 对于不平衡的分类数据集来说,它可以平衡误差。
  • 它计算各例中的亲近度,对于数据挖掘、侦测偏离者(outlier)和将数据视觉化非常有用。
  • 使用上述。它可被延伸应用在未标记的数据上,这类数据通常是使用非监督式聚类。也可侦测偏离者和观看数据。
  • 学习过程是很快速的。

随机森林和神经网络以及gradient boosted trees是表现最好的算法之三。

随机森林的缺点:

  • 难以解释,因为它是平均了很多树的结果。
  • 构造过程很长,构造的树越多事假越长,但是我们可以采用多核并行处理这个问题,sklearn中有个参数n_jobs表示用几个CPU来执行算法 。

所以结合了优点以及缺点,通常在精度是至关重要且不要求解释决策的情况下使用随机森林是很好的。当就要求效率(时间复杂度)且需要解释时使用单个的决策树会比较合适。

时间: 2024-10-10 20:44:12

集成模型——随机森林的相关文章

吴裕雄 python 机器学习——集成学习随机森林RandomForestClassifier分类模型

import numpy as np import matplotlib.pyplot as plt from sklearn import datasets,ensemble from sklearn.model_selection import train_test_split def load_data_classification(): ''' 加载用于分类问题的数据集 ''' # 使用 scikit-learn 自带的 digits 数据集 digits=datasets.load_d

吴裕雄 python 机器学习——集成学习随机森林RandomForestRegressor回归模型

import numpy as np import matplotlib.pyplot as plt from sklearn import datasets,ensemble from sklearn.model_selection import train_test_split def load_data_regression(): ''' 加载用于回归问题的数据集 ''' #使用 scikit-learn 自带的一个糖尿病病人的数据集 diabetes = datasets.load_di

集成学习:随机森林.GBDT

集成学习(Ensemble Learning) 集成学习的思想是将若干个学习器(分类器&回归器)组合之后产生一个新学习器.弱分类器(weak learner)指那些分类准确率只稍微好于随机猜测的分类器(errorrate < 0.5): 集成算法的成功在于保证弱分类器的多样性(Diversity).而且集成不稳定的算法也能够得到一个比较明显的性能提升 常见的集成学习思想有: Bagging Boosting Stacking Why need Ensemble Learning? 1. 弱分

机器学习算法整理(四)集成算法—随机森林模型

随机:数据采样随机,特征选择随机 (数据采样,有放回) 原文地址:https://www.cnblogs.com/douzujun/p/8386930.html

sklearn之随机森林

''' 集合算法: 1.正向激励 2.自助聚合:每次从总样本矩阵中以有放回抽样的方式随机抽取部分样本构建决策树,这样形成多棵包含不同训练样本的决策树, 以削弱某些强势样本对模型预测结果的影响,提高模型的泛化特性. 3.随机森林:在自助聚合的基础上,每次构建决策树模型时,不仅随机选择部分样本,而且还随机选择部分特征,这样的集合算法, 不仅规避了强势样本对预测结果的影响,而且也削弱了强势特征的影响,使模型的预测能力更加泛化.(中庸-->真值) 随机森林相关API: import sklearn.en

人工智能_5_决策树_随机森林

# 决策树,随机森林 # 决策树结构:if-then # 信息熵: # 例:第一届世界杯32支球队 每个队伍冠军概率1/32 # 可得 log32(程序员认为的log一般都默认是以2为底) = -(1/32*log(1/32)+1/32*log(1/32).....) # 2018 第21届世界杯根据历史数据获胜概率不同 log32 > -(1/4*log(1/4)+1/4*log(1/4).....) # 几个log的和即为信息熵, 当概率变化时 log的和是小于log(n)的 # 信息熵与不

机器学习实战之 第七章 集成方法(随机森林和 AdaBoost)

第7章 集成方法 ensemble method 集成方法: ensemble method(元算法: meta algorithm) 概述 概念:是对其他算法进行组合的一种形式. 通俗来说: 当做重要决定时,大家可能都会考虑吸取多个专家而不只是一个人的意见. 机器学习处理问题时又何尝不是如此? 这就是集成方法背后的思想. 集成方法: 投票选举(bagging: 自举汇聚法 bootstrap aggregating): 是基于数据随机重抽样分类器构造的方法 再学习(boosting): 是基于

3. 集成学习(Ensemble Learning)随机森林(Random Forest)

1. 前言 相信看了之前关于集成学习的介绍,大家对集成学习有了一定的了解.本文在给大家介绍下远近闻名的随机森林(RF)算法. 随机森林是集成学习中可以和梯度提升树GBDT分庭抗礼的算法,尤其是它可以很方便的并行训练,在如今大数据大样本的的时代很有诱惑力. 2. 随机森林原理 随机森林是Bagging算法的进化版,也就是说,它的基本思想仍然和Bagging,但是进行了独有的改进. RF使用了CART决策树作为弱学习器,这让我们想到了梯度提示树GBDT. 在使用决策树的基础上,RF对决策树的建立做了

大白话5分钟带你走进人工智能-第二十八节集成学习之随机森林概念介绍(1)

                                                      第二十八节集成学习之随机森林概念介绍(1) 从本系列开始,我们讲解一个新的算法系列集成学习.集成学习其实是怎么样去应用决策树解决一些问题. 在机器学习领域集成学习是一种非常简单直接的提升分类器回归器预测效果的一种思路.决策树有一个困境,当层数太深的时候会有过拟合问题,当我不想过拟合,就通过预剪枝给它砍掉一部分深度,此时损失又容易太大了,导致在训练集上预测的又不怎么准.所以对于决策树很难去找