您的位置:首页 > 编程语言 > Python开发

python adaboost的简单实现

2017-11-10 17:35 483 查看
初学adaboost,自己尝试着写了下adaboost的实现,这个实现以几个简单的数字作为训练样本,当然,这些数字是带标签的。然后尝试着使用adaboost对其分类。对于10个带标签的数字,分类他们只需要3个左右的弱分类器级联,组成一个强分类器就可以完全正确的分类。如果代码本身没有bug的话,adaboost的表现的确惊艳。

另外,pathon也是初学,很多的编程思路和c,c++类似,总之,各方面有待提高。但是因为代码能很好的分类样本,其结果还是令人兴奋的。

adaboost的教程非常多了,再次就不多做废话了。

一下是完整的代码。python是3.5.2版本的,如果版本没什么问题,粘贴复制应该就可以运行。

import cv2
import numpy as np
import math
import matplotlib.pyplot as plt

def buildDatasAndLables():
data =  [23,12,3,54,89,2,43,7,45,26]
label = [1, 1,-1,-1,-1,1,1,  -1, -1,1,]
return (data,label)

def calWeakClassfyOuput(input,weakClassy):
# 在期望范围的数为1,否则为-1
if weakClassy[0] == "left":
# left的时候,如果小于阈值,则输出1,否则,输出0
if input < weakClassy[1] :
return 1
elif input >= weakClassy[1]:
return -1
elif weakClassy[0] == "right":
# right的时候,如果大于阈值,则输出1,否则,输出0
if input > weakClassy[1] :
return 1
elif input <= weakClassy[1]:
return -1

#训练弱分类器
def trainWeakClassfy(data,label,W):
#训练若分类器的方式:找到一个阈值,把data分成两部分,使得错误率最小
weakClassy = []
#将每个data中的数据作为阈值,判断以该值作为阈值的误差率,这样需要判断len(data)次
for m in data:
for direct in ["left","right"]:
i = 0
error = 0
for mm in data:
#在期望范围的数为1,否则为-1
if direct == "left":
#left的时候,如果小于阈值,则对应的label应该为1,如果为-1,则错了,需要增加错误率
if mm < m and label[i]==-1:
error += W[i]
elif mm >= m and label[i]==1:
error += W[i]
elif direct == "right":
# right的时候,如果大于阈值,则对应的label应该为1,如果为-1,则错了,需要增加错误率
if mm > m and label[i]==-1:
error += W[i]
elif mm <= m and label[i]==1:
error += W[i]
i += 1
weakClassy.append([direct,m,error[0]])
#从所有的弱分类器中选择出错误率最低的
bestWeakClassfy = []
for classfy in weakClassy:
if not bestWeakClassfy:
bestWeakClassfy = classfy
else:
if classfy[2]<bestWeakClassfy[2]:
bestWeakClassfy = classfy
return bestWeakClassfy

def adaboostTrain(desAccuracy,maxWeakClassfyNum):
#首先获取训练数据
data,label = buildDatasAndLables()
#初始化权重为1/n
W = np.ones((len(data),1))/len(data)
weakClassfys = []
accuracy = 0
for num in range(maxWeakClassfyNum):
#首先训练弱分类器
weakClassfy = trainWeakClassfy(data, label, W)
#其次,计算该分类器的话语权
weight = 0.5*math.log(((1-weakClassfy[2])/weakClassfy[2]))
print("weight",weight)
print("weakClassfy",weakClassfy)
weakClassfy.append(weight)
weakClassfys.append(weakClassfy)

#然后更新训练样本的权重
midW = np.zeros(W.shape)
for i in range(len(W)):
midW[i] = W[i]*math.exp(-calWeakClassfyOuput(data[i],weakClassfy)*label[i]*weight)
Zt = np.sum(midW)
for i in range(len(W)):
W[i] = midW[i]/Zt
#左右检验输出是否达标
i = 0
accuracy = 0
for d in data:
result = 0
for classfy in weakClassfys:
result += classfy[3]*calWeakClassfyOuput(d,classfy)
if result > 0 :
result = 1
else:
result = -1
if result == label[i]:
accuracy += 1/len(data)
i += 1
print("accuracy",accuracy)
print("num",num)
if accuracy >= desAccuracy:
break

adaboostTrain(0.98,10)


结果如下:

weight 0.6931471805599453
weakClassfy ['left', 45, 0.20000000000000001]
accuracy 0.7999999999999999
num 0
weight 0.5493061443340549
weakClassfy ['left', 3, 0.25]
accuracy 0.7999999999999999
num 1
weight 0.8047189562170503
weakClassfy ['right', 7, 0.16666666666666666]
accuracy 0.9999999999999999
num 2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python adaboost 分类器