zoukankan      html  css  js  c++  java
  • 如何使用集成学习(第一季)

    文章目录
    一,什么是集成学习
    二,使用SKlearn中提供的集成学习器解决分类问题
    2.1 Voting Classifier 投票集成
    2.1.1 少数服从多数原则的投票集成-Hard Voting
    2.1.2 考虑概率的投票集成-Soft Voting
    2.2 Bagging 和 Pasting
    2.2.1 如何使用 Bagging(套袋分类器)
    2.2.2 关于袋外数据(oob)
    2.2.3 同时对特征进行随机采样
    2.3 随机森林
    2.3.1 RandomForestClassifier
    2.3.2 ExtraTreesClassifier
    三,集成学习解决回归问题
    四,Stacking
    首先我们建造如下数据集,作为接下来的训练数据

    二维数据集
    500个样本,2个特征(0, 1)
    import numpy as np
    import matplotlib.pyplot as plt
    1
    2
    ## 创建数据集
    from sklearn import datasets

    x, y = datasets.make_moons(n_samples=500, noise=0.3, random_state=42)
    1
    2
    3
    4
    plt.scatter(x[y==0,0],x[y==0,1])
    plt.scatter(x[y==1,0],x[y==1,1])
    plt.show()
    1
    2
    3


    一,什么是集成学习
    集成学习的思想其实就是我们使用多个弱学习器一起解决一个问题,类似于“三个臭皮匠赛过诸葛亮”的道理。

    首先,我们把数据集分为训练集和测试集

    ## 进行数据切分
    from sklearn.model_selection import train_test_split

    x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=42)
    1
    2
    3
    4
    我们分别使用逻辑回归,SVC和决策树进行数据学习,并且分别得到他们每一个准确率。

    from sklearn.linear_model import LogisticRegression

    log_clf = LogisticRegression()
    log_clf.fit(x_train, y_train)
    log_clf.score(x_test, y_test)
    >>>0.864
    1
    2
    3
    4
    5
    6
    from sklearn.svm import SVC

    svm_clf = SVC()
    svm_clf.fit(x_train, y_train)
    svm_clf.score(x_test, y_test)
    >>>0.888
    1
    2
    3
    4
    5
    6
    from sklearn.tree import DecisionTreeClassifier

    df_clf = DecisionTreeClassifier()
    df_clf.fit(x_train, y_train)
    df_clf.score(x_test, y_test)
    >>>0.84
    1
    2
    3
    4
    5
    6
    接下来,再分别适用三个基学习器对测试集进行预测

    ## 分别得到三种基学习器的预测结果
    y_predict1 = log_clf.predict(x_test)
    y_predict2 = svm_clf.predict(x_test)
    y_predict3 = df_clf.predict(x_test)
    1
    2
    3
    4
    最后,我们通过投票的方式集成以上三种基学习器的学习结果

    ## 集成以上三种的预测数据,通过投票的方法得到集成结果
    y_predict = np.array((y_predict1 + y_predict2 + y_predict3) >= 2,dtype=int)
    y_predict[:10]
    >>>array([1, 0, 0, 1, 1, 1, 0, 0, 0, 0])
    1
    2
    3
    4
    通过计算集成学习的准确率可以看出,准确率有明显的提升,而这仅仅使用了500个样本和3个基学习器。

    ## 计算集成学习的准确率
    from sklearn.metrics import accuracy_score

    accuracy_score(y_test, y_predict)
    >>>0.896
    1
    2
    3
    4
    5
    二,使用SKlearn中提供的集成学习器解决分类问题
    2.1 Voting Classifier 投票集成
    我们可以指定想用那几个基学习器,例如下面我们就指定选用了逻辑回归,SVC和决策树作为基学习器。

    2.1.1 少数服从多数原则的投票集成-Hard Voting
    这里我们依旧使用逻辑回归,SVC和决策树作为基学习器。
    参数说明:

    使用哪几个基学习器 estimators = [ (‘名字1’, 基学习器1), (‘名字2’, 基学习器2)…]
    voting=‘hard’ 表示使用简单地投票方法得到集成结果(少数服从多数原则,后边会提到考虑概率的投票方法)
    from sklearn.ensemble import VotingClassifier

    ## 考虑我们要使用那些基学习器进行集成
    estimators = [
    ('log_clf', LogisticRegression()),
    ('svm_clf', SVC()),
    ('df_clf', DecisionTreeClassifier())
    ]

    ## 训练集成算法(voting='hard'表示使用投票方式得到集成结果)
    voting_clf = VotingClassifier(estimators=estimators, voting='hard')
    voting_clf.fit(x_train, y_train)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    这里我把训练后返回的学习器参数单独列了出来(如下),可以看到我们使用的每一个基学习器的参数。

    >>>VotingClassifier(estimators=[('log_clf',
    LogisticRegression(C=1.0, class_weight=None,
    dual=False, fit_intercept=True,
    intercept_scaling=1,
    l1_ratio=None, max_iter=100,
    multi_class='warn',
    n_jobs=None, penalty='l2',
    random_state=None,
    solver='warn', tol=0.0001,
    verbose=0, warm_start=False)),
    ('svm_clf',
    SVC(C=1.0, cache_size=200, class_weight=None,
    coef0=0.0, decision_f...
    ('df_clf',
    DecisionTreeClassifier(class_weight=None,
    criterion='gini',
    max_depth=None,
    max_features=None,
    max_leaf_nodes=None,
    min_impurity_decrease=0.0,
    min_impurity_split=None,
    min_samples_leaf=1,
    min_samples_split=2,
    min_weight_fraction_leaf=0.0,
    presort=False,
    random_state=None,
    splitter='best'))],
    flatten_transform=True, n_jobs=None, voting='hard',
    weights=None)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    依然和之前学过的学习器一样,通过score方法得到学习器的准确率

    voting_clf.score(x_test, y_test)
    >>>0.904
    1
    2
    2.1.2 考虑概率的投票集成-Soft Voting
    假设有以下5种基学习器

    模型1 A-99%;B-1% ---- 最终结果:A
    模型2 A-49%;B-51% ---- 最终结果:B
    模型3 A-40%;B-60% ---- 最终结果:B
    模型4 A-90%;B-10% ---- 最终结果:A
    模型5 A-30%;B-70% ---- 最终结果:B
    若按照简单投票的方法的到最终结果,则结果为B

    但这样显然是不合理的,因为很容易看出来选择A的基学习器更加确定自己的选择,而B则不是。

    所以我们考虑对每一个选则进行加权(选择的确定性)

    A-(0.99 + 0.49 + 0.4 + 0.9 + 0.3)/5 = 0.616
    B-(0.01 + 0.51 + 0.6 + 0.1 + 0.7)/5 = 0.384
    则此时最终结果为A

    所以说,我们如果要使用Soft Voting:要求集合的每一个模型都能估计概率。

    逻辑回归 - 本身就是基于概率模型
    kNN - 考虑5个最近点,3个是A ,2个是B,则结果为A-3/5%
    决策树 - 与kNN相似
    SVC - 要设置参数 probability=True
    参数:voting='soft'表示使用考虑概率投票的方法得到集成结果

    ## 注意:svc算法要设置参数才会计算概率
    estimators = [
    ('log_clf', LogisticRegression()),
    ('svm_clf', SVC(probability=True)),
    ('df_clf', DecisionTreeClassifier())
    ]

    ## 设置参数 voting='soft',才支持计算概率
    voting_clf2 = VotingClassifier(estimators=estimators, voting='soft')
    voting_clf2.fit(x_train, y_train)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>>VotingClassifier(estimators=[('log_clf',
    LogisticRegression(C=1.0, class_weight=None,
    dual=False, fit_intercept=True,
    intercept_scaling=1,
    l1_ratio=None, max_iter=100,
    multi_class='warn',
    n_jobs=None, penalty='l2',
    random_state=None,
    solver='warn', tol=0.0001,
    verbose=0, warm_start=False)),
    ('svm_clf',
    SVC(C=1.0, cache_size=200, class_weight=None,
    coef0=0.0, decision_f...
    ('df_clf',
    DecisionTreeClassifier(class_weight=None,
    criterion='gini',
    max_depth=None,
    max_features=None,
    max_leaf_nodes=None,
    min_impurity_decrease=0.0,
    min_impurity_split=None,
    min_samples_leaf=1,
    min_samples_split=2,
    min_weight_fraction_leaf=0.0,
    presort=False,
    random_state=None,
    splitter='best'))],
    flatten_transform=True, n_jobs=None, voting='soft',
    weights=None)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    通过计算准确率,可以看出对于此数据,通过考虑概率投票得到的集成结果准确率更高。

    ## 可以看出考虑概率的准确率更高
    voting_clf2.score(x_test, y_test)
    >>>0.912
    1
    2
    3
    2.2 Bagging 和 Pasting
    虽然有很多机器学习方法,但从投票角度看,仍然不够多的;

    我们需要创建更多的子模型!集成更多子模型的意见,但是子模型之间不能一致,子模型之间要有差异性。

    如何创建差异性?

    每个子模型只看样本数据的一部分。
    此时,子模型的准确率会降低,但是对于每个子模型不需要太高的准确率。
    下边举了个例子可以看一下

    如何从所有数据中取样

    放回取样 - Bagging(更常用,使用的数据更少,减少了随机问题的影响)
    统计学中,放回取样叫 bootstrap
    不放回取样 - Pasting
    2.2.1 如何使用 Bagging(套袋分类器)
    关于BaggingClassifier]的参数,属性和方法详细说明:

    算法介绍:集成方法 - BaggingClassifier
    官方说明:套袋分类器
    这里我们使用决策树模型举例(决策树模型个容易产生差异性,则当需要很多基学习器时,优先选择决策树模型)

    from sklearn.tree import DecisionTreeClassifier
    from sklearn.ensemble import BaggingClassifier

    # 参数:基学习器 DecisionTreeClassifier(),
    # 构建基学习器数量 n_estimators=500,
    # 每个基学习器训练所需的样本数量 max_samples==100,
    # 是否为放回取样bootstrap=True
    bagging_clf = BaggingClassifier(DecisionTreeClassifier(),
    n_estimators=500, max_samples=100, bootstrap=True)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    bagging_clf.fit(x_train, y_train)
    bagging_clf.score(x_test, y_test)
    # 如果使用一个决策树,即是使用所有样本训练也会比这个准确度低
    >>>0.904
    1
    2
    3
    4
    如果创建更多的基学习器呢?

    # 创建更多的基学习器(5000个)
    bagging_clf2 = BaggingClassifier(DecisionTreeClassifier(), n_estimators=5000, max_samples=100, bootstrap=True)
    bagging_clf2.fit(x_train, y_train)
    bagging_clf2.score(x_test, y_test)
    >>>0.912
    1
    2
    3
    4
    5
    2.2.2 关于袋外数据(oob)
    没有选到的数据(称为:袋外数据 Out-of-Bag)

    放回取样会导致一部分样本很有可能没有取到,平均大约有37%的样本没有取到。
    因此,我们可以不使用测试数据集,而使用没有取到的样本进行测试/验证。

    这时需要在训练时要设置参数oob_score=True,并且在训练集成学习器时我们就可以将全部数据都作为训练数据。

    使用用oob_score_属性调用得到使用袋外数据测试出的精确度。

    我们使用全部数据重新训练一个集成学习器

    基学习器依旧为决策树
    需要设置参数oob_score=True,其他参数不变
    from sklearn.tree import DecisionTreeClassifier
    from sklearn.ensemble import BaggingClassifier

    bagging_clf3 = BaggingClassifier(DecisionTreeClassifier(),
    n_estimators=500, max_samples=100, bootstrap=True, oob_score=True)
    bagging_clf3.fit(x, y)
    >>>BaggingClassifier(base_estimator=DecisionTreeClassifier(class_weight=None,
    criterion='gini',
    max_depth=None,
    max_features=None,
    max_leaf_nodes=None,
    min_impurity_decrease=0.0,
    min_impurity_split=None,
    min_samples_leaf=1,
    min_samples_split=2,
    min_weight_fraction_leaf=0.0,
    presort=False,
    random_state=None,
    splitter='best'),
    bootstrap=True, bootstrap_features=False, max_features=1.0,
    max_samples=100, n_estimators=500, n_jobs=None,
    oob_score=True, random_state=None, verbose=0,
    warm_start=False)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    获得使用袋外数据测得的准确率

    bagging_clf3.oob_score_
    >>>0.92
    1
    2
    2.2.3 同时对特征进行随机采样
    我们可以把样本看成一个矩阵,横向代表一个样本,纵向代表每一种特征,就相当于随机取矩阵中的元素(例如下图,红色为随即取出的样本数据)

    参数说明:

    是否针对特征随机取样 bootstrap_features=True
    每次特征取样的特征数 max_features=1
    random_patches_clf = BaggingClassifier(DecisionTreeClassifier(),
    n_estimators=100, max_samples=500, bootstrap=True,
    oob_score=True, bootstrap_features=True, max_features=1)
    random_patches_clf.fit(x, y)
    random_patches_clf.oob_score_
    >>>0.81
    1
    2
    3
    4
    5
    6
    可以看出准确率并没有明显的提升,这是因为,我们的样本数据只有两个特征,当我们的数据特征很多事,才适合对特征进行随机取样。

    另外,如果我们设置参数max_samples=样本总数(相当于每个基学习器都使用了全部的数据),就实现了只针对特进行随机取样。

    2.3 随机森林
    在Bagging中,如果我们使用的基学习器是决策树的话,也可以称为随机森林(当然sklearn中也有专门用于决策树的类)。
    决策树在节点划分上,在随机的特征子集上寻找最优划分特征(进一步增加了随机性)。

    2.3.1 RandomForestClassifier
    官网参数说明:随机森林分类器

    from sklearn.ensemble import RandomForestClassifier

    rf_clf = RandomForestClassifier(n_estimators=500, oob_score=True)
    rf_clf.fit(x, y)
    1
    2
    3
    4
    可以看出返回的参数,大部分都是决策树中的所包含的参数。

    >>>RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',
    max_depth=None, max_features='auto', max_leaf_nodes=None,
    min_impurity_decrease=0.0, min_impurity_split=None,
    min_samples_leaf=1, min_samples_split=2,
    min_weight_fraction_leaf=0.0, n_estimators=500,
    n_jobs=None, oob_score=True, random_state=666, verbose=0,
    warm_start=False)
    1
    2
    3
    4
    5
    6
    7
    rf_clf.oob_score_
    >>>0.896
    1
    2
    2.3.2 ExtraTreesClassifier
    官网参数说明:额外的树分类器

    此类实现一个元估计量,该量量估计量适合数据集的各个子样本上的许多随机决策树(又名额外树),并使用平均数来提高预测准确性和控制过度拟合。
    决策树在节点划分上,使用随机的特征和随机的阈(yǜ)值
    提供额外的随机性,抑制过拟合,但增大了bias(偏差)
    更快的训练速度

    from sklearn.ensemble import ExtraTreesClassifier

    et_clf = ExtraTreesClassifier(n_estimators=500, bootstrap=True, oob_score=True)
    et_clf.fit(x, y)
    >>>ExtraTreesClassifier(bootstrap=True, class_weight=None, criterion='gini',
    max_depth=None, max_features='auto', max_leaf_nodes=None,
    min_impurity_decrease=0.0, min_impurity_split=None,
    min_samples_leaf=1, min_samples_split=2,
    min_weight_fraction_leaf=0.0, n_estimators=500,
    n_jobs=None, oob_score=True, random_state=None, verbose=0,
    warm_start=False)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    et_clf.oob_score_
    >>>0.892
    1
    2
    三,集成学习解决回归问题
    上边讲到的都是针对回归问题,那么我们如何让解决回归问题呢?

    当然,sklearn也提供了相应的包供我们使用,并且参数与分类问题的集成学习器参数相似,用法也近乎已知,下边给出了对应的包,具体参数大家可以在官方网站中查询,这里就不做过多解释了。

    # 套袋分类器
    from sklearn.ensemble import BaggingRegressor
    # 随机森林
    from sklearn.ensemble import RandomForestRegressor
    # 额外的随机森林
    from sklearn.ensemble import ExtraTreesRegress
    ————————————————
    版权声明:本文为CSDN博主「壮壮不太胖」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/weixin_46072771/java/article/details/106544135

  • 相关阅读:
    MVC总结
    Python在Linux | Windows中输出带颜色的文字的方法
    flushdns
    linux配置java环境变量(详细)
    ELK
    sed 时间段
    如何让root用户能直接进行ssh登录?
    rsync有两种常用的认证方式,另外一种则是ssh。
    windows rsync server
    awk
  • 原文地址:https://www.cnblogs.com/advocate/p/13042931.html
Copyright © 2011-2022 走看看