adaBoost算法代码

#ifndef _ADA_BOOST_
#define _ADA_BOOST_

#include<iostream>
#include<vector>
#include<math.h>
#include<unordered_map>
#include<algorithm>
using namespace std;

class adaBoost
{
public:
	adaBoost(unordered_map<double, int>trainData1, double alpha1, int iterNums1,int classifyNums1,vector<double> data1);
	void weekClassify(double alpha, int iterNums,vector<vector<double>> weight,int nums);
	void adaptWeight(int num);
	void adaptGmWeight(int num);
	double findMin(const vector<double>& data);
	void getResult();
private:
	vector<double> data;                                             //样本值
	unordered_map<double, int> trainData;            //快速提供类型的作用
	vector<vector<double>> weight;                         //训练数据权值 迭代一次更新一次
	int iterNums;                                                            //迭代次数
	int classifyNums;                                                     //分类器个数
	vector<double> error;                                            //记录错误率
	double alpha;                                                          //迭代步长
	vector<double> gmWeight;                                  //记录弱分类器权值
	vector<double> gm;                                              //记录弱分类器
	vector<int> gmSymbol;                                         //对应分类器符号
	vector<vector<int>> errorPos;                             //记录错误点位置
};
#endif // !_ADA_BOOST_
#include"AdaBoost.h"

adaBoost::adaBoost(unordered_map<double, int> trainData1, double alpha1, int iterNums1, int classifyNums1, vector<double> data1) /*:
	trainData(trainData1), alpha(alpha1), iterNums(iterNums1), classifyNums(classifyNums1), data(data1)*/ {
	trainData = trainData1;
	alpha = alpha1;
	iterNums = iterNums1;
	data = data1;
	classifyNums = classifyNums1;
	int nums = trainData.size();
	vector<double> vec;                                            //第一次迭代权值初始化
	for (int i = 0; i < nums; i++) {
		vec.push_back(1.0 / nums);
	}
	weight.push_back(vec);                                     //1/n
	for (int i = 0; i < classifyNums; i++) {
		weekClassify(alpha, iterNums, weight, i);  //弱分类器 迭代次数 步长 本次迭代的权值(classifyNums确定)
		adaptGmWeight(i);                                         //更新分类器权值
		adaptWeight(i);                                                //更新权重
	}
}

double adaBoost::findMin(const vector<double>& data) {
	double min = data[0];
	for (int i = 1; i < data.size(); i++) {
		if (data[i] <= min)
			min = data[i];
		else
			;
	}
	return min;
}

