集成学习通过建立几个模型来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成组合预测,因此优于任何一个单分类的做出预测。
只要单分类器的表现不太差,集成学习的结果总是要好于单分类器的
在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。
随机森林 = Bagging + 决策树
例如, 如果你训练了5个树, 其中有4个树的结果是True, 1个树的结果是False, 那么最终投票结果就是True
随机森林构造过程中的关键步骤(M表示特征数目):
1)一次随机选出一个样本,有放回的抽样,重复N次(有可能出现重复的样本)
2) 随机去选出m个特征, m < 思考 在随机森林构造过程中,如果进行有放回的抽样,我们会发现,总是有一部分样本我们选不到。 随机森林的 Bagging 过程,对于每一颗训练出的决策树 g t g_t gt,与数据集 D D D 有如下关系: 经验证,包外估计是对集成分类器泛化误差的无偏估计 在随机森林算法中数据集属性的重要性、分类器集强度和分类器间相关性计算都依赖于袋外数据。 什么是无偏估计:参考 n_estimators:integer,optional(default = 10)森林里的树木数量120,200,300,500,800,1200 Criterion:string,可选(default =“gini”) max_depth:integer或None,可选(默认=无) max_features="auto”,每个决策树的最大特征数量 bootstrap:boolean,optional(default = True) min_samples_split 内部节点再划分所需最小样本数 这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分,默认是2。 如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。 min_samples_leaf 叶子节点的最小样本数 这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝, 默认是1。 叶是决策树的末端节点。 较小的叶子使模型更容易捕捉训练数据中的噪声。 一般来说,我更偏向于将最小叶子节点数目设置为大于50。 min_impurity_split: 节点划分最小不纯度 一般不推荐改动默认值1e-7。 上面决策树参数中最重要的包括 基于泰坦尼克号乘客生存预测案例的x_train,y_train进行训练 实例化随机森林 定义超参数的选择列表 使用GridSearchCV进行网格搜索 注意: Bagging + 决策树/线性回归/逻辑回归/深度学习… = bagging集成学习方法 经过上面方式组成的集成学习方法: 奥托集团是世界上最大的电子商务公司之一,在20多个国家设有子公司。该公司每天都在世界各地销售数百万种产品,所以对其产品根据性能合理的分类非常重要。 不过,在实际工作中,工作人员发现,许多相同的产品得到了不同的分类。本案例要求,你对奥拓集团的产品进行正确的分类。尽可能的提供分类的准确性。 链接:https://www.kaggle.com/c/otto-group-product-classification-challenge/overview 本案例中,最后结果使用多分类对数损失进行评估。 截取部分数据 可以看到经过欠采样以后数据的分布平衡了 把标签值转换成数字 分割数据 这里报了错:y_true and y_pred contain different number of classes 9, 2. Please provide the true labels explicitly through the labels argument. Classes found in y_true: [0 1 2 3 4 5 6 7 8] 确定最优的n_estimators 经过图像展示,最后确定n_estimators=175的时候,表现效果不错 确定最优的max_features 经过图像展示,最后确定max_features=15的时候,表现效果不错 确定最优的max_depth 经过图像展示,最后确定max_depth=30的时候,表现效果不错 确定最优的min_sample_leaf 经过图像展示,最后确定min_sample_leaf=1的时候,表现效果不错 之后将csv文件提交到kaggle上就可以了 简而言之:每新加入一个弱学习器,整体能力就会得到提升 代表算法:Adaboost,GBDT,XGBoost,LightGBM 区别一:数据方面 区别二:投票方面 区别三:学习顺序 区别四:主要作用 如何确认投票权重? 给定下面这张训练数据表所示的数据,假设弱分类器由xv产生,其阈值v使该分类器在训练数据集上的分类误差率最低,试用Adaboost算法学习一个强分类器。 api介绍链接:点这 api的使用方法和前面差不多,可以动手试一试 GBDT 的全称是 Gradient Boosting Decision Tree,梯度提升树,在传统机器学习算法中,GBDT算的上TOP3的算法。想要理解GBDT的真正意义,那就必须理解GBDT中的Gradient Boosting 和Decision Tree分别是什么? 首先,GBDT使用的决策树是CART回归树,无论是处理回归问题还是二分类以及多分类,GBDT使用的决策树通通都是都是CART回归树。 对于回归树算法来说最重要的是寻找最佳的划分点,那么回归树中的可划分点包含了所有特征的所有可取的值。 在分类树中最佳划分点的判别标准是熵或者基尼系数,都是用纯度来衡量的,但是在回归树中的样本标签是连续数值,所以再使用熵之类的指标不再合适,取而代之的是平方误差,它能很好的评判拟合程度。 梯度提升树(Grandient Boosting)是提升树(Boosting Tree)的一种改进算法,所以在讲梯度提升树之前先来说一下提升树。 先来个通俗理解:假如有个人30岁,我们首先用20岁去拟合,发现损失有10岁,这时我们用6岁去拟合剩下的损失,发现差距还有4岁,第三轮我们用3岁拟合剩下的差距,差距就只有一岁了。如果我们的迭代轮数还没有完,可以继续迭代下面,每一轮迭代,拟合的岁数误差都会减小。最后将每次拟合的岁数加起来便是模型输出的结果。 针对这一问题,Friedman提出了梯度提升树算法,这是利用最速下降的近似方法,其关键是利用损失函数的负梯度作为提升树算法中的残差的近似值。 那么负梯度长什么样呢? 那么对于分类问题呢? 本文以回归问题为例进行讲解。 上面两节分别将Decision Tree和Gradient Boosting介绍完了,下面将这两部分组合在一起就是我们的GBDT了。 根据如下数据,预测最后一个样本的身高。 上一篇:机器学习:决策树
如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的
如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“片面的”(当然这样说可能不对),也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树(弱分类器)的投票表决。3 包外估计 (Out-of-Bag Estimate)
3.1 包外估计的定义
对于星号的部分,即是没有选择到的数据,称之为 Out-of-bag(OOB)数据,当数据足够多,对于任意一组数据 ( x n , y n ) (x_n, y_n) (xn,yn) 是包外数据的概率为:
由于基分类器是构建在训练样本的自助抽样集上的,只有约 63.2 % 63.2\% 63.2% 原样本集出现在中,而剩余的 36.8 % 36.8\% 36.8% 的数据作为包外数据,可以用于基分类器的验证集。
3.2 包外估计的用途
4 随机森林api介绍
sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’, max_depth=None, bootstrap=True, random_state=None, min_samples_split=2)
在利用最大投票数或平均值来预测之前,你想要建立子树的数量。
分割特征的测量方法
树的最大深度 5,8,15,25,30
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
是否在构建树时使用放回抽样
这个值限制了决策树的增长,如果某节点的不纯度(基于基尼系数,均方差)小于这个阈值,则该节点不再生成子节点。即为叶子节点 。
5 随机森林预测案例
from sklearn.ensemble import RandomForestClassifier
# 随机森林去进行预测
rf = RandomForestClassifier()
from sklearn.model_selection import GridSearchCV
param = {"n_estimators": [120,200,300,500,800,1200], "max_depth": [5, 8, 15, 25, 30]}
# 超参数调优
gc = GridSearchCV(rf, param_grid=param, cv=2)
gc.fit(x_train, y_train)
print("随机森林预测的准确率为:", gc.score(x_test, y_test))
6 bagging集成优点
三、otto案例介绍 – Otto Group Product Classification Challenge
1.背景介绍
2.数据集介绍
3.评分标准
m a x ( m i n ( p , 1 − 1 0 − 15 ) , 1 0 − 15 ) max(min(p,1-10^{-15}),10^{-15}) max(min(p,1−10−15),10−15)4.实现过程
4.1 流程分析
4.2 代码实现
数据基本展示
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# 导入数据
data = pd.read_csv("./data/otto/train.csv")
# 图形可视化,查看数据分布
sns.countplot(data.target)
plt.show()
数据基本处理
# 首先需要确定标签值
y = data["target"]
x = data.drop(["id","target"],axis=1)
# 欠采样获取数据
from imblearn.under_sampling import RandomUnderSampler
rus = RandomUnderSampler(random_state=0)
X_resampled, y_resampled = rus.fit_resample(x,y)
print(X_resampled.shape,y_resampled.shape)
# (17361, 93) (17361,)
# 图形可视化,查看数据分布
sns.countplot(y_resampled)
plt.show()
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
y_resampled = le.fit_transform(y_resampled)
print(y_resampled)
# [0 0 0 ... 8 8 8]
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(X_resampled,y_resampled,test_size=0.2)
print(x_train.shape,y_train.shape) # (13888, 93) (13888,)
print(x_test.shape,y_test.shape) # (3473, 93) (3473,)
基本模型训练
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(oob_score=True)
rf.fit(x_train,y_train)
y_pre = rf.predict(x_test)
y_pre #array([4, 3, 3, ..., 1, 8, 3])
rf.score(x_test, y_test) #0.7817448891448315
rf.oob_score_ #0.7626008064516129
# 图形可视化,查看数据分布
sns.countplot(y_pre)
plt.show()
# logloss模型评估
from sklearn.metrics import log_loss
log_loss(y_test, y_pre, eps=1e-15, normalize=True)
解决办法就是将y值改为独热编码from sklearn.preprocessing import OneHotEncoder
one_hot = OneHotEncoder(sparse=False)
y_test1 = one_hot.fit_transform(y_test.reshape(-1,1))
y_pre1 = one_hot.fit_transform(y_pre.reshape(-1,1))
# logloss模型评估
log_loss(y_test1, y_pre1, eps=1e-15, normalize=True)
# 7.538264470873115
# 改变预测值的输出模式,让输出结果为百分占比,降低logloss值
y_pre_proba = rf.predict_proba(x_test)
# logloss模型评估
log_loss(y_test1, y_pre_proba, eps=1e-15, normalize=True)
# 0.7378124652239569
模型调优
n_estimators, max_feature, max_depth, min_samples_leaf
# 确定n_estimators的取值范围
tuned_parameters = range(10, 200, 10)
# 创建添加accuracy的一个numpy
accuracy_t = np.zeros(len(tuned_parameters))
# 创建添加error的一个numpy
error_t = np.zeros(len(tuned_parameters))
# 调优过程实现
for j, one_parameter in enumerate(tuned_parameters):
rf2 = RandomForestClassifier(n_estimators=one_parameter,
max_depth=10,
max_features=10,
min_samples_leaf=10,
oob_score=True,
random_state=0,
n_jobs=-1)
rf2.fit(x_train, y_train)
# 输出accuracy
accuracy_t[j] = rf2.oob_score_
# 输出log_loss
y_pre = rf2.predict_proba(x_test)
error_t[j] = log_loss(y_test, y_pre, eps=1e-15, normalize=True)
print(error_t)
# 优化结果过程可视化
fig,axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 4), dpi=100)
axes[0].plot(tuned_parameters, error_t)
axes[1].plot(tuned_parameters, accuracy_t)
axes[0].set_xlabel("n_estimators")
axes[0].set_ylabel("error_t")
axes[1].set_xlabel("n_estimators")
axes[1].set_ylabel("accuracy_t")
axes[0].grid(True)
axes[1].grid(True)
plt.show()
# 确定max_features的取值范围
tuned_parameters = range(5, 40, 5)
# 创建添加accuracy的一个numpy
accuracy_t = np.zeros(len(tuned_parameters))
# 创建添加error的一个numpy
error_t = np.zeros(len(tuned_parameters))
# 调优过程实现
for j, one_parameter in enumerate(tuned_parameters):
rf2 = RandomForestClassifier(n_estimators=175,
max_depth=10,
max_features=one_parameter,
min_samples_leaf=10,
oob_score=True,
random_state=0,
n_jobs=-1)
rf2.fit(x_train, y_train)
# 输出accuracy
accuracy_t[j] = rf2.oob_score_
# 输出log_loss
y_pre = rf2.predict_proba(x_test)
error_t[j] = log_loss(y_test, y_pre, eps=1e-15, normalize=True)
print(error_t)
# 优化结果过程可视化
fig,axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 4), dpi=100)
axes[0].plot(tuned_parameters, error_t)
axes[1].plot(tuned_parameters, accuracy_t)
axes[0].set_xlabel("max_features")
axes[0].set_ylabel("error_t")
axes[1].set_xlabel("max_features")
axes[1].set_ylabel("accuracy_t")
axes[0].grid(True)
axes[1].grid(True)
plt.show()
# 确定max_depth的取值范围
tuned_parameters = range(10, 100, 10)
# 创建添加accuracy的一个numpy
accuracy_t = np.zeros(len(tuned_parameters))
# 创建添加error的一个numpy
error_t = np.zeros(len(tuned_parameters))
# 调优过程实现
for j, one_parameter in enumerate(tuned_parameters):
rf2 = RandomForestClassifier(n_estimators=175,
max_depth=one_parameter,
max_features=15,
min_samples_leaf=10,
oob_score=True,
random_state=0,
n_jobs=-1)
rf2.fit(x_train, y_train)
# 输出accuracy
accuracy_t[j] = rf2.oob_score_
# 输出log_loss
y_pre = rf2.predict_proba(x_test)
error_t[j] = log_loss(y_test, y_pre, eps=1e-15, normalize=True)
print(error_t)
# 优化结果过程可视化
fig,axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 4), dpi=100)
axes[0].plot(tuned_parameters, error_t)
axes[1].plot(tuned_parameters, accuracy_t)
axes[0].set_xlabel("max_depth")
axes[0].set_ylabel("error_t")
axes[1].set_xlabel("max_depth")
axes[1].set_ylabel("accuracy_t")
axes[0].grid(True)
axes[1].grid(True)
plt.show()
# 确定min_sample_leaf的取值范围
tuned_parameters = range(1, 10, 2)
# 创建添加accuracy的一个numpy
accuracy_t = np.zeros(len(tuned_parameters))
# 创建添加error的一个numpy
error_t = np.zeros(len(tuned_parameters))
# 调优过程实现
for j, one_parameter in enumerate(tuned_parameters):
rf2 = RandomForestClassifier(n_estimators=175,
max_depth=30,
max_features=15,
min_samples_leaf=one_parameter,
oob_score=True,
random_state=0,
n_jobs=-1)
rf2.fit(x_train, y_train)
# 输出accuracy
accuracy_t[j] = rf2.oob_score_
# 输出log_loss
y_pre = rf2.predict_proba(x_test)
error_t[j] = log_loss(y_test, y_pre, eps=1e-15, normalize=True)
print(error_t)
# 优化结果过程可视化
fig,axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 4), dpi=100)
axes[0].plot(tuned_parameters, error_t)
axes[1].plot(tuned_parameters, accuracy_t)
axes[0].set_xlabel("min_sample_leaf")
axes[0].set_ylabel("error_t")
axes[1].set_xlabel("min_sample_leaf")
axes[1].set_ylabel("accuracy_t")
axes[0].grid(True)
axes[1].grid(True)
plt.show()
确定最优模型
n_estimators=175
max_depth=30
max_features=15
min_samples_leaf=1
rf3 = RandomForestClassifier(n_estimators=175,
max_depth=30,
max_features=15,
min_samples_leaf=1,
oob_score=True,
random_state=40,
n_jobs=-1)
rf3.fit(x_train, y_train)
rf3.score(x_test, y_test)
# 0.7788655341203571
rf3.oob_score_
# 0.7693692396313364
y_pre_proba1 = rf3.predict_proba(x_test)
log_loss(y_test, y_pre_proba1)
# 0.7018021583384667
生成提交数据
test_data = pd.read_csv("./data/otto/test.csv")
test_data_drop_id = test_data.drop(["id"], axis=1)
y_pre_test = rf3.predict_proba(test_data_drop_id)
result_data = pd.DataFrame(y_pre_test, columns=["Class_"+str(i) for i in range(1, 10)])
result_data.insert(loc=0, column="id", value=test_data.id)
result_data.to_csv("./data/otto/submission.csv", index=False)
四、Boosting
1 什么是boosting
2 实现过程
3 bagging集成与boosting集成的区别
4 AdaBoost介绍
4.1 构造过程细节
4.2 关键点剖析
4.3 案例
问题解答:
4.4 api介绍
from sklearn.ensemble import AdaBoostClassifier
五、GBDT介绍
1 Decision Tree:CART回归树
1.1 回归树生成算法(复习)
2 Gradient Boosting: 拟合负梯度
当损失函数是平方损失和指数损失函数时,梯度提升树每一步优化是很简单的,但是对于一般损失函数而言,往往每一步优化起来不那么容易。
此时我们发现GBDT的负梯度就是残差,所以说对于回归问题,我们要拟合的就是残差。
3 GBDT算法原理
4 实例介绍
4.1 数据介绍
编号
年龄(岁)
体重(kg)
身高(m)(标签值)
0
5
20
1.1
1
7
30
1.3
2
21
70
1.7
3
30
60
1.8
4(要预测的)
25
65
?
4.2 模型训练
4.2.1 设置参数
4.2.2 开始训练
下一篇:机器学习:聚类算法