相关文章:
- 李航《统计学习方法》第二章——用Python实现感知器模型(MNIST数据集)
- 李航《统计学习方法》第三章——用Python实现KNN算法(MNIST数据集)
- 李航《统计学习方法》第四章——用Python实现朴素贝叶斯分类器(MNIST数据集)
- 李航《统计学习方法》第五章——用Python实现决策树(MNIST数据集)
- 李航《统计学习方法》第六章——用Python实现逻辑斯谛回归(MNIST数据集)
- 李航《统计学习方法》第六章——用Python实现最大熵模型(MNIST数据集)
- 李航《统计学习方法》第七章——用Python实现支持向量机模型(伪造数据集)
- 李航《统计学习方法》第十章——用Python实现隐马尔科夫模型
第八章我打算就实现一个AdaBoost算法了。
AdaBoost看起来就是将一堆弱分类器的线性组合。
知乎上说AdaBoost分类器不适合上强分类器,且直接上强分类器也体现不出AdaBoost的效果,因此打算在MNIST数据集上使用例8.1的分类器,即阈值分类器。
AdaBoost算法
这里先贴上书上的算法
算法
细节处理
我们使用的弱分类器是例8.1的阈值分类器,但阈值分类器只能分类单一维度的特征,而通常情况下我们的特征都是多维的,这时就需要我们使用一些trick。
假设特征有n维,我们针对每一维特征求一个分类器,选取这些分类器中分类误差率最低的分类器作为本轮的分类器,将其特征坐标与分类器一起存入G(x)中。
当分类时,获取当前分类器Gm(x)及其特征坐标i,选取测试数据X的第i个特征X[i],放入分类器中分类,即Gm(X[i])。
如此一来,就能解决阈值分类器在多维特征下的情况了!
数据集
数据集和感知器那个博文用的是同样的数据集。
数据地址:https://github.com/WenDesi/lihang_book_algorithm/blob/master/data/train_binary.csv
特征
将整个图作为特征,但需要先经过二值化处理
代码
因为纯python的代码运行速度有些慢,所以我又写了一个版本,将计算阈值分类器那段写成了C++版本,编译成dll,加快运行速度。
纯python
代码已放到Github上,这边也贴出来
# encoding=utf-8
# @Author: wendesi
# @Date: 15-11-16
# @Email: wendesi@foxmail.com
# @Last modified by: wendesi
# @Last modified time: 17-11-16
import cv2
import time
import math
import logging
import numpy as np
import pandas as pd
from sklearn.cross_validation import train_test_split
from sklearn.metrics import accuracy_score
sign_time_count = 0
class Sign(object):
'''
阈值分类器
有两种方向,
1)x<v y=1
2) x>v y=1
v 是阈值轴
因为是针对已经二值化后的MNIST数据集,所以v的取值只有3个 {0,1,2}
'''
def __init__(self,features,labels,w):
self.X = features # 训练数据特征
self.Y = labels # 训练数据的标签
self.N = len(labels) # 训练数据大小
self.w = w # 训练数据权值分布
self.indexes = [0,1,2] # 阈值轴可选范围
def _train_less_than_(self):
'''
寻找(x<v y=1)情况下的最优v
'''
index = -1
error_score = 1000000
for i in self.indexes:
score = 0
for j in xrange(self.N):
val = -1
if self.X[j]<i:
val = 1
if val*self.Y[j]<0:
score += self.w[j]
if score < error_score:
index = i
error_score = score
return index,error_score
def _train_more_than_(self):
'''
寻找(x>v y=1)情况下的最优v
'''
index = -1
error_score = 1000000
for i in self.indexes:
score = 0
for j in xrange(self.N):
val = 1
if self.X[j]<i:
val = -1
if val*self.Y[j]<0:
score += self.w[j]
if score < error_score:
index = i
error_score &