//void adaBoost::weekClassify(unordered_map<double, int>&trainData, double alpha, int iterNums, vector<vector<double>> weight, int nums) {
//	int nums = iterNums;                                                                  //迭代算出本次权重下的最小错误率 
//	double begin = findMin(data);
//	double  error1=-1;
//	double classify = 0;
//	vector<double> vec = weight[ nums-classifyNums];
//	for (int i = 0; i < iterNums; i++) {
//		double errNums = 0;                                                                       //先左-1 再左 1 判断
//		double errNums1 = 0;
//		double errNums2 = 0;
//		begin = alpha*i + begin;
//		for (int j = 0; j < data.size(); j++) { 
//			if (data[j] <= begin&&trainData[data[j]] == 1) {             //错误项乘权重 不是记录错误次数  
//				errNums=errNums*vec[j];
//			}
//			else if (data[j] > begin&&trainData[data[j]] == -1) {
//				errNums = errNums*vec[j];
//			}
//			else if (data[j] <= begin&&trainData[data[j]] == -1)
//				errNums1 = errNums1*vec[j];
//			else if (data[j] > begin&&trainData[data[j]] == 1)
//				errNums1 = errNums1*vec[j];
//		}
//
//		if (errNums1 > errNums)
//			errNums2 = errNums;
//		else
//			errNums2 = errNums1;
//
//		if (error1 == -1)
//			error1 = errNums2;
//		else {
//			if (errNums2 > error1)
//				;
//			else {
//				error1 = errNums2;
//				classify = begin;
//			}
//		}
//	}
//	gm.push_back(classify);
//	error.push_back(error1);
//}
void adaBoost::weekClassify(double alpha, int iterNums, vector<vector<double>> weight, int nums) {
	double begin = findMin(data);                                                                                                //大循环结束 记录一个分类器(数值 符号)
	double errorNums3 = -1;
	int symbol1 = 0;
	double gmValue = 0;
	vector<int> vec3;                                                                                                              //记录错误点位置
	for (int i = 0; i < iterNums; i++) {
		begin = begin + i*alpha;
		double errorNums = 0;
		double errorNums1 = 0;
		double errorNums2 = 0;
		int symbol = 0;
		vector<int> vec1;                                                                                                            //记录错误点1
		vector<int> vec2;                                                                                                            //记录错误点2
		for (int j = 0; j < data.size(); j++) {                                                                                 //比较 对比 错误率 记录最优
			if (data[j] <= begin&&trainData[data[j]] == 1) {                                                     //小的默认-1 大的默认1 这表示分类错了 记录下来
				errorNums = errorNums + weight[nums][j];
				vec1.push_back(j);
			}
		   if (data[j] > begin&&trainData[data[j]] == -1) {
				errorNums = errorNums + weight[nums][j];
				vec1.push_back(j);
			}
		   if (data[j] <= begin&&trainData[data[j]] == -1) {
				errorNums1 = errorNums1 + weight[nums][j];
				vec2.push_back(j);
			}
		   if (data[j] > begin&&trainData[data[j]] == 1) {
				errorNums1 = errorNums1 + weight[nums][j];
				vec2.push_back(j);
			}
		}
		if (errorNums <= errorNums1) {                                                                                     //同一小循环若分类器 不知道 -1 +1 谁小保留谁 再与大循环比较 谁小 保留谁 得到最终弱分类器
			errorNums2 = errorNums;
			symbol = -1;
		}
		else {
			errorNums2 = errorNums1;
			symbol = 1;
		}
		if (errorNums3 == -1) {
			errorNums3 = errorNums2;
			symbol1 = symbol;
			gmValue = begin;
			if (symbol1 == -1)
				vec3 = vec1;
			else
				vec3 = vec2;
		}
		else {
			if (errorNums3 <= errorNums2)
				;
			else {
				errorNums3 = errorNums2;
				symbol1 = symbol;
				gmValue = begin;
				if (symbol1 == -1)
					vec3 = vec1;
				else
					vec3 = vec2;
			}
		}
	}
	gm.push_back(gmValue);                                                                   //最终记录数据 分类器值 方向 错误率
	gmSymbol.push_back(symbol1);
	error.push_back(errorNums3);
	errorPos.push_back(vec3);
}

void adaBoost::adaptGmWeight(int num) {
	double em = (1 - error[num]) / error[num];
	gmWeight.push_back((1.0 / 2)*log(exp(em)));
}

void adaBoost::adaptWeight(int num) {
	vector<double> nextWeight;
	for (int i = 0; i < data.size(); i++) {                          //大循环 求出每一个样本的更新权值
		int Yi = trainData[data[i]];
		int GmXi1=Yi;
		double Wnext;
		double Zm = 0;
		for (int j = 0; j < data.size(); j++) {                     //二循环求出 zm归一化值
			int yi = trainData[data[j]];
			double GmXi=yi;
			for (int p = 0; p < errorPos[num].size(); p++) {
				if (errorPos[num][p] == j)
					GmXi = -yi;
			}
			Zm = Zm + weight[num][j] * exp(-gmWeight[num] * yi*GmXi);
		}
		for (int k = 0; k < errorPos[num].size(); k++) {
			if (errorPos[num][k] == i)
				GmXi1 = -Yi;
		}
		Wnext = (weight[num][i] / Zm)*exp(-gmWeight[num] * Yi*GmXi1);
		nextWeight.push_back(Wnext);
	}
	weight.push_back(nextWeight);
}

void adaBoost::getResult() {
	for (auto c : gm)
		cout << "弱分类器值" << c<<" ";
	for (auto c : gmWeight)
		cout << "弱分类器权值" <<c<< " ";
	for (auto c : gmSymbol)
		cout << "弱分类器方向" << c<<" ";
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值