集成学习
**集成学习(Ensemble learning)**是机器学习中近年来的一大热门领域。其中的集成方法是用多种学习方法的组合来获取比原方法更优的结果。
使用于组合的算法是弱学习算法,即分类正确率仅比随机猜测略高的学习算法,但是组合之后的效果仍可能高于强学习算法,即集成之后的算法准确率和效率都很高。
三个臭皮匠,赛过诸葛亮!!!以弱搏强,就是集成学习!
主要方法包括:
- Bagging
- Boosting
- Stacking
Stacking方法(知识蒸馏)
==Stacking方法(知识蒸馏)==是指训练一个模型用于组合其他各个模型。
- 先训练多个不同的模型,然后把训练得到的各个模型的输出作为输入来训练一个模型,以得到一个最终的输出。
- 原理:将多个不同模型的预测结果作为新的特征,输入到一个或多个元模型(meta-learner)中进行训练。
装袋法(Bagging)
装袋法(Bagging)又称为Bootstrap Aggregating, 是通过组合多个训练集的分类结果来提升分类效果
原理:对原始数据集进行多次有放回的抽样(bootstrap sampling),生成多个不同的训练数据集。
装袋法由于多次采样,每个样本被选中的概率相同,因此噪声数据的影响下降,所以装袋法太容易受到过拟合的影响。
【[数据挖掘Python] 26 集成学习 1 bagging算法 BaggingClassifier 个人银行贷款数据】
Bagging算法就是用多个弱分类器(CART)对划分的不同数据集进行分类,对于弱分类器的结果进行投票或者加权得到最终的结果。
Bagging对鸢尾花数据集进行分类
鸢尾花数据集是4个类别。
- 导入数据集
- 对数据集进行划分:·
KFold
函数进行K折交叉验证 - 创建CART决策树:
cart = DecisionTreeClassifier(criterion='gini', max_depth=3)
cart_result = cart.fit(X, Y)# 训练决策树模型
- 利用CART模型作为基决策器生产Bagging模型:
可以设置基决策器的数量n_estimators
,但不是越多越好哦!
model = BaggingClassifier(estimator=cart, n_estimators=100, random_state=seed)
result = cross_val_score(model, X, Y, cv=kfold)
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn import datasets
# 1.获取数据
iris = datasets.load_iris()
X = iris.data
Y = iris.target
seed = 42
# 创建K折交叉验证,设置分割数为10,打乱数据,设置随机种子
kfold = KFold(n_splits=10, shuffle=True, random_state=seed)
# 2.构建模型
# 创建决cart模型基础模型,设置使用基尼系数作为分裂标准,树的最大深度为3
cart = DecisionTreeClassifier(criterion='gini', max_depth=3)
cart_result = cart.fit(X, Y)# 训练决策树模型
result = cross_val_score(cart_result, X, Y, cv=kfold)# 使用交叉验证计算决策树模型的分数
print("CART树结果:", result.mean())
#————————————————————————————————————————————————————————————————————————————————
# 创建bagging分类器,设置基础模型为cart,设置cart分类器数量为100,设置随机种子
model = BaggingClassifier(estimator=cart, n_estimators=100, random_state=seed)
result = cross_val_score(model, X, Y, cv=kfold)
print("装袋法提升后结果:", result.mean())
结果:
CART树结果: 0.9466666666666667
装袋法提升后结果: 0.9600000000000002
提升法:Boosting
原理
提升法(Boosting)与装袋法(Bagging)相比:每次的训练样本均为同一组,并且引入了权重的概念,给每个单独的训练样本都会分配个相同的初始权重。
-
从训练集用初始权重训练出一个弱学习器1,
-
根据弱学习的学习误差率表现来更新训练样本的权重:
使得之前弱学习器1学习误差率高的训练样本点的权重变高,使得这些误差率高的点在后面的羽学习器2中得到更多的重视。 -
然后基于调整权重后的训练集来训练弱学习器2.,
-
如此重复进行,直到弱学习器数达到事先指定的数目T,最终将这T个弱学习器通过集合策略进行整合,得到最终的强学习器。
Adaboost(Adaptive Boosting)是一种自适应增强算法,它集成多个弱决策器进行决策。Adaboost解决二分类问题,且二分类的标签为{-1,1}。
注:一定是{-1,1},不能是{0,1}
它的训练过程是通过不断添加新的弱决策器,使损失函数继续下降,直到添加决策器已无效,最终将所有决策器集成一个整体进行决策。
理论上Adaboost适用于多种决策器,但实际中基本都是以决策树作为决策器
个体学习器之间存在强依赖关系、必须串行生成的序列化方法。
- 【提高】那些在前一轮被弱分类器【分错】的样本的权值
- 【减小】那些在前一轮被弱分类器【分对】的样本的权值
- 【加法模型】将弱分类器进行【线性组合】
Adaboost
是Boosting算法中最典型的一个算法!!!
【【五分钟机器学习】Adaboost:前人栽树后人乘凉】
直接上代码:
Adaboost对乳腺癌数据集进行分类(良性、恶心)
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn import datasets
dataset_all = datasets.load_iris()#获取乳腺癌数据集
X = dataset_all.data
Y = dataset_all.target
seed = 42
kfold = KFold(n_splits=10, shuffle=True,random_state=seed)#10折交叉验证
cart = DecisionTreeClassifier(criterion='gini',max_depth=3)#构建决策树分类器,使用基尼系数(Gini)作为分裂的准则,并且设置树的最大深度为3
dtree = cart.fit(X, Y)#训练
result = cross_val_score(dtree, X, Y, cv=kfold)#交叉验证分数
print("决策树结果:",result.mean())
model = AdaBoostClassifier(estimator=cart, n_estimators=100,random_state=seed)#创建AdaBoost分类器,使用决策树作为基学习器,弱学习器数量为100
result = cross_val_score(model, X, Y, cv=kfold)#交叉验证分数
print("提升法改进结果:",result.mean())
决策树结果: 0.92969924812
提升法改进结果: 0.970112781955
随机森林(RandomForest)
原理
随机森林与装袋法采取相同的样本抽取方式。
- 装袋法中的决策树每次从所有属性中选取一个最优的属性(gini)作为其分支属性,
- 而随机森林算法每次从所有属性中随机抽取𝑡个属性,然后从这𝑡个属性中选取一个最优的属性作为其分支属性,
- 这样就使得整个模型的随机性更强,从而使模型的泛化能力更强。
- 随机森林算法使用的弱分类决策树通常为CART算法。
- 【【五分钟机器学习】随机森林(RandomForest):看我以弱搏强】
代码实现
随机森林对鸢尾花数据进行分类,输出每个特征数据的重要性。
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
import pandas as pd
# 加载数据集
iris = load_iris()
X = iris.data
y = iris.target
# 分割数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)#测试级比例是0.3,训练集比例是0.7.
# #训练集的特征X_train和训练集的标签y_train进行训练;测试集的特征X_test和测试集的标签y_test进行预测与评估
# 创建随机森林分类器实例
rf_classifier = RandomForestClassifier(n_estimators=100, random_state=42)#默认基分类器(弱分类器)是CART模型,CART模型数量是100个。
# 训练模型
rf_classifier.fit(X_train, y_train)#用划分的训练集数据(包括X_train, y_train)进行训练
# 预测测试集结果
y_pred = rf_classifier.predict(X_test)#用划分的测试集数据进行测试,但是预测predict只需要X_test(测试集的特征数据),预测结果为测试集的y_pred
# 计算准确率
accuracy = accuracy_score(y_test, y_pred)#计算测试集的预测值y_pred和测试集的标签y_test的准确率accuracy
print(f"模型准确率: {accuracy:.2f}")
# 输出特征重要性
feature_importances = rf_classifier.feature_importances_
print("特征重要性:")
for name, importance in zip(iris.feature_names, feature_importances):
print(f"{name}: {importance:.4f}")
模型准确率: 100.00%
特征重要性:
sepal length (cm): 0.1081
sepal width (cm): 0.0304
petal length (cm): 0.4400
petal width (cm): 0.4215
Xgboost
GBDT
- 梯度提升决策树算法是利用梯度下降的思想,使用损失函数的负梯度在当前模型的值,作为提升树中残差的近似值,以此来拟合回归决策树。
- GBDT中的树都是回归树,不是分类树。
- GBDT的核心就在于,每一棵树学的是之前所有树结论和的残差,这个残差就是一个加预测值后能得真实值的累加量。
GBDT
XGBoost
XGBoost
XGBoost可以用于:
- 分类
- 回归
- 异常检测
XGBoost安装:
pip install xgboost -i https://pypi.tuna.tsinghua.edu.cn/simple
XGBRegressor
import xgboost as xgb
import numpy as np
from sklearn.linear_model import LinearRegression
# 数据准备
X = [[1],
[2],
[3]]
y = [2, 4, 6]
# 构建XGBRegressor模型
model = xgb.XGBRegressor(n_estimators=1)
# 训练模型
model.fit(X, y)
# 预测
X_predict = [[4]] # 修正预测数据的格式
y_predict = model.predict(X_predict)
print(f"{X_predict}XGBoost预测y值为: {y_predict}")
#____________________________________________
model1 = LinearRegression()
#继续写线性回归预测X_predict
model1.fit(X,y)
y_predict = model1.predict(X_predict)
print(f"{X_predict}LinearRegression预测y值为: {y_predict}")
[[4]]XGBoost预测y值为: [4.3]
[[4]]LinearRegression预测y值为: [8.]
XGBoost预测误差很大!!!
因为XGBoost 是一个强大的非线性模型,更适合处理复杂的非线性关系。
而这个数据明显是简单的线性模型,更适合用LinearRegression!
XGBClassifier
用XGBoost对UCI蘑菇数据集进行分类:
UCI蘑菇数据集Kaggle下载
- 类别信息:可食用=e,有毒=p
- 帽形:钟形=b,圆锥形=c,凸面=x,平面=f,结节=k,凹陷=s
- 帽表面:纤维=f,凹槽=g,鳞片=y,光滑=s
- 帽子颜色:棕色=n,浅黄色=b,肉桂色=c,灰色=g,绿色=r,粉红色=p,紫色=u,红色=e,白色=w,黄色=y
瘀伤:瘀伤=t,否=f
气味:杏仁=a,八角=l,杂酚油=c,鱼腥味=y,恶臭=f,霉味=m,无=n,辛辣=p,辛辣=s
…
在写代码的时候需要将数据集进行编码转化为数字
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import LabelEncoder
import xgboost as xgb
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import AdaBoostClassifier
# 加载数据集
data = pd.read_csv('mushrooms.csv')#相对路径:mushrooms.csv
# 对分类数据进行编码:值由字母变成数字
label_encoder = LabelEncoder()
for column in data.columns:
data[column] = label_encoder.fit_transform(data[column])
print(data.head())
# 分割数据集
X = data.drop('class', axis=1)
y = data['class']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 初始化Xgboost模型
model = xgb.XGBClassifier()
# 训练模型
model.fit(X_train, y_train)
# 预测测试集
y_pred = model.predict(X_test)
print(y_pred)
# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f'模型准确率:{accuracy*100}%')
#_________________________________________________
# LogisticRegression、AdaBoostClassifier也可以实现二分类哦
# model1 = LogisticRegression()
# model2 = AdaBoostClassifier()
class cap-shape cap-surface … spore-print-color population habitat
0 1 5 2 … 2 3 5
1 0 5 2 … 3 2 1
2 0 0 2 … 3 2 3
3 1 5 3 … 2 3 5
4 0 5 2 … 3 0 1
[5 rows x 23 columns]
[0 1 1 … 1 1 1]
模型准确率:100.0%
Process finished with exit code 0