1. 算法思想
基于串行集成的策略,加权综合考虑各个基分类器预测的结果,获得最终的预测结果。通俗讲就是,“三个臭皮匠,顶一个诸葛亮”,为每个人的建议设置一个权值,各抒己见,最后综合计算合理的答案。
首先,初始化所有样本的权重都相同,基于基分类器预测此数据集在权重分布下的预测结果;然后,根据此基分类器的预测结果和真实标签计算此时的分类错误率,并依据分类错误率继续计算此基分类器在最后决策中所占的权重;最后,串行迭代训练多个基分类器,并综合考虑获得强分类器。
2. 推导过程
图片来源:《统计学习方法》李航
3. 代码实现
1. 使用的数据集是sklearn中的乳腺癌二分类数据集;
2. 基分类器使用的是逻辑回归;
3. 对比自编的AdaBoost与sklearn中的AdaBoostClassifer算法
# -*-coding:utf-8 -*-
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import AdaBoostClassifier
from sklearn.datasets import load_breast_cancer
class AdaBoost:
def __init__(self,m,clf=LogisticRegression()):
self.m = m
self.clf = clf
self.clf_arr = []
self.alpha_arr = []
# 指定训练数据集、基分类器、迭代次数
def fit(self,X,Y):
num = X.shape[0]
# 初始化样本权重
W = np.ones(num) / num
# 迭代
for i in range(self.m):
# 基分类器预测
self.clf.fit(X, Y, sample_weight=W)
self.clf_arr.extend([self.clf])
Y_pred = np.sign(self.clf.predict(X))
# 分类误差率
indic_arr = [1 if Y_pred[i] != Y[i] else 0 for i in range(num)]
err = np.dot(W, np.array(indic_arr))
print("classify error rate is ",err)
# 分类器系数
alpha = 1 / 2 * np.log((1 - err) / err)
self.alpha_arr.extend([alpha])
# 更新权重
temp = W * np.exp([-alpha * Y[i] * Y_pred[i] for i in range(num)])
W = temp / np.sum(temp)
return self
def predict(self, X):
Y_pred = np.zeros(X.shape[0])
for i in range(self.m):
temp = self.alpha_arr[i] * self.clf_arr[i].predict(X)
Y_pred += temp
return np.sign(Y_pred)
def score(self,X,Y):
Y_pred = self.predict(X)
count = 0.
for i in range(Y.shape[0]):
if Y_pred[i]==Y[i]:
count +=1
return count/np.float(Y.shape[0])
if __name__=="__main__":
# 读取乳腺癌二分类数据集
X,Y = load_breast_cancer(return_X_y=True)
Y = np.array([1 if y==0 else -1 for y in Y],dtype=np.float64)
# 自编Adaboost
adaboost = AdaBoost(5)
adaboost.fit(X,Y)
print("accuracy is ",adaboost.score(X,Y))
# sklearn AdaBoostClassifier
# ada = AdaBoostClassifier(base_estimator=LogisticRegression(),n_estimators=22)
# ada.fit(X,Y)
# print(ada.score(X,Y))