<>title: Adaboost
date: 2021-12-21 01:27:40
tags: 机器学习

<>关于Adaboost

Adaboost算法是针对二分类问题提出的集成学习算法,是boosting类算法最著名的代表。当一个学习器的学习的正确率仅比随机猜测的正确率略高,那么就称它是弱学习器,当一个学习期的学习的正确率很高,那么就称它是强学习器。而且发现弱学习器算法要容易得多,这样就需要将弱学习器提升为强学习器。Adaboost的做法是首先选择一个弱学习器,然后进行多轮的训练,但是每一轮训练过后,都要根据当前的错误率去调整训练样本的权重,让预测正确的样本权重降低,预测错误的样本权重增加,从而达到每次训练都是针对上一次预测结果较差的部分进行的,从而训练出一个较强的学习器。

<>实现

首先展示理论算法描述。

按照上述步骤开始用代码实现。

首先是初始化样本权重,初始他们的权重都是相等的,都是样本数分之一。代码如下所示。
n_train, n_test = len(X_train), len(X_test) W = np.ones(n_train) / n_train #
样本权重初始化
然后在规定的训练轮数下,在相应的样本权重下对弱分类器进行训练。
Weak_clf.fit(X_train, Y_train, sample_weight=W)
然后在测试集进行预测,并且计算出不正确的样本数。
# 预测不正确的样本数,计算精度 miss = [int(x) for x in (pred_train_i != Y_train)] #
在当前权重下计算错误率 miss_w = np.dot(W, miss)
下面就是根据预测的结果,对预测正确的样本权重进行削弱,对预测错误的样本权重进行加强,从而对样本对权重进行更新,用于下一次学习器的训练,公式代码如下所示。
# 计算alpha alpha = 0.5 * np.log(float(1 - miss_w) / float(miss_w + 0.01)) #
权重的系数 factor = [x if x == 1 else -1 for x in miss] # 更新样本权重 W = np.multiply(W,
np.exp([float(x) * alpha for x in factor])) W = W / sum(W) # normalization
最终输出的H(x)要对每个也测结果乘alhpa然后加入到结果的列表中。
# predict pred_train_i = [1 if x == 1 else -1 for x in pred_train_i]
pred_test_i= [1 if x == 1 else -1 for x in pred_test_i] pred_test = pred_test +
np.multiply(alpha, pred_test_i)
最后对于列表中大于0 的值认为它预测为标签值1,小于0的值认为它预测为比标签值0。
pred_test = (pred_test > 0) * 1 # pred = (pred > 0) * 1 return pred_test
从而完成了Adaboost的一次训练过程。

下面阐述一下我自己实现的十折交叉验证,这里使用的是sklearn的KFold,来对数据集进行十次划分,让每次划分的十个部分轮流做测试集,在同一弱学习器下训练十次,最终预测结果指标是这十次的求和取平均,代码如下所示。
weak_clf = DecisionTreeClassifier(criterion='entropy', max_depth=2) # 十折交叉验证
acc= [] pre = [] rec = [] f1 = [] Data = data.copy() kf = KFold(n_splits=10,
shuffle=True, random_state=0) # 10折 for train_index, test_index in tqdm(kf.split
(Data)): # 将数据划分为10折 train_data = Data[train_index] # 选取的训练集数据下标 test_data =
Data[test_index] # 选取的测试集数据下标 x_train = train_data[:, :8] y_train = train_data[:
, 8] x_test = test_data[:, :8] y_test = test_data[:, 8] scaler = StandardScaler(
) # 标准化转换 scaler.fit(x_train) # 训练标准化对象 x_train = scaler.transform(x_train)
scaler.fit(x_test) # 训练标准化对象 x_test = scaler.transform(x_test) pred_test =
my_adaboost(weak_clf, x_train, x_test, y_train, y_test, epoch) acc.append(
accuracy_score(y_test, pred_test)) pre.append(precision_score(y_test, pred_test)
) rec.append(recall_score(y_test, pred_test)) f1.append(f1_score(y_test,
pred_test)) # 计算测试集的精度,查准率,查全率,F1 print("My Adaboost outcome in test set with
{} epoch:".format(epoch)) print("ACC:", sum(acc) / 10) print("PRE: ", sum(pre) /
10) print("REC: ", sum(rec) / 10) print("F1: ", sum(f1) / 10)
整体的代码如下:
# 自己实现的adaboost def my_adaboost(Weak_clf, X_train, X_test, Y_train, Y_test,
Epoch): """ :param Weak_clf: :param X_train: :param X_test: :param Y_train:
:param Y_test: :param Epoch: :return: """ n_train, n_test = len(X_train), len(
X_test) W = np.ones(n_train) / n_train # 样本权重初始化 # W = np.ones(n) / n pred_train
, pred_test = [np.zeros(n_train), np.zeros(n_test)] # pred = [np.zeros(n)] for i
in range(Epoch): # 用特定权重训练分类器 Weak_clf.fit(X_train, Y_train, sample_weight=W)
pred_train_i= weak_clf.predict(X_train) pred_test_i = weak_clf.predict(X_test)
# pred_i = cross_val_predict(Weak_clf, X, Y, cv=10) # 预测不正确的样本数,计算精度 miss = [int
(x) for x in (pred_train_i != Y_train)] # 在当前权重下计算错误率 miss_w = np.dot(W, miss)
# 计算alpha alpha = 0.5 * np.log(float(1 - miss_w) / float(miss_w + 0.01)) # 权重的系数
factor= [x if x == 1 else -1 for x in miss] # 更新样本权重 W = np.multiply(W, np.exp(
[float(x) * alpha for x in factor])) W = W / sum(W) # normalization # predict
pred_train_i= [1 if x == 1 else -1 for x in pred_train_i] # pred_i = [1 if x ==
1 else -1 for x in pred_i] pred_test_i = [1 if x == 1 else -1 for x in
pred_test_i] pred_test = pred_test + np.multiply(alpha, pred_test_i) pred_train
= pred_train + np.multiply(alpha, pred_train_i) # pred = pred +
np.multiply(alpha, pred_i) pred_train = (pred_train > 0) * 1 pred_test = (
pred_test> 0) * 1 # pred = (pred > 0) * 1 return pred_test

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信