前进之路 发表于 2025-1-11 16:33:29

人工智能知识分享第九天-机器学习_集成学习

集成学习

概念

集成学习是机器学习中的一种思想,它通过多个模型的组合形成一个精度更高的模型,参与组合的模型称为弱学习器(基学习器)。训练时,使用训练集依次训练出这些弱学习器,对未知的样本进行预测时,使用这些弱学习器联合进行预测。
https://i-blog.csdnimg.cn/direct/0a3ad0152e584259ab19fbccfec1be66.png
传统机器学习算法 (例如:决策树,逻辑回归等) 的目标都是探求一个最优分类器尽可能的将训练数据分开。集成学习 (Ensemble Learning) 算法的基本思想就是将多个分类器组合,从而实现一个预测结果更好的集成分类器。集成算法可以说从一方面验证了中国的一句老话:三个臭皮匠,赛过诸葛亮
https://i-blog.csdnimg.cn/direct/5b0fde1b16404f13908e1daec099d5dc.png
集成学习通过创建几个模型来解决单一预测问题。它的工作原理是 生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后联合成组合预测,因此优于任何一个单分类的做出预测
集成学习分类

集成学习算法一样平常分为:bagging和boosting。
https://i-blog.csdnimg.cn/direct/f460e11a43bf4b5e989ec3e938d8ecd1.png
bagging集成

Baggging 框架通过有放回的抽样产生差异的训练集,从而训练具有差异性的弱学习器,然后通过平权投票、多数表决的方式决定预测结果
boosting集成

Boosting 表现了提升思想,每一个训练器重点关注前一个训练器不足的地方进行训练,通过加权投票的方式,得出预测结果。
Boosting是一组可将弱学习器升为强学习器算法。这类算法的工作机制雷同:
1.先从初始训练集训练出一个基学习器
2.在根据基学习器的表现对训练样天职布进行调整,使得先前基学习器做错的训练样本在后续得到最大的关注。
3.然后基于调整后的样天职布来训练下一个基学习器;
4.云云重复进行,直至基学习器数量到达实现指定的值T为止。
5.再将这T个基学习器进行加权联合得到集成学习器。
简而言之:每新加入一个弱学习器,整体本领就会得到提升
Bagging 与 Boosting
区别一:数据方面


[*]Bagging:有放回采样
[*]Boosting:全部数据集, 重点关注前一个弱学习器不足
区别二:投票方面


[*]Bagging:平权投票
[*]Boosting:加权投票
区别三:学习次序


[*]Bagging的学习是并行的,每个学习器没有依靠关系
[*]Boosting学习是串行,学习有先后次序
随机丛林

算法思想

随机丛林是基于 Bagging 思想实现的一种集成学习算法,它接纳决策树模型作为每一个基学习器。其构造过程:

[*]训练:
[*]有放回的产生训练样本
[*]随机挑选 n 个特性(n 小于总特性数量)

[*]预测:平权投票,多数表决输出预测结果
随机丛林的步调
https://i-blog.csdnimg.cn/direct/bda43631129f4204900d78b0420dc61a.png
如上图:
首先,对样本数据进行有放回的抽样,得到多个样本集。具体来讲就是每次从原来的N个训练样本中有放回地随机抽取m个样本(包罗可能重复样本)。
然后,从候选的特性中随机抽取k个特性,作为当前节点下决策的备选特性,从这些特性中选择最好地分别训练样本的特性。用每个样本集作为训练样本构造决策树。单个决策树在产生样本集和确定特性后,使用CART算法计算,不剪枝。
最后,得到所需数量的决策树后,随机丛林方法对这些树的输出进行投票,以得票最多的类作为随机丛林的决策。
说明:
(1)随机丛林的方法即对训练样本进行了采样,又对特性进行了采样,充实包管了所构建的每个树之间的独立性,使得投票结果更准确。
(2)随机丛林的随机性表现在每棵树的训练样本是随机的,树中每个节点的分裂属性也是随机选择的。有了这2个随机因素,即使每棵决策树没有进行剪枝,随机丛林也不会产生过拟合的现象。
随机丛林中有两个可控制参数:


[*] 丛林中树的数量(一样平常选取值较大)
[*] 抽取的属性值m的巨细。
思索

[*]为什么要随机抽样训练集?
如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样。

