一、Cross Validation(交叉验证)
1. 解决的问题
用于验证分类器的性能的数据分析方法,可以抽样(抽取合适的训练集和测试集)、可以评估模型(计算模型的预测误差)。
2. 如何解决
基本原理:将原始数据分组,一部分做训练集,一部分做测试集。如k-fold cross validation均分成n组,抽取一组为测试集,剩下n-1组为训练集,依次抽遍,测试结果取预测误差平均值。
算法步骤:
Step1: 将学习样本空间 C分为大小相等的 K份
Step2: fori =1 to K:
取第i份作为测试集
forj =1 to K:
ifi !=j:
将第j份加到训练集中,作为训练集的一部分
endif
endfor
endfor
Step3: fori in (K-1训练集):
训练第i个训练集,得到一个分类模型
使用该模型在第N个数据集上测试,计算并保存模型评估指标
endfor
Step4: 计算模型的平均性能
Step5: 用这K个模型在最终验证集的分类准确率平均值作为此K-CV下分类器的性能指标.
实现抽样:(matlab/python里的scikit-learn库sklearn.cross_validation)
(1)K-fold(K组)
from sklearn.model_selection import KFold
X=["a","b","c","d"]
kf=KFold(n_splits=4)//分成四组,训练四次
for train,test in kf.split(X):
print("%s %s" % (train,test))
>>>
[1 2 3] [0]
[0 2 3] [1]
[0 1 3] [2]
[0 1 2] [3]
(2)Repeated K-Fold(随机分组n次,每次按K组分)
import numpy as np
from sklearn.model_selection import RepeatedKFold
X=np.array([[1,2],[3,4],[1,2],[3,4]])
random_state=12883823
rkf=RepeatedKFold(n_splits=2,n_repeats=2,random_state=random_state)//随机分成两组,随机分组两次
for train,test in rkf.split(X):
print("%s %s" % (train,test))
>>>
[2 3] [0 1]
[0 1] [2 3]
[0 2] [1 3]
[1 3] [0 2]
(3)LeaveOneOut/LeavePOut(随机拿出P个数据作为测试集)
from sklearn.model_selection import LeavePOut/LeaveOneOut
X=[1,2,3,4]
lpo=LeavePOut(p=2)/LeaveOneOut()
for train,test in lpo.split(X):
print("%s %s" % (train,test))
>>>
[2 3] [0 1]
[1 3] [0 2]
[1 2] [0 3]
[0 3] [1 2]
[0 2] [1 3]
[0 1] [2 3]
(4)ShuffleSplit(洗牌加随机抽样)
import numpy as np
from sklearn.model_selection import ShuffleSplit
X=np.arange(5)
ss=ShuffleSplit(n_splits=3,test_size=2/5,random_state=0)//随机抽三次,每次抽出测试数据占2/5)
for train_index,test_index in ss.split(X):
print("%s %s" % (train_index,test_index))
>>>
[1 3 4] [2 0]
[1 4 3] [0 2]
[4 0 2] [1 3]
PS:一个不均衡样本的实例:http://blog.csdn.net/dream_angel_z/article/details/47110077
3. 优缺点
优点:几乎能够训练到所有数据
缺点:如何确定K的最佳取值(也许碰运气吧)
二、自助法(Bootstrap)
1. 可以解决的问题
是一种统计方法,适用于小样本抽样,可以划分train/test,可以通过方差估计构造置信区间。(集成学习中的bagging有运用)。
2. 如何解决
基本原理:其实就是利用样本再生成自助样本,自助样本估计样本,样本再估计总体。在原始数据中有放回的随机抽样,样本容量仍为n,所得样本称为bootstrap样本。
算法步骤:
#这个伪代码自己写的,希望可以得到改正
fori =1 to K:
第i次采样
iflen(train) < m:
随机抽取一个数据添加到train
endfor
endfor
Python实现:(用bootstrap抽样)
import random
#抽样对象
class Sampling(object):
def__init__(self):
pass
defsampling(self):
pass
#bootstrap抽样
class BootStrap(Sampling):
def __init__(self,n_samples):
self.n_samples=n_samples
def sampling(self):
_slice=[]
whilelen(_slice)<self.n_samples:
p=random.randrange(0,self.n_samples)
_slice.append(p)
return _slice
if __name__ == '__main__':
bootstrap=BootStrap(10)//样本数十个,则bootstrap样本容量也为10
for i inrange(5)://bootstrap抽样次数为5,即抽出五组
_slice=bootstrap.sampling()
print(_slice)
>>>
[8, 0, 6, 2, 8, 7, 2, 6, 7, 1]
[7, 1, 4, 6, 6, 0, 5, 1, 3, 8]
[2, 1, 2, 6, 1, 0, 0, 1, 3, 8]
[1, 4, 4, 2, 5, 9, 4, 6, 0, 1]
[8, 7, 3, 5, 4, 9, 3, 9, 4, 3]
PS:数据前处理实例
https://github.com/Lehyu/pyml/tree/9bcb213b5bd5702f9b7df5d03f3fedcad32e08ae/preprocessing
3. 优缺点
优点:在数据集较小时适合使用;可以从原始数据中产生多个训练集。
缺点:改变了原始数据的分布,会引入估计偏差。
如何划分训练集/验证集/测试集?
http://blog.csdn.net/ch1209498273/article/details/79006255
http://blog.csdn.net/cherdw/article/details/54881167