作者:i阿极
作者简介:数据分析领域优质创作者、多项比赛获奖者:博主个人首页
如果觉得文章不错或能帮助到你学习,可以点赞收藏评论+关注哦!
如果有小伙伴需要数据集和学习交流,文章下方有交流学习区!一起学习进步!
大家好,我i阿极。喜欢本专栏的小伙伴,请多多支持
专栏案例:机器学习案例 |
---|
机器学习(一):线性回归之最小二乘法 |
机器学习(二):线性回归之梯度下降法 |
机器学习(三):基于线性回归对波士顿房价预测 |
机器学习(四):基于KNN算法对鸢尾花类别进行分类预测 |
机器学习(五):基于KNN模型对高炉发电量进行回归预测分析 |
机器学习(六):基于高斯贝叶斯对面部皮肤进行预测分析 |
机器学习(七):基于多项式贝叶斯对蘑菇毒性分类预测分析 |
机器学习(八):基于PCA对人脸识别数据降维并建立KNN模型检验 |
机器学习(十四):基于逻辑回归对超市销售活动预测分析 |
机器学习(十五):基于神经网络对用户评论情感分析预测 |
机器学习(十六):线性回归分析女性身高与体重之间的关系 |
机器学习(十七):基于支持向量机(SVM)进行人脸识别预测 |
机器学习(十八):基于逻辑回归对优惠券使用情况预测分析 |
机器学习(十九):基于逻辑回归对某银行客户违约预测分析 |
机器学习(二十):LightGBM算法原理(附案例实战) |
机器学习(二十一):基于朴素贝叶斯对花瓣花萼的宽度和长度分类预测 |
机器学习(二十二):基于逻辑回归(Logistic Regression)对股票客户流失预测分析 |
AdaBoost是一种通过改变训练样本权重来学习多个弱分类器并线性组合成强分类器的Boosting算法。一般来说,Boosting方法要解答两个关键问题:
针对这两个问题,AdaBoost的做法非常朴素:
给定训练集
其中
AdaBoost训练算法如下:
(1) 初始化训练数据样本的权重分布,即为每个训练样本分配一个初始权重:
(2) 对于t = 1,2,3,…,T,分别执行以下步骤:
(a) 对包含权重分布 D t D_t Dt的训练集进行训练并得到弱分类器 G t ( x ) G_t(x) Gt(x)。
(b) 计算 G t ( x ) G_t(x) Gt(x)在当前加权训练集上的分类误差率:
ϵ t = P ( G t ( x i ) ≠ y i ) = ∑ i = 1 N w t i I ( G t ( x i ) ≠ y i ) \epsilon_t=P\left(G_t\left(x_i\right) \neq y_i\right)=\sum_{i=1}^N w_{t i} I\left(G_t\left(x_i\right) \neq y_i\right) ϵt=P(Gt(xi)=yi)=∑i=1NwtiI(Gt(xi)=yi)
(c )根据分类误差率计算当前弱分类器的权重系数 α t \alpha_t αt:
α t = 1 2 log 1 − ϵ t ϵ t \alpha_t=\frac{1}{2} \log \frac{1-\epsilon_t}{\epsilon_t} αt=21logϵt1−ϵt
其中 Z t Z_t Zt为归一化因子, Z t = ∑ i = 1 N w i exp ( − α t y i G t ( x i ) ) Z_t=\sum_{i=1}^N w_i \exp \left(-\alpha_t y_i G_t\left(x_i\right)\right) Zt=∑i=1Nwiexp(−αtyiGt(xi))
(3) 最后构建 T T T个弱分类器的线性组合:
最终的强分类器可以写为:
根据 α t = 1 2 log 1 − ϵ t ϵ t \alpha_t=\frac{1}{2} \log \frac{1-\epsilon_t}{\epsilon_t} αt=21logϵt1−ϵt的弱分类器权重系数计算过程中,当弱分类器的分类误差率 ϵ t ⩽ 1 2 \epsilon_t \leqslant \frac{1}{2} ϵt⩽21时, 0 ⩽ α t 0 \leqslant\alpha_t 0⩽αt,且 α t \alpha_t αt随着 ϵ t \epsilon_t ϵt的减小而变大,这也正是弱分类器权重系数计算公式的设计思想,它能够使得分类误差率较低的分类器有较大的权重系数。
根据
训练样本权重分布可以写为:
当样本被弱分类器正确分类时,它的权重变小;当样本被弱分类器错误分类时,它的权重变大。相比之外,错误分类样本的权重增大了 e 2 α t \mathrm{e}^{2 \alpha_t} e2αt倍,这就使得在下一轮训练中,算法将更加关注这些误分类的样本。
以上就是AdaBoost算法的基本原理。可以看到,算法步骤非常直观易懂,巧妙的算法设计能够非常好地回答Boosting方法的两个关键问题。上述关于AdaBoost的理解可以视为该模型的经典版本。
Python 3.9
Anaconda
Jupyter Notebook
AdaBoostClassifier分类器
AdaBoostClassifier(base_estimator=None, n_estimators=50,
learning_rate=1.0, algorithm='SAMME.R', random_state=None)
AdaBoostClassifier回归器
AdaBoostRegressor(base_estimator=None, n_estimators=50,
learning_rate=1.0, loss='linear', random_state=None)
# 导入第三方包
import pandas as pd
import matplotlib.pyplot as plt
# 读入数据
default = pd.read_excel(r'D:\CSDN\machine learning\default of credit card.xls')
plt.axes(aspect = 'equal')
# 中文乱码和坐标轴负号的处理
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
# 统计客户是否违约的频数
counts = default.y.value_counts()
# 绘制饼图
plt.pie(x = counts, # 绘图数据
labels=pd.Series(counts.index).map({0:'不违约',1:'违约'}), # 添加文字标签
autopct='%.1f%%' # 设置百分比的格式,这里保留一位小数
)
# 显示图形
plt.show()
# 导入第三方包
from sklearn import model_selection
from sklearn import ensemble
from sklearn import metrics
# 排除数据集中的ID变量和因变量,剩余的数据用作自变量X
X = default.drop(['ID','y'], axis = 1)
y = default.y
# 数据拆分
X_train,X_test,y_train,y_test = model_selection.train_test_split(X,y,test_size = 0.25, random_state = 1234)
使用train_test_split函数将数据集拆分为训练集和测试集。其中,参数X和y分别表示自变量和因变量,test_size表示测试集的比例(此处设置为0.25,即25%),random_state用于控制数据集的随机拆分,确保结果可重复。
# 构建AdaBoost算法的类
AdaBoost1 = ensemble.AdaBoostClassifier()
# 算法在训练数据集上的拟合
AdaBoost1.fit(X_train,y_train)
# 算法在测试数据集上的预测
pred1 = AdaBoost1.predict(X_test)
# 返回模型的预测效果
print('模型的准确率为:\n',metrics.accuracy_score(y_test, pred1))
print('模型的评估报告:\n',metrics.classification_report(y_test, pred1))
y_score = AdaBoost1.predict_proba(X_test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(y_test, y_score)
# 计算AUC的值
roc_auc = metrics.auc(fpr,tpr)
# 绘制面积图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
# 添加边际线
plt.plot(fpr, tpr, color='black', lw = 1)
# 添加对角线
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
# 添加文本信息
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
# 添加x轴与y轴标签
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
# 显示图形
plt.show()
importance = pd.Series(AdaBoost1.feature_importances_, index = X.columns)
importance.sort_values().plot(kind = 'barh')
plt.show()
predictors = list(importance[importance>0.02].index)
predictors
# 通过网格搜索法选择基础模型所对应的合理参数组合
# 导入第三方包
from sklearn.model_selection import GridSearchCV
from sklearn.tree import DecisionTreeClassifier
max_depth = [3,4,5,6]
params1 = {'base_estimator__max_depth':max_depth}
base_model = GridSearchCV(estimator = ensemble.AdaBoostClassifier(base_estimator = DecisionTreeClassifier()),
param_grid= params1, scoring = 'roc_auc', cv = 5, n_jobs = 4, verbose = 1)
base_model.fit(X_train[predictors],y_train)
# 返回参数的最佳组合和对应AUC值
base_model.best_params_, base_model.best_score_
# 导入第三方包
from sklearn.model_selection import GridSearchCV
n_estimators = [100,200,300]
learning_rate = [0.01,0.05,0.1,0.2]
params2 = {'n_estimators':n_estimators,'learning_rate':learning_rate}
adaboost = GridSearchCV(estimator = ensemble.AdaBoostClassifier(base_estimator = DecisionTreeClassifier(max_depth = 3)),
param_grid= params2, scoring = 'roc_auc', cv = 5, n_jobs = 4, verbose = 1)
adaboost.fit(X_train[predictors] ,y_train)
# 返回参数的最佳组合和对应AUC值
adaboost.best_params_, adaboost.best_score_
AdaBoost2 = ensemble.AdaBoostClassifier(base_estimator = DecisionTreeClassifier(max_depth = 3),
n_estimators = 300, learning_rate = 0.01)
# 算法在训练数据集上的拟合
AdaBoost2.fit(X_train[predictors],y_train)
# 算法在测试数据集上的预测
pred2 = AdaBoost2.predict(X_test[predictors])
# 返回模型的预测效果
print('模型的准确率为:\n',metrics.accuracy_score(y_test, pred2))
print('模型的评估报告:\n',metrics.classification_report(y_test, pred2))
y_score = AdaBoost2.predict_proba(X_test[predictors])[:,1]
fpr,tpr,threshold = metrics.roc_curve(y_test, y_score)
# 计算AUC的值
roc_auc = metrics.auc(fpr,tpr)
# 绘制面积图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
# 添加边际线
plt.plot(fpr, tpr, color='black', lw = 1)
# 添加对角线
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
# 添加文本信息
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
# 添加x轴与y轴标签
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
# 显示图形
plt.show()
文章下方有交流学习区!一起学习进步!
首发CSDN博客,创作不易,如果觉得文章不错,可以点赞收藏评论
你的支持和鼓励是我创作的动力❗❗❗