[*]为什么要有放回地抽样?
如果不是有放回的抽样,那么每棵树的训练样本都是差异的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“片面的”,也就是说每棵树训练出来都是有很大的差异的;而随机丛林最后分类取决于多棵树(弱分类器)的投票表决。
随机丛林 API

sklearn.ensemble.RandomForestClassifier()
n_estimators:决策树数量,(default = 10)
Criterion:entropy、大概 gini, (default = gini)
max_depth:指定树的最大深度,(default = None 表示树会尽可能的生长)
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:是否接纳有放回抽样,如果为 False 将会使用全部训练样本,(default = True)
min_samples_split: 结点分裂所需最小样本数,(default = 2)


[*]如果节点样本数少于min_samples_split,则不会再进行分别.
[*]如果样本量不大,不必要设置这个值.
[*]如果样本量数量级非常大,则推荐增大这个值.
min_samples_leaf: 叶子节点的最小样本数,(default = 1)


[*]如果某叶子节点数量小于样本数,则会和兄弟节点一起被剪枝.
[*]较小的叶子结点样本数量使模型更容易捕捉训练数据中的噪声.
min_impurity_split: 节点分别最小不纯度


[*]如果某节点的不纯度(基尼系数,均方差)小于这个阈值,则该节点不再生成子节点,并变为叶子节点.
[*]一样平常不推荐改动默认值1e-7。
随机丛林泰坦尼克号生存预测

这泰坦尼克号案例实战:
#1.数据导入
#1.1导入数据
import pandas as pd
#1.2.利用pandas的read.csv模块从互联网中收集泰坦尼克号数据集
titanic=pd.read_csv("data/泰坦尼克号.csv")
titanic.info() #查看信息
#2人工选择特征pclass,age,sex
X=titanic[['Pclass','Age','Sex']]
y=titanic['Survived']
#3.特征工程
#数据的填补
X['Age'].fillna(X['Age'].mean(),inplace=True)
X = pd.get_dummies(X)
#数据的切分
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test =train_test_split(X,y,test_size=0.25,random_state=22)


#4.使用单一的决策树进行模型的训练及预测分析
from sklearn.tree import DecisionTreeClassifier
dtc=DecisionTreeClassifier()
dtc.fit(X_train,y_train)
dtc_y_pred=dtc.predict(X_test)
dtc.score(X_test,y_test)

#5.随机森林进行模型的训练和预测分析
from sklearn.ensemble import RandomForestClassifier
rfc=RandomForestClassifier(max_depth=6,random_state=9)
rfc.fit(X_train,y_train)
rfc_y_pred=rfc.predict(X_test)
rfc.score(X_test,y_test)

#6.性能评估
from sklearn.metrics import classification_report
print("dtc_report:",classification_report(dtc_y_pred,y_test))
print("rfc_report:",classification_report(rfc_y_pred,y_test))
超参数选择代码:
# 随机森林去进行预测
# 1 实例化随机森林
rf = RandomForestClassifier()
# 2 定义超参数的选择列表
param={"n_estimators":, "max_depth": ,"random_state":}
# 超参数调优
# 3 使用GridSearchCV进行网格搜索
from sklearn.model_selection import GridSearchCV
gc = GridSearchCV(rf, param_grid=param, cv=2)
gc.fit(X_train, y_train)
print("随机森林预测的准确率为:", gc.score(X_test, y_test))
Adaboost

adaboost算法简介

Adaptive Boosting(自适应提升)基于 Boosting思想实现的一种集成学习算法核心思想是通过逐步进步那些被前一步分类错误的样本的权重来训练一个强分类器。弱分类器的性能比随机猜测强就行,即可构造出一个非常准确的强分类器。其特点是:训练时,样本具有权重,而且在训练过程中动态调整。被分错的样本的样本会加大权重,算法更加关注难分的样本。
Adaboost自适应在于:“关注”被错分的样本,“器重”性能好的弱分类器:(观察下图)
(1)差异的训练集—>调整样本权重
(2)“关注”—>增长错分样本权重
(3)“器重”—>好的分类器权重大
(4) 样本权重间接影响分类器权重
重要过程演示如下:https://i-blog.csdnimg.cn/direct/a9d89518632740bf86cb20e52151181f.png
https://i-blog.csdnimg.cn/direct/dcb0e7aa796f41fbb31b42a7e8b71e32.png
https://i-blog.csdnimg.cn/direct/28f39bba72544bf68cc19ebff106d6e6.png
https://i-blog.csdnimg.cn/direct/f8a1cf1c8e804f21afb032d0979ebef1.png
https://i-blog.csdnimg.cn/direct/8d1bfbe2ec314bd0ab216791294cf9eb.png
https://i-blog.csdnimg.cn/direct/c75dffb358b3479bbfa0e9033496fb60.png
AdaBoost算法的两个核心步调:
权值调整: AdaBoost算法进步那些被前一轮基分类器错误分类样本的权值,而低落那些被正确分类样本的权值。从而使得那些没有得到正确分类的样本,由于权值的加大而受到后一轮基分类器的更大关注。
基分类器组合: AdaBoost接纳加权多数表决的方法。


