AdaBoost 元算法
我们可以将前面介绍的不同的分类器组合起来,这种组合结果被称为集成方法或者元方法。
bagging:基于数据随机重抽样的分类器构建方法
通过对一个数据集多次抽样数据集个数的样本,可能会出现一个样本多次抽到,获得S个数据集,将某个算法分别作用于每个数据集就得到了S个分类器,然后对多个分类器的结果采用多数投票原则。
说人话就是并行独立构建多个弱分类器,然后投票表决。比如随机森林(Random Forest)
boosting
boosting是通过集中关注被已有分类器错分的那些数据来获得新的分类器。boosting分类的结果是基于所有分类器的加权求和结果,而bagging的分类器权重是相等的。
说人话就是串行构建多个弱分类器,比如Adaboost、GBDT(Gradient Boosting Decision Tree)、Xgboost
训练算法:基于错误提升分类器的性能
AdaBoost算法:训练集的每个样本会初始化一个相等的权重,构成向量D,首先训练一个弱分类器计算分类器的错误率,然后在同一数据集上再次训练弱分类器,第二次训练将会重新调整每个样本的权重,第一次训练分对的样本权重将会降低,分错的样本的权重将会提高。
为了从所有弱分类器中得到最终的分类结果,AdaBoost为每个分类器都基于错误率分配了一个权重值alpha。
ϵ
=
n
u
m
f
a
l
s
e
n
u
m
\epsilon = \frac{num_{false}}{num}
ϵ=numnumfalse
α
=
1
2
l
o
g
(
1
−
ϵ
ϵ
)
\alpha=\frac{1}{2}log(\frac{1-\epsilon}{\epsilon})
α=21log(ϵ1−ϵ)
num_false
是分错的样本数,num
是总样本数
正确率、召回率及ROC曲线
关于正确率、召回率及ROC曲线的理论知识这里不多介绍,咱们来看下代码,我发现机器学习实战这本书难点竟然都在画图上,作者画图的代码有时候看来太诡异?
代码主要分为两部分,索引列表的构造和画图,输入为预测的概率值数组和样本真正的类别标签,
1.通过argsort()函数输出概率分布的由小到大的index列表。
2.然后开始画图,这里采用的两点画图法,即确定一个点然后与上一个点左连接。首先确认初始点(1.0,1.0),为什么是该点,因为我们假设把预测概率值最小的点以及大于最小值的点都预测为类别1,这样的话我们的正确率明显是100%,因为我们把所有的值都预测为类别1了,而召回率也为100%,召回率指的是所有的负向样本中我们预测为正向样本的概率,所以也为100%。
3.然后我们开始for循环,第一个点,继续假设:该点以及大于该点概率都为类别1,小于该点概率的为类别2。然后我们检验该点的样本真实值,如果为1,我们该如何对正确率和召回率做变化呢?答案是正确率应该减掉一个ystep,而召回率不变。为什么变化的是正确率呢?这里我们需要反向来看,当我们加上这第一个点之后,正确率应该增加,而召回率是不变的,那么反向来看,正确率就应该减少,召回率依然是不变的。
至于AUC的计算就不难了,当纵向移动时,面积是不变的,横向移动时我们计算横向移动的y值,因为横向移动的xstep是固定的,最后只需要将加和的y值乘固定的xstep即可。后续我再把AdaBoost的代码贴上来。
import matplotlib.pyplot as plt
def plotroc(pred,label):
cur = (1.0,1.0)
ysum = 0.0
num = np.sum(label==1.0) #TP+FN
ystep = 1/float(num) #TP/(TP+FN)
xstep = 1/float(len(label)-num) #FP/(FP+TN)
sortindicies = np.squeeze(pred).argsort()
#print(sortindicies)
plt.figure()
#figure().clf()
plt.subplot(111)
for index in sortindicies.tolist():
#print(index)
if label[index] ==1.0:
delX = 0
delY = ystep
else:
delX = xstep
delY = 0
ysum +=cur[1]
plt.plot([cur[0],cur[0]-delX],[cur[1],cur[1]-delY],c='b')#draw line from (cur[0],cur[1]) to (cur[0]-delX,cur[1]-delY)
cur =(cur[0]-delX,cur[1]-delY)
plt.plot([0,1],[0,1],'b--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC')
结果图: