adaboost求助

本文讨论了作者在使用自定义Adaboost算法实现时遇到的问题,即错误率曲线在迭代次数1时达到最低,随着迭代增加反而上升。作者分析了训练过程中的样本权重更新和分类器性能,并展示了如何通过决策树作为基分类器进行实验。
摘要由CSDN通过智能技术生成

adaboost实现

不知道为什么自己写的adaboost代码运行的错误率随着迭代次数增加的曲线很奇怪,经常在迭代次数=1的时候错误率最低

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

class AdaBoostClassifier:
    def __init__(self, M, base_clf):  # 创建一个 AdaBoost 分类器的类
        self.M = M  # 记录迭代次数
        self.base_clf = base_clf  # 记录基分类器

    def fit(self, X_train, Y_train):  # 定义 fit 方法用于训练模型
        n_train = len(X_train)  # 获取训练样本的数量
        self.w = np.ones(n_train) / n_train  # 初始化样本权重,使其总和为1,用于加权训练
        self.classifiers = []  # 初始化分类器列表
        self.alphas = []  # 初始化分类器权重列表
        self.t = 1

        # 开始进行迭代训练
        while self.t <= self.M:
            clf = self.base_clf  # 创建基分类器的实例
            clf.fit(X_train, Y_train, sample_weight=self.w)  # 使用样本权重进行训练       #基础分类器需要支出样本权重
            pred_train_i = clf.predict(X_train)  # 对训练集进行预测
            miss = (pred_train_i != Y_train)  # 判断预测结果是否与真实标签不符
            err_m = np.dot(self.w, miss)


            #print(f"第{self.t}次迭代,当前弱分类器的带权训练误差率:{err_m}")     #打印每次迭代的训练误差率和迭代次数
            alpha_m = float(0.5 * np.log((1 - err_m) / max(err_m, 1e-16)))  # 计算当前分类器的权重

            #print(f"----------------{self.t}轮迭代的权重和:{sum(self.w)}")

            Z_m = sum((np.multiply(self.w, np.exp(-alpha_m * pred_train_i * Y_train ))))  # 规范化因子
            self.w = np.multiply(self.w, np.exp(-alpha_m * pred_train_i * Y_train))/ Z_m  # 更新样本权重

            self.classifiers.append(clf)  # 将当前分类器加入分类器列表
            self.alphas.append(alpha_m)  # 将当前分类器的权重加入权重列表


            pred_train = self.predict(X_train)  # 对训练集进行预测
            miss2 = (pred_train != Y_train)  # 预测错误则为True
            miss_sample_sum_num2 = np.sum(miss2)  # 分类错误样本总个数
            if miss_sample_sum_num2 == 0:
                print(f"第{self.t}次迭代,集合的强分类器误差率已经达到0,结束迭代。")
                break

            self.t += 1

    def predict(self, X):  # 定义预测方法
        n_samples = len(X)  # 获取样本数量
        pred = np.zeros(n_samples)  # 初始化预测结果数组
        # 对每个分类器和权重进行迭代
        for alpha, clf in zip(self.alphas, self.classifiers):
            pred += alpha * clf.predict(X)  # 加权累加预测结果
        return np.sign(pred)  # 对预测结果进行符号化处理,返回预测标签数组



#制造随机数据
from sklearn.datasets import make_classification
num_samples =  500  # 设置样本数量
num_features = 33  # 设置特征数量
# 生成二分类数据集
dataMat, labelMat= make_classification(
    n_samples=num_samples,
    n_features=num_features,
    n_informative=num_features-3,
    n_redundant=3,      #表示冗余特征的数量,这些特征与信息特征线性相关。
    n_clusters_per_class=1,     #表示每个类别内部的簇数
    flip_y=0.,     #表示标签翻转的概率,用于模拟部分噪声
    random_state=42
)
labelMat = np.where(labelMat == 0, -1, labelMat)        #把数组的0变成-1


# # 绘制数据集
# plt.scatter(dataMat[:, 0], dataMat[:, 1], c=labelMat, cmap='bwr')
# plt.xlabel('Feature 1')  # x轴标签
# plt.ylabel('Feature 2')  # y轴标签
# plt.title('Randomly Generated Dataset')  # 图表标题
# plt.show()

#拆分测试集
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(dataMat, labelMat, test_size=0.3,
                                                           random_state=42)  # 拆分数据20%作为测试的

flip_ratios = 0.0      #噪声比例
flip_count = int(flip_ratios * len(Y_train))
flip_indices = np.random.choice(len(Y_train), flip_count, replace=False)
Y_train_flip = np.copy(Y_train)
Y_train_flip[flip_indices] *= -1



#========================================================================================================================
from sklearn.tree import DecisionTreeClassifier
base_clf = DecisionTreeClassifier(max_depth=1)
#创建adaboost
adaboost = AdaBoostClassifier(M=20, base_clf= DecisionTreeClassifier(max_depth=1))
adaboost.fit(X_train,Y_train_flip)
print(f"弱分类器个数:{len(adaboost.classifiers)}")


# 评估分类器
from sklearn.metrics import accuracy_score
train_predictions = adaboost.predict(X_train)
test_predictions = adaboost.predict(X_test)
train_error_rate = 1 - accuracy_score(Y_train, train_predictions, normalize=True, sample_weight=None)
test_error_rate = 1 - accuracy_score(Y_test, test_predictions, normalize=True, sample_weight=None)
print(f"噪声比例:{flip_ratios*100}%")
#错误率
print("训练误差:", train_error_rate)
print("测试误差:", test_error_rate)



base_clf.fit(X_train,Y_train_flip)
train_pre = base_clf.predict(X_train)
miss = sum(train_pre != Y_train) / len(Y_train)
print(f"单个基础分类器的训练误差率  =  {miss}")
train_pre2 = base_clf.predict(X_test)
miss2 = sum(train_pre2 != Y_test) / len(Y_test)
print(f"单个基础分类器的测试误差率  =  {miss2}")
  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值