共计 5631 个字符,预计需要花费 15 分钟才能阅读完成。
原文链接:http://tecdat.cn/?p=24421
AdaBoost 是?
Boosting 指的是机器学习元算法系列,它将许多 “ 弱 “ 分类器的输入合并成一个弱小的 “ 汇合 ”,其中每个弱分类器独自的错误率可能只比随机猜想好一点。
AdaBoost 这个名字代表了自适应晋升,它指的是一种非凡的晋升算法,在这种算法中,咱们适宜一连串的 “ 树桩 ”(有一个节点和两个叶子的决策树),并依据它们预测的精确水平对它们的最终投票进行加权。在每个迭代之后,咱们对数据集进行从新加权,对那些被前一个弱学习者谬误分类的数据点给予更大的器重,这样,这些数据点在迭代 t + 1 期间就会失去 “ 特地关注 ”。
它与随机森林相比如何?
特点
随机森林
AdaBoost
深度
有限(一棵残缺的树)
树桩(带有 2 个叶子的单个节点)
树木成长
独立
顺次
投票
雷同
加权
AdaBoost 算法
A) 对立初始化样本权重为 .
B) 对于每次迭代 t:
- 找到
ht(x)
最小化的弱学习 器 . - 咱们依据其准确性为弱学习器设置权重:
- 减少谬误分类察看的权重:.
- 从新归一化权重,使得 .
C)将最终预测作为弱学习器预测的加权多数票:.
绘图
咱们将应用上面的函数来可视化咱们的数据点,并可抉择笼罩拟合 AdaBoost 模型的决策边界。
def plot(X: np.ndaay,
y: np.ndrry,
cf=None) -> None:
"""绘制 2D 的±个样本,可抉择决策边界"""
if not ax:
fig, ax = plt.sults(fgsze=(5, 5), di=100)
pad = 1
x\_min, x\_max = X\[:, 0\].min() - pad, X\[:, 0\].max() + pad
y\_min, y\_max = X\[:, 1\].min() - pad, X\[:, 1\].max() + pad
if saligs is not None:
sies = np.array(spl_wigts) * X.hae\[0\] * 100
else:
sze = np.oes(sape=X.shpe\[0\]) * 100
if cf:
xx, yy = np.ehrid(n.aange(x\_min, x\_max, plot_step),
p.aang(y\_min, y\_max, plot_step))
pdt(np.c_\[xx.ravel(), yy.ravel()\])
# 如果所有的预测都是正类,则相应地调整色彩图。if list(np.niue(Z)) == \[1\]:
colors = \['r'\]
else:
colors = \['b', 'r'\]
ax.st\_im(in+0.5, \_ax-0.5)
ax.st_lm(ymin+0.5, yax-0.5)
数据集
咱们将应用相似的办法生成一个数据集,但应用较少的数据点。这里的要害是咱们想要两个不可线性拆散的类,因为这是 AdaBoost 的现实用例。
def maketat(n: it = 100, rased: it = None):
"""生成一个用于评估 AdaBoost 分类器的数据集"""
nclas = int(n/2)
if ranmed:
np.ram.sed(rndoed)
X, y = me\_gainqnes(n=n, n\_fees=2, n_css=2)
plot(X, y)
应用 scikit-learn 进行基准测试
让咱们通过从 scikit-learn 导入 AdaBoostClassifier,并将其拟合到咱们的数据集上,来建设一个基准,看看咱们的模型的输入应该是什么样子的。
from skarn.esele import AdosClaser
bnh = Adostlier(netrs=10, atm='SAMME').fit(X, y)
plat(X, y, bech)
tnr = (prdict(X) != y).man()
分类器在 10 次迭代中齐全拟合训练数据集,咱们数据集中的数据点被正当拆散。
编写本人的 AdaBoost 分类器
上面是咱们的 AdaBoost 分类器的框架代码。拟合模型后,咱们将把所有的要害属性保留到类中 – 包含每次迭代的样本权重 – 这样咱们就能够在当前查看它们,以理解咱们的算法在每一步的作用。
下表显示了咱们将应用的变量名称和后面在算法形容中应用的数学符号之间的映射。
变量
数学
sampleweight
wi(t)
stump
ht(x)
stumpweight
αt
error
εt
predict(X)
Ht(x)
class AdBst:
"""AdaBoost 分类器"""
def \_\_init\_\_(self):
self.sump = None
self.stup_weght = None
self.erro = None
self.smle_weih = None
def \_ceck\_X_y(self, X, y):
"""验证对于输出数据格式的假如"""
assrt st(y) == {-1, 1}
reurn X, y
拟合模型
回忆一下咱们的算法来拟合模型:
- 找到
ht(x)
最小化的弱学习 器 . - 咱们依据其准确性为弱学习器设置权重:
- 减少谬误分类察看的权重:. 留神 当假如与标签统一时将评估为 +1,当它与标签不统一时将评估为 -1。
- 从新归一化权重,使得 .
上面的代码实质上是下面的一对一的实现,然而有几点须要留神:
- 因为这里的重点是了解 AdaBoost 的汇合元素,咱们将调用 DecinTeassfir(mxdpth=1, mlefnes=2)实现筛选每个 ht(x)的逻辑。
- 咱们在 for 循环之外设置初始对立样本权重,并在每次迭代 t 内设置 t+1 的权重,除非它是最初一次迭代。咱们在这里特意在拟合模型上保留一组样本权重,以便咱们当前能够在每次迭代时可视化样本权重。
def ft(slf, X: narry, y: ndray, ites: int):
"""应用训练数据拟合模型"""
X, y = slf.\_chck\_X_y(X, y)
n = X.shpe\[0\]
# 启动 Numpy 数组
self.smle_wegts = np.zos(shpe=(itrs, n))
self.tumps = np.zeos(she=iters, dtpe=obect)
# 平均地初始化权重
sef.sampewegts\[0\] = np.one(shpe=n) / n
for t in range(iters):
# 拟合弱学习器
fit(X, y, smpe\_eght=urrsmle\_igts)
# 从弱学习者的预测中计算出误差和树桩权重
predict(X)
err = cu_seghts\[(pred != y)\].sum()# / n
weiht = np.log((1 - err) / err) / 2
# 更新样本权重
newweis = (crrawe * np.exp(-sum_wiht * y * tupd)
)
# 如果不是最终迭代,则更新 t + 1 的样本权重
if t+1 < ies:
sef.smpe\_wit\[t+1\] = ne\_saml_wigt
# 保留迭代的后果
sef.sups\[t\] = tump
做出预测
咱们通过采取“加权少数投票”来做出最终预测,计算为每个树桩的预测及其相应树桩权重的线性组合的符号 (±)。
def pedc(self, X):
"""应用曾经拟合的模型进行预测"""
supds = np.aray(\[stp.pect(X) for sump in slf.stps\])
return np.sgn(np.dt(self.tum_whts, sumpreds))
体现
当初让咱们把所有货色放在一起,用与咱们的基准测试雷同的参数来拟合模型。
# 将咱们独自定义的函数指定为分类器的办法
AaBt.fit = fit
Adostreit = pedct
plot(X, y, clf)
err = (clf.prdc(X) != y).mean()
不错! 咱们获得了与 sklearn 基准完全相同的后果。我筛选了这个数据集来展现 AdaBoost 的劣势,但你能够本人运行这个笔记本,看看它是否与输入后果相匹配,无论起始条件如何。
可视化
因为咱们把所有的两头变量作为数组保留在咱们的拟合模型中,咱们能够应用上面的函数来可视化咱们的汇合学习器在每个迭代 t 的演变过程。
- 左栏显示了所抉择的 “ 树桩 “ 弱学习器,它与 ht(x)绝对应。
- 左边一栏显示了到目前为止的累积强学习器。Ht(x)。
- 数据点标记的大小反映了它们的绝对权重。在上一次迭代中被谬误分类的数据点将被更多地加权,因而在下一次迭代中显得更大。
def truost(clf, t: int):
"""AdaBoost 的拟合,直到(并包含)某个特定的迭代。"""
nwwghts = clf.suweighs\[:t\]
def plotost(X, y, clf, iters=10):
"""在每个迭代中绘制出弱学习者和累积强学习者。"""
# 更大的网格
fig, axs = subplos(fisze=(8,ters*3),
nrows=iers,
ncls=2,
shaex=True,
dpi=100)
# 绘制弱学习者
plotot(X, y, cf.\[i\],
saplweghs=clf.saple_wigts\[i\],
aoat=False, a=ax1)
#绘制强学习者
truost(clf, t=i + 1)
pltot(X, y, tun_cf,
weights=smplweih\[i\], ax=ax2)
plt.t_aot()
为什么有些迭代没有决策边界?
您可能会留神到,咱们的弱学习器在迭代 t=2,5,7,10 时将所有点归类为正。产生这种状况是因为给定以后样本权重,只需将所有数据点预测为正值即可实现最低误差。请留神,在下面这些迭代的每个图中,负样本被按比例更高权重的正样本突围。
没有方法画出一个线性决策边界来正确分类任何数量的负面数据点,而不对侧面样本的更高累积权重进行谬误分类。不过这并不能阻止咱们的算法收敛。所有的正数点都被谬误分类,因而样本权重减少。这种权重的更新使得下一次迭代的弱学习者可能发现一个有意义的决策边界。
为什么咱们对 alpha_t 应用那个特定的公式?
为什么咱们应用这个特定的值 αt
?咱们能够证实抉择 最小化在训练集上的指数损失 。
疏忽符号函数,咱们 H
在迭代时 的强学习器 t
是弱学习器的加权组合 h(x)
。在任何给定的迭代中 t
,咱们能够Ht(x)
递归地将其定义 为迭代时的值 t−1
加上以后迭代的加权弱学习器。
咱们利用于 H 的损失函数是所有 n 个数据点的均匀损失。能够代替 的递归定义 Ht(x)
,并应用恒等式宰割指数项 .
当初咱们取损失函数对于 的导数 αt
并将其设置为零以找到最小化损失函数的参数值。能够将总和分为两个:case where ht(xi)=yi
和 case where ht(xi)≠yi
。
最初,咱们意识到权重之和等同于咱们后面探讨的误差计算:∑Dt(i)=ϵt。进行置换,而后进行代数操作,咱们就能够拆散出 αt。
进一步浏览
- sklearn.ensemble.AdaBoostClassifier – 官网 scikit-learn 文档
最受欢迎的见解
1. 从决策树模型看员工为什么到职
2.R 语言基于树的办法:决策树,随机森林
3.python 中应用 scikit-learn 和 pandas 决策树
4.机器学习:在 SAS 中运行随机森林数据分析报告
5.R 语言用随机森林和文本开掘进步航空公司客户满意度
6. 机器学习助推快时尚精准销售工夫序列
7. 用机器学习辨认一直变动的股市情况——隐马尔可夫模型的利用
8.python 机器学习:举荐零碎实现(以矩阵合成来协同过滤)
9.python 中用 pytorch 机器学习分类预测银行客户散失