机器学习中的Bagging

一、前言

(1)集成学习

集成学习通过建立几个模型来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成组合预测,因此优于任何一个单分类的做出预测。

(2)集成学习中boosting和Bagging

在集成学习中boosting是用来解决欠拟合问题,Bagging是用来解决过拟合问题。只要单分类器的表现不太差,集成学习的结果总是要好于单分类器的。

 

二、Bagging和随机森林

(1)Bagging集成原理

目标:把下面的圈和方块进行分类

实现步骤:

  • 1、 采样不同数据集(从原始数据集中进行随机的采样得到n组规模大小相似的子集)

  • 2、训练分类器(为1中的n个数据集创建对应的分类器,并对其进行训练)

  • 3、平权投票,获取最终结果(使用2中的n个分别对测试集进行预测,将预测结果进行无差别的平均投票,分类结果取票数最多的)

(2)随机森林构造过程

随机森林 = Bagging + 决策树 。

在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。

随机森林的构建过程如下图所示:

(3)sklearn中随机森林API

  • sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’, max_depth=None, bootstrap=True, random_state=None, min_samples_split=2)

    • n_estimators:integer,optional(default = 10)森林里的树木数量120,200,300,500,800,1200

      • 在利用最大投票数或平均值来预测之前,你想要建立子树的数量。
    • Criterion:string,可选(default =“gini”)

      • 分割特征的测量方法
    • max_depth:integer或None,可选(默认=无)

      • 树的最大深度 5,8,15,25,30
    • max_features="auto”,每个决策树的最大特征数量

      • If "auto", then max_features=sqrt(n_features).
      • If "sqrt", then max_features=sqrt(n_features)(same as "auto").
      • If "log2", then max_features=log2(n_features).
      • If None, then max_features=n_features.
    • bootstrap:boolean,optional(default = True)

      • 是否在构建树时使用放回抽样
    • min_samples_split 内部节点再划分所需最小样本数

      • 这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分,默认是2。
      • 如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。
    • min_samples_leaf 叶子节点的最小样本数

      • 这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝, 默认是1。

      • 叶是决策树的末端节点。 较小的叶子使模型更容易捕捉训练数据中的噪声。

      • 一般来说,我更偏向于将最小叶子节点数目设置为大于50。

    • min_impurity_split: 节点划分最小不纯度

      • 这个值限制了决策树的增长,如果某节点的不纯度(基于基尼系数,均方差)小于这个阈值,则该节点不再生成子节点。即为叶子节点 。

      • 一般不推荐改动默认值1e-7。

  • 上面决策树参数中最重要的包括

    • 最大特征数max_features,
    • 最大深度max_depth,
    • 内部节点再划分所需最小样本数min_samples_split
    • 叶子节点最少样本数min_samples_leaf。

(4) kaggle otto 商品分类案例

题目来源:https://www.kaggle.com/c/otto-group-product-classification-challenge/overview

奥托集团是世界上最大的电子商务公司之一,在20多个国家设有子公司。该公司每天都在世界各地销售数百万种产品,所以对其产品根据性能合理的分类非常重要。不过,在实际工作中,工作人员发现,许多相同的产品得到了不同的分类。本案例要求,你对奥拓集团的产品进行正确的分分类。尽可能的提供分类的准确性。

  • 数据集介绍

          本案例中,数据集包含大约200,000种产品的93个特征。

          其目的是建立一个能够区分otto公司主要产品类别的预测模型。

         所有产品共被分成九个类别(例如时装,电子产品等)。

  • 评分标准

本案例中,最后结果使用多分类对数损失进行评估。

                                             

          i表示样本,j表示类别。Pij代表第i个样本属于类别j的概率,

          如果第i个样本真的属于类别j,则yij等于1,否则为0。

          根据上公式,假如你将所有的测试样本都正确分类,所有pij都是1,那每个log(pij)都是0,最终的logloss也是0。

          假如第1个样本本来是属于1类别的,但是你给它的类别概率pij=0.1,那logloss就会累加上log(0.1)这一项。我们知道这一项是负数,而且pij越小,负得越多,如果pij=0,将是无穷。这会导致这种情况:你分错了一个,logloss就是无穷。这当然不合理,为了避免这一情况,我们对非常小的值做如下处理:

image-20191104203941475

         也就是说最小不会小于10^-15。

实现流程

  • 获取数据
  • 数据基本处理
    • 数据量比较大,尝试是否可以进行数据分割
    • 转换目标值表示方式
  • 模型训练
    • 模型基本训练

代码:

1 导包

import pandas as pd 
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from imblearn.under_sampling import RandomUnderSampler
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import log_loss

2 数据获取

data = pd.read_csv('./train.csv')

2.1 查看数据分布

# 图像可视化查看数据分布
sns.countplot(data.target)
plt.show()

3 数据基本处理

3.1截取部分数据

# 使用随机欠采样方法
# 划分特征和目标值
x = data.drop(['id', 'target'], axis=1)
y = data['target']
rus = RandomUnderSampler()
x_resampled, y_reamapled =rus.fit_resample(x,y)
sns.countplot(y_reamapled)

3.2 将类别字符串转换为数字标签

le = LabelEncoder()
y_reamapled = le.fit_transform(y_reamapled)
sns.countplot(y_reamapled)

4 数据分割

x_train, x_test,y_train,y_test = train_test_split(x_resampled,y_reamapled, test_size=0.2)

5 机器学习

# 实例化随机森林
rf = RandomForestClassifier(oob_score=True)
# 模型训练
rf.fit(x_train, y_train)

y_pre = rf.predict(x_test)
# 模型准确率的分
print(rf.score(x_test, y_test))
# 包外估计
print(rf.oob_score_)

# 计算log_loss 损失
# 1实例化onehot编码转换器
onehot_decoder = OneHotEncoder(sparse=False)

# 2 将真实值和预测值转换为onehot编码
y_test1 = onehot_decoder.fit_transform(y_test.reshape(-1, 1))
y_pre1 = onehot_decoder.fit_transform(y_pre.reshape(-1, 1))

# 3 计算损失
log_loss_1 =  log_loss(y_test1, y_pre1,eps=1e-15, normalize=True)

# 4 上述损失太大,因为预测值是0、1这些数,如果用概率替换会好很多
# 5 将预测值转换为概率值
y_pre_pro = rf.predict_proba(x_test)

# 6 在此计算loss
log_loss_2 = log_loss(y_test1, y_pre_pro, eps=1e-15, normalize=True)

(5) 4中的模型优化

在随机森林中又n_estimators, max_feature, max_depth, min_samples_leaf这些参数可以被优化。

1 确定最优的n_estimator

# 确定n_estimator的取值范围
turned_parameters = range(5,1000,1)
acc_t = np.zeros(len(turned_parameters))
err_t = np.zeros(len(turned_parameters))

for i, one_parameter in enumerate(turned_parameters):
    rf2 = RandomForestClassifier(n_estimators=one_parameter,
                                max_depth=10,
                                max_features=10,
                                min_samples_leaf=10,
                                oob_score=True,
                                random_state=10,
                                n_jobs=-1)
    rf2.fit(x_train, y_train)
    acc_t[i] = rf2.oob_score_
    y_pre = rf2.predict_proba(x_test)
    err_t[i] = log_loss(y_test, y_pre,eps=1e-15, normalize=True)


fig, axes = plt.subplots(nrows=1, ncols=2,figsize=(20,4),dpi=100)
axes[0].plot(turned_parameters,err_t)
axes[1].plot(turned_parameters, acc_t)
axes[0].set_xlabel("n_estimators")
axes[0].set_ylabel('err_t')
axes[1].set_xlabel("n_estimators")
axes[1].set_ylabel('acc_t')
axes[0].grid(True)
axes[1].grid(True)

从图中可知 n_estimators为400左右时最佳

2 确定最优的max_feature

 # 确定max_feature的取值范围
turned_parameters = range(5,40,1)
acc_t = np.zeros(len(turned_parameters))
err_t = np.zeros(len(turned_parameters))

