集成学习
集成学习
"""
概述
是机器学习的一种思想, 它通过多个模型的组合形成一个精度更高的模型, 参与组合的模型称为 弱学习器(基学习器)
"""
1. 学习分类
"""
学习分类
Bagging
随机森林
采用决策树模型作为每一个弱学习器
训练
1. 有放回的产生训练样本
2. 随机挑选n个特征
预测
平权投票, 多数表决输出预测结果
API
sklearn.ensemble.RandomForestClassifier
n_estimators 决策树数量 default = 10
Criterion: entropy 或者 gini default = gini
max_depth: 指定树的最大深度, default=None
max_features='auto' 决策树构建时使用的最大特征数量
auto
sqrt
log2
None
bootstrap: 是否采用有放回抽样, 如果为False将会使用全部训练样本 default = True
min_samples_split
节点分裂所需最小样本数 default = 2
如果节点样本数少于min_samples_split 则不在进行划分
如果样本量不大, 不需要设置这个值
如果样本量数量级非常大, 则推荐增大这个值
min_samples_leaf
叶子节点的最小样本数 default = 1
如果某叶子节点数目小于样本数, 则会和兄弟节点一起被剪枝
较小的叶子节点样本数量使模型更容易捉捕训练数据中的噪声
min_impurity_split
节点划分最小不纯度
如果某节点的不纯度小于这个阈值, 则该节点不再生成子节点,并变为叶子节点
一般不推荐改动 默认值 1e-7
思想
又称为装袋算法或自举汇聚法
有放回的抽样产生不同的训练集, 从而训练不同的学习器
通过平权投票, 多数表决的方式决定预测结果
分类问题中, 会使用多数投票统计结果
回归问题中, 会使用求平均值统计结果
弱学习器可以并行训练
算法模型
Linear Ridge Lasso Logistic Softmax ID3 C4.5 CART SVM KNN
Boosting
思想
每一个训练器重点关注前一个训练器不足的地方进行训练
通过加权投票的方式 得出预测结果
串行的训练方式
算法模型
Adaboost, GBDT, XGBoost, LightGBM
对比
数据采样
Bagging
对数据进行有放回的采样训练
Boosting
全部样本, 根据前一轮学习结果调整数据的重要性
投票方式
Bagging
所有学习器平权投票
Boosting
对学习器进行加权投票
学习顺序
Bagging
并行的, 每个学习器没有依赖关系
Boosting
串行, 学习有先后顺序
"""
# 1.导入依赖包
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.metrics import classification_report
from sklearn.ensemble import RandomForestClassifier
import warnings
warnings.filterwarnings('ignore')
# 随机森林案例
def titanicCase():
# 2.读数据到内存并预处理
# 2.1 读取数据
taitan_df = pd.read_csv("data/train.csv")
print(taitan_df.head()) # 查看前5条数据
print(taitan_df.info) # 查看特性信息
# 2.2 数据处理,确定x y
x = taitan_df[['Pclass', 'Age', 'Sex']]
y = taitan_df['Survived']
# 2.3 缺失值处理
x['Age'] = x['Age'].fillna(x['Age'].mean())
print('x -->1', x.head(10))
# 2.4 pclass类别型数据,需要转数值one-hot编码
x = pd.get_dummies(x)
print('x -->2', x.head(10))
# 2.5 数据集划分
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.20, random_state=33)
# 3.训练模型,实例化决策树模型
estimator = DecisionTreeClassifier()
estimator.fit(x_train, y_train)
print(estimator.score(x_test, y_test))
# 基于随机森林
forest_classifier = RandomForestClassifier()
forest_classifier.fit(x_train, y_train)
print(forest_classifier.score(x_test, y_test))
# 基于交叉网格
param_grid = {
'n_estimators': [20, 40, 60]
}
grid_search = GridSearchCV(forest_classifier, param_grid=param_grid, cv=5)
grid_search.fit(x_train, y_train)
print(grid_search.best_estimator_.score(x_test, y_test))
2. Adaboost算法
"""
Adaboost算法
核心思想
通过逐步提高那些被前一步分类错误的样本的权重来训练一个强分类器
算法推导
1. 初始化训练数据权重相等, 训练第一个学习器
2. 根据新权重的样本集, 训练第二个学习器
3. 迭代训练在前一个学习器的基础上, 根据新的样本权重训练当前学习器
4. m个弱学习器集成预测公式
-a为模型的权重,输出结果大于0 则归为正类,小于0 则归为负类
5. 模型权重计算公式
6. 样本权重计算公式:
构建过程
1. 初始化数据权重, 来训练第一个弱弱学习器, 找最小的错误率计算模型权重, 再更新模数据权重
2. 根据更新的数据集权重, 来训练第二个弱学习器, 再找最小的错误率计算模型权重, 再更新模数据权重
3. 依次重复第二步, 训练n个弱学习器, 组合起来进行预测, 结果大于0为正类, 结果小于0为 负类
"""
# 1.导入依赖包
import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import AdaBoostClassifier # 集成学习
from sklearn.metrics import accuracy_score
# adaboost案例
# 2.读取数据及数据预处理
# 2.1 读取数据
wine_data = pd.read_csv('data/wine0501.csv')
print(wine_data.columns)
# 2.2 数据预处理
wine_data = wine_data[wine_data['Class label'] != 1]
x_feature = wine_data[['Alcohol', 'Hue']].values
y_target = wine_data['Class label']
# 2.3 数据集划分
y_target = LabelEncoder().fit_transform(y_target)
x_train, x_test, y_train, y_test = train_test_split(x_feature, y_target, test_size=0.2, random_state=2)
# 3.模型训练
tree_classifier = DecisionTreeClassifier(criterion='entropy', max_depth=1, random_state=2)
boost_classifier = AdaBoostClassifier(estimator=tree_classifier, n_estimators=500, random_state=2, learning_rate=0.1)
tree_classifier.fit(x_train, y_train)
y_pred = tree_classifier.predict(x_test)
print(tree_classifier.score(x_test, y_test))
# 4.模型评估
boost_classifier.fit(x_train, y_train)
y_pred = boost_classifier.predict(x_test)
print(boost_classifier.score(x_test, y_test))
弱学习器 集成预测公式
模型权重计算公式
样本权重计算公式
3. GBDT 算法
"""
GBDT
提升树
通过拟合残差的思想来进行提升
残差 = 真实值 - 预测值
梯度提升树
梯度提升树不再拟合残差, 利用梯度下降的近似方法, 利用损失函数的负梯度作为提升树算法中的残差近似值
构建流程
1. 初始化弱学习器(目标值的均值作为预测值)
2. 迭代构建学习器, 每一个学习器拟合上一个学习器的扶梯度
3. 直到达到指定的学习器个数
4. 当输入未知样本时, 将所有弱学习器的输出结果组合起来作为强学习器的输出
"""
# 1.导入依赖包
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import classification_report
from sklearn.model_selection import GridSearchCV
def gbdtCase():
# 2.读取数据
taitan_df = pd.read_csv('./data/train.csv')
# taitan_df.info()
# print('taitan_df.describe()-->', taitan_df.describe())
# 3.数据基本处理准备
# 3.1 获取 x y
x = taitan_df[['Pclass', 'Age', 'Sex']].copy()
y = taitan_df['Survived'].copy()
# 3.2 缺失值处理
x['Age'].fillna(x['Age'].mean(), inplace=True)
# 3.3 pclass离散型数据需one-hot编码
x = pd.get_dummies(x)
# 3.4 数据集划分
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22, test_size=0.2)
# 4.GBDT 训练和评估
estimator = GradientBoostingClassifier()
estimator.fit(x_train, y_train)
mysorce = estimator.score(x_test, y_test)
print("gbdt mysorce-->1", mysorce)
# 5.GBDT 网格搜索交叉验证
estimator = GradientBoostingClassifier()
param = {"n_estimators": [100, 110, 120, 130], "max_depth": [2, 3, 4], "random_state": [9]}
estimator = GridSearchCV(estimator, param_grid=param, cv=3)
estimator.fit(x_train, y_train)
mysorce = estimator.score(x_test, y_test)
print("gbdt mysorce-->2", mysorce)
4. XGBBoost算法
"""
XGBoost
极端梯度提升树
集成学习方法的王牌,在数据挖掘中大部分使用XGBoost
构建思想
1. 构建模型的方法是最小化训练数据的损失函数
训练模型复杂度较高, 易过拟合
2. 在损失函数中加入正则化项
提高对未知的测试数据的泛化性能
公式
γT 中的T 表示一棵树的叶子结点数量
λ||w||²中的w 表示叶子结点输出值组成的向量,||w||向量的模;λ对该项的调节系数
目标函数
公式
该公式也叫做打分函数 (scoring function),从损失函数、树的复杂度两个角度来衡量一棵树的优劣
选择树划分点
公式
思想
1. 根据Gain值 对树中每个叶子节点尝试进行分裂
2. 计算分裂前 - 分裂后的分数:
1. 如果 Gain > 0 则分裂之后树的损失更小, 会考虑此次分裂
2. 如果 Gain <0 说明分裂后的分数比分裂前的分数大, 此时不建议分裂
3. 当出发以下条件时, 停止分裂
1. 达到最大深度
2. 叶子节点数量低于某个阈值
3. 所有的节点在分裂时不能降低损失
"""
# 1.导入依赖包
import joblib
import numpy as np
import pandas as pd
from xgboost import XGBClassifier
from collections import Counter
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import GridSearchCV
import warnings
warnings.filterwarnings("ignore")
def xgbCase():
# 2.读取数据及数据预处理
# 2.1 加载数据集
train_data = pd.read_csv('./data/红酒品质分类_train.csv')
test_data = pd.read_csv('./data/红酒品质分类_test.csv')
# 2.2 准备数据 训练集测试集
x_train = train_data.iloc[:, :-1]
y_train = train_data.iloc[:, -1]
x_test = test_data.iloc[:, :-1]
y_test = test_data.iloc[:, -1]
print(x_train.shape, y_train.shape, x_test.shape, y_test.shape)
# 2.3 交叉验证时,采用分层抽取
spliter = StratifiedKFold(n_splits=5, shuffle=True)
# 3.模型训练
# 3.1 定义超参数
param_grid = {'max_depth': np.arange(3, 5, 1),
'n_estimators': np.arange(50, 150, 50),
'eta': np.arange(0.1, 1, 0.3)}
# 3.2 实例化XGBoost
estimator = XGBClassifier(n_estimators=100,
objective='multi:softmax',
eval_metric='merror',
eta=0.1,
use_label_encoder=False,
random_state=22)
# 3.3 实例化cv工具
estimator = GridSearchCV(estimator=estimator, param_grid=param_grid, cv=spliter)
# 3.4 训练模型
estimator.fit(x_train, y_train)
# 4.模型预测及评估
y_pred = estimator.predict(x_test)
print(classification_report(y_true=y_test, y_pred=y_pred))
print('estimator.best_estimator_-->', estimator.best_estimator_)
print('estimator.best_params_-->', estimator.best_params_)
损失函数中加入正则项公式
目标函数公式
选择树划分点 公式