精华内容
下载资源
问答
  • CrossValidation

    2017-06-23 14:42:58
    1.1 概念 交叉验证(Cross-validation)主要用于模型训练或建模应用中,如分类预测、PCR、PLS回归建模等。在给定的样本空间中,拿出大部分样本作为训练集来训练模型,剩余的小部分样本使用刚建立的模型进行预测,并...

    1.1 概念

    交叉验证(Cross-validation)主要用于模型训练或建模应用中,如分类预测、PCR、PLS回归建模等。在给定的样本空间中,拿出大部分样本作为训练集来训练模型,剩余的小部分样本使用刚建立的模型进行预测,并求这小部分样本的预测误差或者预测精度,同时记录它们的加和平均值。这个过程迭代K次,即K折交叉。其中,把每个样本的预测误差平方加和,称为PRESS(predicted Error Sum of Squares)。

    1.2 目的

    用交叉验证的目的是为了得到可靠稳定的模型。在分类,建立PC 或PLS模型时,一个很重要的因素是取多少个主成分的问题。用cross validation校验每个主成分下的PRESS值,选择PRESS值小的主成分数。或PRESS值不再变小时的主成分数。

    常用的精度测试方法主要是交叉验证,例如10折交叉验证(10-fold cross validation),将数据集分成十份,轮流将其中9份做训练1份做验证,10次的结果的均值作为对算法精度的估计,一般还需要进行多次10折交叉验证求均值,例如:10次10折交叉验证,以求更精确一点。
    交叉验证有时也称为交叉比对,如:10折交叉比对

    展开全文
  • Sklearn包装器的实现,用于处理嵌套CrossValidation。 提供附加的通用类,以通过选择一种集成方法或提供您自己的一种方法,通过过滤管道中的方法来集成降维和特征选择。 在使用来自不同设备的数据进行放射学研究的...
  • 多重交叉验证代码,测试可用,代码完善简洁。
  • 这是一组使用 CRF ++ 执行交叉验证的脚本。 去做 摆脱疯狂耗时的严格拆分 计算并输出conlleval cross-validation的宏观/微观平均值 不拆分执行时的错误显示 使用 d 选项指定输入数据分隔符(制表符和空白) ...
  • > 主要是在模型训练阶段的知识,及其常见的交叉验证/CV在样本集选择和模型构建中的作用; ## 关于正负样本比例 在二分类中一般是1:3的正负样本比例状态; ## 训练集、测试集、验证集比例 三个概念容易混淆,得到...

    主要是在模型训练阶段的知识,及其常见的交叉验证/CV在样本集选择和模型构建中的作用;

    关于正负样本比例

    在二分类中一般是1:3的正负样本比例状态;

    训练集、测试集、验证集比例

    三个概念容易混淆,得到正负样本后合并数据集然后按照8:2的比例把20%数据放在一边(即是测试集),剩下80%数据进行建模(训练集+验证集),开始进行模型构建必然要进行训练集和验证集的拆分,可以用K折法均分成K份分别进行建模,每次建模都会产生(k-1)份的真实训练集和1份真实验证集,然后求平均得到该模型的平均准确率,固化后使用到测试集上;
    训练集:测试集:验证集常见的比例是:6:2:2或者5:2.5:2.5

    关于数据拆分中的交叉验证

    可以用做数据集划分,也可以用于模型建模时候参数指定;

    1. KFold:K折交叉验证会把样本数据随机的分成K份(一般是均分),每次随机的选择K-1份作为训练集,剩下的1份做测试集。当这一轮完成后,重新随机选择K-1份来训练数据。若干轮(小于K)之后,选择损失函数评估最优的模型和参数。优点是可以降低由一次随机划分带来的偶然性,提高其泛化能力。但K折还有个问题就是因为是随机划分,很有可能划分的过程中刚好把类别都划分开了,比如第一折训练集里全是0标签,第二折测试集里全是1标签,这样对模型训练就不太好,在其中的某个模型学习的时候就没有学习到测试集的分类特征。在KFold中就是这样的,
    展开全文
  • 评估方法与CrossValidation交叉验证

    千次阅读 2017-12-29 14:29:01
    crossvalidation是在数据量有限的情况下的非常好的一个evaluate performance的方法。而对原始数据划分出train data和testdata的方法有很多种,这也就造成了cross validation的方法有很多种。 kFold ...

    评估方法

    关键:怎么获得“测试集”(test set) ?

    测试集应该与训练集“互斥”

    常见方法:

    • 留出法 (hold-out)
    • 交叉验证法 (cross validation)
    • 自助法 (bootstrap)

    留出法

    这里写图片描述

    这里写图片描述

    注意:

    保持数据分布一致性 (例如: 分层采样)

    多次重复划分 (例如: 100次随机划分)

    测试集不能太大、不能太小 (例如:1/5~1/3)


    k-折交叉验证法

    这里写图片描述


    自助法

    这里写图片描述
    这里写图片描述


    sklearn.cross_validation模块

    cross validation大概的意思是:对于原始数据我们要将其一部分分为traindata,一部分分为test data。train data用于训练,test data用于测试准确率。在test data上测试的结果叫做validation error。将一个算法作用于一个原始数据,我们不可能只做出随机的划分一次train和testdata,然后得到一个validation error,就作为衡量这个算法好坏的标准。因为这样存在偶然性。我们必须多次的随机的划分train data和test data,分别在其上面算出各自的validation error。这样就有一组validationerror,根据这一组validationerror,就可以较好的准确的衡量算法的好坏。crossvalidation是在数据量有限的情况下的非常好的一个evaluate performance的方法。而对原始数据划分出train data和testdata的方法有很多种,这也就造成了cross validation的方法有很多种。

    kFold

    classsklearn.model_selection.KFold(n_splits=3,shuffle=False, random_state=None)
    
    参数:
    
    n_splits : 默认3,最小为2;K折验证的K值
    
    shuffle : 默认False;shuffle会对数据产生随机搅动(洗牌)
    
    random_state :默认None,随机种子
    
    方法:
    
    get_n_splits([X, y, groups])        Returnsthe number of splitting iterations in the cross-validator
    
    split(X[, y, groups])        Generateindices to split data into training and test set.
    
    
    >>> import numpy as np
    >>> from sklearn.model_selection import KFold
    
    >>> X = ["a", "b", "c", "d"]
    >>> kf = KFold(n_splits=2)
    >>> for train, test in kf.split(X):
    ...     print("%s %s" % (train, test))
    [2 3] [0 1]
    [0 1] [2 3]

    Repeated K-Fold

    重复KFold重复K次折叠n次。 当需要运行KFold n次时,可以使用它,在每次重复中产生不同的分割。

    >>> 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]

    Leave One Out

    >>> from sklearn.model_selection import LeaveOneOut
    
    >>> X = [1, 2, 3, 4]
    >>> loo = LeaveOneOut()
    >>> for train, test in loo.split(X):
    ...     print("%s %s" % (train, test))
    [1 2 3] [0]
    [0 2 3] [1]
    [0 1 3] [2]
    [0 1 2] [3]

    Leave P Out (LPO)

    与Leave-One-Label-Out类似,但这种策略每次取p种类标号的数据作为测试集,其余作为训练集。

    >>> from sklearn.model_selection import LeavePOut
    
    >>> X = np.ones(4)
    >>> lpo = LeavePOut(p=2)
    >>> 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]

    Stratified k-fold
    与k-fold类似,将数据集划分成k份,不同点在于,划分的k份中,每一份内各个类别数据的比例和原始数据集中各个类别的比例相同。

    >>> from sklearn.model_selection import StratifiedKFold
    
    >>> X = np.ones(10)
    >>> y = [0, 0, 0, 0, 1, 1, 1, 1, 1, 1]
    >>> skf = StratifiedKFold(n_splits=3)
    >>> for train, test in skf.split(X, y):
    ...     print("%s %s" % (train, test))
    [2 3 6 7 8 9] [0 1 4 5]
    [0 1 3 4 5 8 9] [2 6 7]
    [0 1 2 4 5 6 7] [3 8 9]

    train_test_split

    >>> import numpy as np
    >>> from sklearn.model_selection import train_test_split
    >>> from sklearn import datasets
    >>> from sklearn import svm
    
    >>> iris = datasets.load_iris()
    >>> iris.data.shape, iris.target.shape
    ((150, 4), (150,))
    
    >>> X_train, X_test, y_train, y_test = train_test_split(
    ...     iris.data, iris.target, test_size=0.4, random_state=0)
    
    >>> X_train.shape, y_train.shape
    ((90, 4), (90,))
    >>> X_test.shape, y_test.shape
    ((60, 4), (60,))
    
    >>> clf = svm.SVC(kernel='linear', C=1).fit(X_train, y_train)
    >>> clf.score(X_test, y_test)                           
    0.96...

    cross_val_score

    sklearn.cross_validation.cross_val_score(estimator, X, y=None, scoring=None, cv=None,n_jobs=1, verbose=0, fit_params=None, pre_dispatch='2*n_jobs')
    
    返回值就是对于每次不同的的划分raw data时,在test data上得到的分类的准确率。
    
    参数解释:
    estimator:是不同的分类器,可以是任何的分类器。比如支持向量机分类器:estimator = svm.SVC(kernel='linear', C=1)
    
    cv:代表不同的cross validation的方法。如果cv是一个int值,并且如果提供了rawtarget参数,那么就代表使用StratifiedKFold分类方式;如果cv是一个int值,并且没有提供rawtarget参数,那么就代表使用KFold分类方式;也可以给定它一个CV迭代策略生成器,指定不同的CV方法。
    
    scoring:默认Nnoe,准确率的算法,可以通过score_func参数指定;如果不指定的话,是用estimator默认自带的准确率算法
    >>> from sklearn.model_selection import cross_val_score
    >>> clf = svm.SVC(kernel='linear', C=1)
    >>> scores = cross_val_score(clf, iris.data, iris.target, cv=5)
    >>> scores                                              
    array([ 0.96...,  1.  ...,  0.96...,  0.96...,  1.        ])
    #置信区间
    >>> print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
    Accuracy: 0.98 (+/- 0.03)

    默认情况下,每个CV迭代计算的得分是估计器的得分方法。 可以通过使用评分参数来改变这一点:

    >>> from sklearn import metrics
    >>> scores = cross_val_score(
    ...     clf, iris.data, iris.target, cv=5, scoring='f1_macro')
    >>> scores                                              
    array([ 0.96...,  1.  ...,  0.96...,  0.96...,  1.        ])

    请参阅评分参数:详细定义模型评估规则。 在Iris数据集的情况下,样本在各个目标类别之间是平衡的,因此准确度和F1得分几乎相等。

    当cv参数是一个整数时,cross_val_score默认使用KFold或StratifiedKFold策略,如果估计器来自ClassifierMixin,则使用后者。

    也可以通过传递交叉验证迭代器来使用其他交叉验证策略,例如:

    >>> from sklearn.model_selection import ShuffleSplit
    >>> n_samples = iris.data.shape[0]
    >>> cv = ShuffleSplit(n_splits=3, test_size=0.3, random_state=0)
    >>> cross_val_score(clf, iris.data, iris.target, cv=cv)
    ...                                                     
    array([ 0.97...,  0.97...,  1.        ])

    详细资料

    展开全文
  • K-折交叉验证(k-fold crossValidation)

    万次阅读 2017-12-25 18:41:57
    k-重交叉验证(k-fold crossValidation): 定义:  在机器学习中,将数据集A分为训练集B(training set)和测试集C(test set),在样本量不充足的情况下,为了充分利用数据集对算法效果进行测试,...
    k-重交叉验证(k-fold crossValidation):

    定义: 

    在机器学习中,将数据集A分为训练集B(training set)和测试集C(test set),在样本量不充足的情况下,为了充分利用数据集对算法效果进行测试,将数据集A随机分为k个包,每次将其中一个包作为测试集,剩下k-1个包作为训练集进行训练。

    [M,N]=size(data);//数据集为一个M*N的矩阵,其中每一行代表一个样本
        indices=crossvalind('Kfold',data(1:M,N),10);//进行随机分包
        for k=1:10//交叉验证k=10,10个包轮流作为测试集
            test = (indices == k); //获得test集元素在数据集中对应的单元编号
            train = ~test;//train集元素的编号为非test元素的编号
            train_data=data(train,:);//从数据集中划分出train样本的数据
     train_target=target(:,train);//获得样本集的测试目标,在本例中是实际分类情况
            test_data=data(test,:);//test样本集
     test_target=target(:,test);
     [HammingLoss(1,k),RankingLoss(1,k),OneError(1,k),Coverage(1,k),Average_Precision(1,k),Outputs,Pre_Labels.MLKNN]=MLKNN_algorithm(train_data,train_target,test_data,test_target);//要验证的算法
     end
    //上述结果为输出算法MLKNN的几个验证指标及最后一轮验证的输出和结果矩阵,每个指标都是一个k元素的行向量
        
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    indices=crossvalind('Kfold',x,k);
    来实现随机分包的操作,其中x为一个N维列向量(N为数据集A的元素个数,与x具体内容无关,只需要能够表示数据集的规模),k为要分成的包的总个数,输出的结果indices是一个N维列向量,每个元素对应的值为该单元所属的包的编号(即该列向量中元素是1~k的整随机数),利用这个向量即可通过循环控制来对数据集进行划分。例:

    [M,N]=size(data);//数据集为一个M*N的矩阵,其中每一行代表一个样本
    indices=crossvalind('Kfold',data(1:M,N),10);//进行随机分包
    fork=1:10//交叉验证k=10,10个包轮流作为测试集
    test = (indices == k); //获得test集元素在数据集中对应的单元编号
    train = ~test;//train集元素的编号为非test元素的编号
    train_data=data(train,:);//从数据集中划分出train样本的数据
    train_target=target(:,train);//获得样本集的测试目标,在本例中是实际分类情况
    test_data=data(test,:);//test样本集
    test_target=target(:,test);


    今天用到crossvalind. 这个适用于Cross validation。中文应该叫做交叉验证。我主要想说说这个函数怎么用的。举个简单的例子;

    P_train=[1 2 3 4 5 6 7 8 ]'
    P_train =

            1
            2
            3
            4
            5
            6
            7
            8
    Indices=crossvalind('Kfold',8,4)
    Indices =
            2
            3
            4
            1
            4
            1
            3
            2
    看到Incides了吗,这个是问题的关键,他把所有的点分成4类。数字一样的是一类, Indices=crossvalind('Kfold',8,4)中‘8’代表元素的个数,‘4’代表分成几类,因为有四类,每类应该有8/4两个元素,看indices中,每个相同的数字有两个元素,这样就能完成分类了。
    正常都是需要循环4次,这里的‘4’和crossvalind中的参数‘4’是一样的。比如第一次循环令i=1;
    得到indicies中是‘1’的,把其中的相应的设置为‘1’,其余的为零。
    val_set_index=(Indices==1)
    这个是对于test的(validation)验证
    val_set_index =
            0
            0
            0
            1
            0
            1
            0
            0
      train_set_index=~val_set_index
    这个是train的(训练分类器)
    train_set_index =
            1
            1
            1
            0
            1
            0
            1
            1
    这两个结果加在一起是一个全为1的向量。
    若果我想提取其中的test,用下面语句:
    >>val_ma=P_train(val_set_index,:);%val_set_index=[0 0 0 1 0 1 0 0]'
    >> val_ma
    val_ma =

            4
            6
    看见没,得到相应的测试元素

    十折交叉验证

    (1)英文名叫做10-fold cross-validation,用来测试算法准确性,是常用的测试方法。

    (2)将数据集分成十份,轮流将其中9份作为训练数据,1份作为测试数据,进行试验。每次试验都会得出相应的正确率(或差错率)。

    (3)10次的结果的正确率(或差错率)的平均值作为对算法精度的估计,一般还需要进行多次10折交叉验证(例如10次10折交叉验证),再求其均值,作为对算法准确性的估计。

     

    例子:利用十折交叉验证计算错误分类率

    (Matlab内置了由Fisher在1936年发布的关于iris的数据集,鸠尾花的分类,详见UCI链接;载入该数据集,包括means和species,分别是四维的150个样本和对应的类别)

     

    load fisheriris
    indices = crossvalind('Kfold',species,10); 
    cp = classperf(species); 
    for i = 1:10
          test = (indices == i); train = ~test;     %分别取第1、2、...、10份为测试集,其余为训练集
          class = classify(meas(test,:),meas(train,:),species(train,:));
          classperf(cp,class,test);
    end
    cp.ErrorRate      %查询错误分类率

     

     相关函数解释:

    Indices = crossvalind('Kfold', N, K)

    1)参数'Kfold'表明为了K折十字交叉验证,把数据集N随机分成平均的(或近似评价的)K份,Indices中为每个样本所属部分的索引(从1到K)
    2)因为是随机分,因此重复调用会产生不同分法。
    3)在K折十字交叉验证中,K-1份被用做训练,剩下的1份用来测试,这个过程被重复K次。

     

    cp = classperf(truelabels)

    1)classperf是评估分类器性能(Evaluate performance of classifie)函数。

    2)truelabels中为每个样本对应的真实类别,创建并初始化一个空的分类器性能对象CP。

    3)classperf provides an interface to keep track of the performance during the validation of classifiers. classperf creates and, optionally, updates a classifier performance object, CP, which accumulates the results of the classifier.

     

    class = classify(sample,training,group)

    1)classify是判别分析(Discriminant Analysis)函数。

    2)若事先已经建立类别,则使用判别分析;若事先没有建立类别,则使用聚类分析。一般地,若已有给定的若干总体的(即若干类别)的观测资料,希望构造一个或多个判别函数,能由此函数对新的位置其所属总体的样品作出判断,从而决定其应属于哪个总体,这就是判别分析问题。

    3)判别分析是利用原有的分类信息,得到判别函数(判别函数关系式,一般是与分类相关的若干个指标的线性关系式),然后利用 该函数去判断未知样品属于哪一类。因此,这是一个学习与预测的过程。常用的判别分析法有距离判别法、费歇尔判别法、贝叶斯判别法等。

    4)matlab中语法:class = classify(sample,training,group) ,默认线性判别分析,将sample的每个样本进行判别,分到trainning指定的类中,返回该类表作为分类结果。还可以用参数type指定判别分析法。

     

    classperf(cp, classout, testidx)

    1)根据分类结果,更新分类器性能对象CP。

    2)在十折交叉验证法中,就是重复10次,可累积得到总的错误分类率。


    10折交叉验证的例子

    第1步,将数据等分到10个桶中。
     

    我们会将50名篮球运动员和50名非篮球运动员分到每个桶中。每个桶当中放入了100人的信息。

    第2步,下列步骤重复10次。

    (1)每一次迭代中留存其中一个桶。第一次迭代中留存桶1,第二次留存桶2,其余依此类推。

    (2)用其他9个桶的信息训练分类器(第一次迭代中利用从桶2到桶10的信息训练分类器)。

    (3)利用留存的数据来测试分类器并保存测试结果。在上例中,这些结果可能如下:

    35个篮球运动员被正确分类;

    29个非篮球运动员被正确分类。

    第3步,对上述结果汇总。

    通常情况下我们会将结果放到与下表类似的表格中:
     

     

    分成篮球运动员

    分成非篮球运动员

    实际为篮球运动员

    372

    128

    实际为非篮球运动员

    220

    280

    在所有500名篮球运动员中,有372人被正确分类。可能需要做的一件事是将右下角的数字也加上去,也就是说1000人当中有652(372+280)人被正确分类。因此得到的精确率为65.2%。与2折或3折交叉验证相比,基于10折交叉验证得到的结果可能更接近于分类器的真实性能。之所以这样,是因为每次采用90%而不是2折交叉验证中仅仅50%的数据来训练分类器。
     


    展开全文
  • 机器学习-CrossValidation交叉验证Python实现

    万次阅读 多人点赞 2015-07-28 19:34:40
    在scikit-learn中有CrossValidation的实现代码,地址: scikit-learn官网crossvalidation文档 使用方法: 首先加载数据集 >>> import numpy as np >>> from sklearn import cross_validation ...
  • 机器学习-CrossValidation交叉验证

    千次阅读 2017-07-31 10:01:54
    机器学习中“交叉验证法”(cross validation)以及Python代码
  • 完整影像组学分析流程 多重插值补缺-特征挑选-聚类-回归-ROC-Crossvalidation-DCA-收工
  • imROOT = 'D:\CaffeInfo\B_DataCreate\CancerNormal\CVgroups'; imSUB = ['A', 'B', 'C', 'D']; trainPath = 'D:\CaffeInfo\B_DataCreate\train_image'; valPath = 'D:\CaffeInfo\B_DataCreate\val_image';...
  • AIC, BIC v.s. Crossvalidation

    千次阅读 2017-01-25 22:29:51
    模型选择的方法有许多,例如 AIC, BIC, Crossvalidation, GCV等等。这 些准则的适用条件有哪些?该如何选择不同的准则? AIC, BIC准则 ref: https://methodology.psu.edu/node/504 ref: ...
  • import sklearn.model_selection import sklearn.datasets import sklearn.metrics import autosklearn.classification def main(): X, y = sklearn.datasets.load_breast_cancer(return_X_y=True) ...
  • //交叉验证 public class CrossValidation { /** * The number of rounds of cross validation.交叉验证的轮数。 */ public final int k; /** * The index of training instances.训练实例的索引。 */ public final...
  • CrossValidation【CV】 基本思想 将原始数据(dataset)分组: 一部分为训练集(train set) 一部分为验证集(validation set) 用训练集对分类器进行训练,再利用验证集来测试训练得到的模型(model),以此来做为评价分类器...
  • 交叉严重 crossvalidation

    2019-08-05 10:17:49
    交叉只是做验证,让不至于过拟合,次数一般自己来定 # -*- coding:utf-8 -*- from sklearn import datasets from sklearn.model_selection import train_...plt.ylabel('CrossValidation accuracy') plt.show()
  • crossvalidation是在数据量有限的情况下的非常好的一个 evaluate performance的方法。 而对原始数据划分出 train data和testdata的方法有很多种,这也就造成了cross validation的方法有很多种。   主要函数: ...
  • crossvalidation是在数据量有限的情况下的非常好的一个evaluate performance的方法。而对原始数据划分出train data和testdata的方法有很多种,这也就造成了cross validation的方法有很多种。 主要函数 sklearn...
  • 在scikit-learn中有CrossValidation的实现代码,地址:  scikit-learn官网crossvalidation文档 使用方法: 首先加载数据集 >>> import numpy as np >>> from sklearn import cross_...
  • CrossValidation.m

    2018-03-18 08:37:44
    TrainPath = [root_path, 'CrossValidation1\WithoutAugment\Data\train_image\'];%最终训练集图片保存路径 ValPath = [root_path, 'CrossValidation1\WithoutAugment\Data\val_image\'];%最终验证集图片保存路径 ...
  • crossvalidation是在数据量有限的情况下的非常好的一个 evaluate performance的方法。 而对原始数据划分出 train data和testdata的方法有很多种,这也就造成了cross validation的方法有很多种。 主要函数 ...
  • crossvalidation是在数据量有限的情况下的非常好的一个 evaluate performance的方法。 而对原始数据划分出 train data和testdata的方法有很多种,这也就造成了cross validation的方法有很多种。 主要函数...
  • 交叉验证(CrossValidation)方法思想简介

    万次阅读 2018-01-22 11:41:07
    交叉验证(CrossValidation)方法思想简介 以下简称交叉验证(Cross Validation)为CV.CV是用来验证分类器的性能一种统计分析方法,基本思想是把在某种意义下将原始数据(dataset)进行分组,一部分做为训练集(train ...
  • 1、CrossValidation 交叉验证 训练集,测试集,和验证集三者之间的关系:  首先要了解到我们的数据集一般分为训练集,测试集,和验证集,训练集主要是训练,验证集主要是为了验证模型的性能,从而选择不同的模型...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 829
精华内容 331
关键字:

crossvalidation