for i, one_parameter in enumerate(turned_parameters):
    rf2 = RandomForestClassifier(n_estimators=400,
                                max_depth=10,
                                max_features=one_parameter,
                                min_samples_leaf=10,
                                oob_score=True,
                                random_state=10,
                                n_jobs=-1)
    rf2.fit(x_train, y_train)
    acc_t[i] = rf2.oob_score_
    y_pre = rf2.predict_proba(x_test)
    err_t[i] = log_loss(y_test, y_pre,eps=1e-15, normalize=True)


fig, axes = plt.subplots(nrows=1, ncols=2,figsize=(20,4),dpi=100)
axes[0].plot(turned_parameters,err_t)
axes[1].plot(turned_parameters, acc_t)
axes[0].set_xlabel("max_feature")
axes[0].set_ylabel('err_t')
axes[1].set_xlabel("max_feature")
axes[1].set_ylabel('acc_t')
axes[0].grid(True)
axes[1].grid(True)

从上图可知max_feature为15时候最佳

3 确定最优的max_depth

# 确定max_depth的取值范围
turned_parameters = range(10,100,2)
acc_t = np.zeros(len(turned_parameters))
err_t = np.zeros(len(turned_parameters))

for i, one_parameter in enumerate(turned_parameters):
    rf2 = RandomForestClassifier(n_estimators=400,
                                max_depth=one_parameter,
                                max_features=15,
                                min_samples_leaf=10,
                                oob_score=True,
                                random_state=10,
                                n_jobs=-1)
    rf2.fit(x_train, y_train)
    acc_t[i] = rf2.oob_score_
    y_pre = rf2.predict_proba(x_test)
    err_t[i] = log_loss(y_test, y_pre,eps=1e-15, normalize=True)
fig, axes = plt.subplots(nrows=1, ncols=2,figsize=(20,4),dpi=100)
axes[0].plot(turned_parameters,err_t)
axes[1].plot(turned_parameters, acc_t)
axes[0].set_xlabel("max_depth")
axes[0].set_ylabel('err_t')
axes[1].set_xlabel("max_depth")
axes[1].set_ylabel('acc_t')
axes[0].grid(True)
axes[1].grid(True)

从上图可知max_depth为30时候最佳

4 确定最优的min_samples_leaf

# 确定min_samples_leaf的取值范围
turned_parameters = range(1,10,1)
acc_t = np.zeros(len(turned_parameters))
err_t = np.zeros(len(turned_parameters))

for i, one_parameter in enumerate(turned_parameters):
    rf2 = RandomForestClassifier(n_estimators=400,
                                max_depth=10,
                                max_features=15,
                                min_samples_leaf=one_parameter,
                                oob_score=True,
                                random_state=10,
                                n_jobs=-1)
    rf2.fit(x_train, y_train)
    acc_t[i] = rf2.oob_score_
    y_pre = rf2.predict_proba(x_test)
    err_t[i] = log_loss(y_test, y_pre,eps=1e-15, normalize=True)

fig, axes = plt.subplots(nrows=1, ncols=2,figsize=(20,4),dpi=100)
axes[0].plot(turned_parameters,err_t)
axes[1].plot(turned_parameters, acc_t)
axes[0].set_xlabel("min_samples_leaf")
axes[0].set_ylabel('err_t')
axes[1].set_xlabel("min_samples_leaf")
axes[1].set_ylabel('acc_t')
axes[0].grid(True)
axes[1].grid(True)

从上图可知min_samples_leaf为1时候最佳

5 模型评估

rf3 = RandomForestClassifier(n_estimators=400,
                                max_depth=30,
                                max_features=15,
                                min_samples_leaf=1,
                                oob_score=True,
                                random_state=10,
                                n_jobs=-1)
rf3.fit(x_train, y_train)
print(rf3.oob_score_)
y_pre_prob_3 = rf3.predict_proba(x_test)
loss = log_loss(y_test, y_pre_prob_3)
print(loss)

综上所述:包外估计准确率、log_loss损失都被优化了

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值