前面一共介绍了五种分类算法:KNN,决策树,朴素贝叶斯,逻辑斯蒂回归和SVM,它们各有优缺点。我们自然可以将不同的分类器组合起来,而这种组合结果被称为集成方法或者元算法。
今天主要练习的内容是一个被称为AdaBoost的最流行的元算法。
其优缺点如下图所示:
一、基于单层决策树构建弱分类器
在构造Adaboost的代码时,我们首先通过一个简单的数据集来确保在算法实现上一切就绪。
1.构造一个简单的数据集
def loadSimpData():
datMat = np.matrix([[ 1. , 2.1],
[ 2. , 1.1],
[ 1.3, 1. ],
[ 1. , 1. ],
[ 2. , 1. ]])
classLabels = [1.0, 1.0, -1.0, -1.0, 1.0]
return datMat,classLabels
2.单层决策树生成函数
首先先生成一个辅助函数,用于实现支持主体函数遍历所有特征值的所有分界点的所有可能性。
def stumpClassify(dataMatrix, dimen, threshVal, threshIneq): # 该函数用于遍历所有特征值的所有分界点的所有可能性
retArray = np.ones((np.shape(dataMatrix)[0], 1)) # 矩阵大小为:数据个数*1
if threshIneq == 'lt':
retArray[dataMatrix[:, dimen] <= threshVal] = -1.0 # 左负右正,左侧是w2
else:
retArray[dataMatrix[:, dimen] > threshVal] = -1.0 # 左正右负,右侧是w2
# 没错,因为只有一个分界点的时候,也是有两种可能的,左正右负或者左负右正
return retArray
接着基于以上函数,实现整个单层决策树的建立:
def buildStump(dataArr, classLabels, D): # 建立单层决策树
dataMatrix = np.array(dataArr) # m * n 阶矩阵
labelMat = np.array(classLabels) # m 阶一维矩阵矩阵
m, n = np.shape(dataMatrix) # m为样本数,n为每个样本的特征数
numSteps = 10.0 # 每个特征值取10个来看哪个最适合做分界点
bestStump = {
}
bestClasEst = np.array(np.zeros((m, 1)))
minError = math.inf # inf代表正无穷
for i in range(n): # 遍历所有特征
rangeMin = dataMatrix[:, i].min() # 第i个特征的最小值
rangeMax = dataMatrix[:, i].max() # 第i个特征的最大值
stepSize = (rangeMax - rangeMin) / numSteps # 步长
for j in range(-1, int(numSteps) + 1): # 遍历所有可能的特征值分界点
for inequal in ['lt', 'gt']:
threshVal = (rangeMin + float(j) * stepSize) # 所有可能的分界点
predictedVals = stumpClassify(dataMatrix, i, threshVal,
inequal) # 预测值
errArr = np.array(np.ones((m, 1)