[*] 分类偏差率较小的弱分类器的权值大,在表决中起较大作用。
[*] 分类偏差率较大的弱分类器的权值小,在表决中起较小作用。
AdaBoost算法推导

https://i-blog.csdnimg.cn/direct/20a86e9065f14084bd124f06a8e47345.png
AdaBoost实战葡萄酒数据

葡萄酒分为白葡萄酒和红葡萄酒两类。
该分析涉及白葡萄酒,并基于数据会合表现的13个变量/特性:
固定酸度,挥发性酸度,柠檬酸,残留糖,氯化物,游离二氧化硫,总二氧化硫,密度,pH值,硫酸盐,酒精,质量等。为了评估葡萄酒的质量,我们提出的方法就是根据酒的物理化学性子与质量的关系,找出高风致的葡萄酒具体与什么性子密切相干,这些性子又是如何影响葡萄酒的质量。
# 获取数据
import pandas as pd
df_wine = pd.read_csv('data/wine.data')
# 修改列名
df_wine.columns = ['Class label', 'Alcohol', 'Malic acid', 'Ash', 'Alcalinity of ash', 'Magnesium', 'Total phenols',
'Flavanoids', 'Nonflavanoid phenols', 'Proanthocyanins', 'Color intensity', 'Hue', 'OD280/OD315 of diluted wines',
'Proline']
# 去掉一类(1,2,3)
df_wine = df_wine != 1]
# 获取特征值和目标值
X = df_wine[['Alcohol', 'Hue']].values
y = df_wine['Class label'].values

from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
# 类别转化 (2,3)=>(0,1)
le = LabelEncoder()
y = le.fit_transform(y)
# 划分训练集和测试集
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.4,random_state=1)

from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import AdaBoostClassifier
# 机器学习(决策树和AdaBoost)
tree = DecisionTreeClassifier(criterion='entropy',max_depth=1,random_state=0)
ada= AdaBoostClassifier(base_estimator=tree,n_estimators=500,learning_rate=0.1,random_state=0)
from sklearn.metrics import accuracy_score
# 决策树和AdaBoost分类器性能评估
# 决策树性能评估
tree = tree.fit(X_train,y_train)
y_train_pred = tree.predict(X_train)
y_test_pred = tree.predict(X_test)
tree_train = accuracy_score(y_train,y_train_pred)
tree_test = accuracy_score(y_test,y_test_pred)
print('Decision tree train/test accuracies %.3f/%.3f' % (tree_train,tree_test))
# Decision tree train/test accuracies 0.845/0.854

# AdaBoost性能评估
ada = ada.fit(X_train,y_train)
y_train_pred = ada.predict(X_train)
y_test_pred = ada.predict(X_test)
ada_train = accuracy_score(y_train,y_train_pred)
ada_test = accuracy_score(y_test,y_test_pred)
print('Adaboost train/test accuracies %.3f/%.3f' % (ada_train,ada_test))
# Adaboost train/test accuracies 1/0.875
总结:AdaBosst预测准确了全部的训练集类标,与单层决策树相比,它在测试机上表现轻微好一些。单决策树对于训练数据过拟合的水平更加严峻一些。总之,我们可以发现Adaboost分类器能够些许进步分类器性能,而且与bagging分类器的准确率接近.
GBDT

提升树(Boosting Tree)

梯度提升树(Gradient Boosting Decision Tre)是提升树(Boosting Decision Tree)的一种改进算法,所以在讲梯度提升树之前先来先容一下提升树。
假如有个人30岁,我们首先用20岁去拟合,发现损失有10岁,这时我们用6岁去拟合剩下的损失,发现差距还有4岁,第三轮我们用3岁拟合剩下的差距,差距就只有一岁了。如果我们的迭代轮数还没有完,可以继续迭代下面,每一轮迭代,拟合的岁数偏差都会减小。最后将每次拟合的岁数加起来便是模型输出的结果。
梯度提升树

梯度提升树不再使用拟合残差,而是利用最速降落的近似方法,利用损失函数的负梯度作为提升树算法中的残差近似值。


[*]GBDT算法流程
1 初始化弱学习器(目标值的均值作为预测值)
2 迭代构建学习器,每一个学习器拟合上一个学习器的负梯度
3 直到到达指定的学习器个数
4 当输入未知样本时,将全部弱学习器的输出结果组合起来作为强学习器的输出
泰坦尼克号案例实战

该案例是在随机丛林的基础上修改的,可以对比理解
#1.数据导入
#1.1导入数据
importpandas as pd
#1.2.利用pandas的read.csv模块泰坦尼克号数据集
titanic=pd.read_csv("../data/泰坦尼克号数据集.csv")
titanic.info() #查看信息
#2人工选择特征pclass,age,sex
X=titanic[['Pclass','Age','Sex']]
y=titanic['Survived']
#3.特征工程
#数据的填补
X['Age'].fillna(X['Age'].mean(),inplace=True)
#数据的切分
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test =train_test_split(X,y,test_size=0.25,random_state=22)
#将数据转化为特征向量
from sklearn.feature_extraction import DictVectorizer
vec=DictVectorizer(sparse=False)
X_train=vec.fit_transform(X_train.to_dict(orient='records'))
X_test=vec.transform(X_test.to_dict(orient='records'))
#4.使用单一的决策树进行模型的训练及预测分析
from sklearn.tree import DecisionTreeClassifier
dtc=DecisionTreeClassifier()
dtc.fit(X_train,y_train)
dtc_y_pred=dtc.predict(X_test)
print("score",dtc.score(X_test,y_test))
#5.随机森林进行模型的训练和预测分析
from sklearn.ensemble import RandomForestClassifier
rfc=RandomForestClassifier(random_state=9)
rfc.fit(X_train,y_train)
rfc_y_pred=rfc.predict(X_test)
print("score:forest",rfc.score(X_test,y_test))
#6.GBDT进行模型的训练和预测分析
from sklearn.ensemble import GradientBoostingClassifier
gbc=GradientBoostingClassifier()
gbc.fit(X_train,y_train)
gbc_y_pred=gbc.predict(X_test)
print("score:GradientBoosting",gbc.score(X_test,y_test))
#7.性能评估
from sklearn.metrics import classification_report
print("dtc_report:",classification_report(dtc_y_pred,y_test))
print("rfc_report:",classification_report(rfc_y_pred,y_test))
print("gbc_report:",classification_report(gbc_y_pred,y_test))
XGBoost

XGBoost(Extreme Gradient Boosting)全名叫极端梯度提升树,XGBoost是集成学习方法的王牌,在Kaggle数据发掘比赛中,大部分得胜者用了XGBoost。
XGBoost在绝大多数的回归和分类问题上表现的十分顶尖
XGBoost 是对GBDT的改进:

[*]求解损失函数极值时使用泰勒二阶睁开
[*]在损失函数中加入了正则化项
[*]XGB 自创一个树节点分裂指标。这个分裂指标就是从损失函数推导出来的。XGB 分裂树时考虑到了树的复杂度。
构建最优模型的方法是最小化训练数据的损失函数 。
https://i-blog.csdnimg.cn/direct/9cd3650f5db5421babc7a2220ac90796.png
预测值和真实值颠末某个函数计算出损失,并求解全部样本的匀称损失,而且使得损失最小。这种方法训练得到的模型复杂度较高,很容易出现过拟合。因此,为了低落模型的复杂度,在损失函数中添加了正则化项,如下所示::https://i-blog.csdnimg.cn/direct/4e81e0bdd088428fbc2dab6be3139b71.png
进步模型对未知数据的泛化本领。
XGboost的目标函数

XGBoost(Extreme Gradient Boosting)是对梯度提升树的改进,而且在损失函数中加入了正则化项。
https://i-blog.csdnimg.cn/direct/0ee4fbecf5494b34bedceb5a3a0155fe.png
目标函数的第一项表示整个强学习器的损失,第二部分表示强学习器中 K 个弱学习器的复杂度。
xgboost 每一个弱学习器的复杂度重要从两个方面来考量:https://i-blog.csdnimg.cn/direct/a2d2779f10fd4e1cbce989e1d6fe96d9.png

[*]γT 中的 T 表示一棵树的叶子结点数量,γ 是对该项的调节系数
[*]λ||w||2 中的 w 表示叶子结点输出值组成的向量,λ 是对该项的调节系数https://i-blog.csdnimg.cn/direct/96cc48682e084ef7b6ad642f43047ae1.png
XGboost APIhttps://i-blog.csdnimg.cn/direct/1a1bd9ecdf454acd8fe163004ba90d9d.png

bst = XGBClassifier(n_estimators, max_depth, learning_rate, objective)
https://i-blog.csdnimg.cn/direct/c78d4ba9409a4158a025bf026ed2feb7.png
红酒风致预测

数据集先容

数据集共包罗 11 个特性,共计 3269 条数据. 我们通过训练模型来预测红酒的风致, 风致共有 6 个各种别,分别使用数字: 1、2、3、4、5 来表示。https://i-blog.csdnimg.cn/direct/22e72bf2d40f4d208f06a4b281d57ea4.png
案例实现



[*]导入必要的库文件
import joblib
import numpy as np
import xgboost as xgb
import pandas as pd
import numpy as np
from collections import Counter
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.model_selection import StratifiedKFold


[*]数据基本处置惩罚
def test01():

    # 1. 加载训练数据
    data = pd.read_csv('data/红酒品质分类.csv')
    x = data.iloc[:, :-1]
    y = data.iloc[:, -1] - 3

    # 2. 数据集分割
    x_train, x_valid, y_train, y_valid = train_test_split(x, y, test_size=0.2, stratify=y, random_state=22)

    # 3. 存储数据
    pd.concat(, axis=1).to_csv('data/红酒品质分类-train.csv')
    pd.concat(, axis=1).to_csv('data/红酒品质分类-valid.csv')


[*]模型基本训练
def test02():

    # 1. 加载训练数据
    train_data = pd.read_csv('data/红酒品质分类-train.csv')
    valid_data = pd.read_csv('data/红酒品质分类-valid.csv')

    # 训练集
    x_train = train_data.iloc[:, :-1]
    y_train = train_data.iloc[:, -1]

    # 测试集
    x_valid = valid_data.iloc[:, :-1]
    y_valid = valid_data.iloc[:, -1]

    # 2. XGBoost模型训练
    estimator = xgb.XGBClassifier(n_estimators=100,
                                  objective='multi:softmax',
                                  eval_metric='merror',
                                  eta=0.1,
                                  use_label_encoder=False,
                                  random_state=22)
    estimator.fit(x_train, y_train)

    # 3. 模型评估
    y_pred = estimator.predict(x_valid)
    print(classification_report(y_true=y_valid, y_pred=y_pred))

    # 4. 模型保存
    joblib.dump(estimator, 'model/xgboost.pth')


[*]模型参数调优
# 样本不均衡问题处理
from sklearn.utils import class_weight
classes_weights = class_weight.compute_sample_weight(class_weight='balanced',y=y_train)
# 训练的时候,指定样本的权重
estimator.fit(x_train, y_train,sample_weight = classes_weights)
y_pred = estimator.predict(x_valid)
print(classification_report(y_true=y_valid, y_pred=y_pred))

# 交叉验证,网格搜索
train_data = pd.read_csv('data/红酒品质分类-train.csv')
valid_data = pd.read_csv('data/红酒品质分类-valid.csv')

# 训练集
x_train = train_data.iloc[:, :-1]
y_train = train_data.iloc[:, -1]

# 测试集
x_valid = valid_data.iloc[:, :-1]
y_valid = valid_data.iloc[:, -1]

spliter = StratifiedKFold(n_splits=5, shuffle=True)
# 2. 定义超参数
param_grid = {'max_depth': np.arange(3, 5, 1),
            'n_estimators': np.arange(50, 150, 50),
            'eta': np.arange(0.1, 1, 0.3)}
estimator = xgb.XGBClassifier(n_estimators=100,
                              objective='multi:softmax',
                              eval_metric='merror',
                              eta=0.1,
                              use_label_encoder=False,
                              random_state=22)
cv = GridSearchCV(estimator,param_grid,cv=spliter)
y_pred = cv.predict(x_valid)
print(classification_report(y_true=y_valid, y_pred=y_pred))
坚持分享 共同进步

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 人工智能知识分享第九天-机器学习_集成学习