cvTrimWeights的源码在opencv的cvboost.cpp文件之中,具体内容和部分注释如下所
/* *cvTrimWeights *作用:对小于一定阈值的权重剔除,因为权重较小的样本对训练结果影响很小,剔除后,这样在训练样本时可以缩短训练时间 */ CV_BOOST_IMPL CvMat* cvTrimWeights( CvMat* weights,//训练样本的权重矩阵 CvMat* idx, //训练样本的索引序列矩阵 float factor ) //剔除小权重的样本后剩余样本的比例,根据这个参数来计算需要剔除较小样本的阈值 { CvMat* ptr = 0; CV_FUNCNAME( "cvTrimWeights" ); __BEGIN__; int i, index, num; float sum_weights; uchar* wdata; size_t wstep; int wnum; float threshold; int count; float* sorted_weights; CV_ASSERT( CV_MAT_TYPE( weights->type ) == CV_32FC1 ); ptr = idx; sorted_weights = NULL; if( factor > 0.0F && factor < 1.0F ) { size_t data_size; CV_MAT2VEC( *weights, wdata, wstep, wnum ); num = ( idx == NULL ) ? wnum : MAX( idx->rows, idx->cols ); data_size = num * sizeof( *sorted_weights ); sorted_weights = (float*) cvAlloc( data_size ); memset( sorted_weights, 0, data_size ); sum_weights = 0.0F; for( i = 0; i < num; i++ ) { index = icvGetIdxAt( idx, i );//将矩阵idx中第i个位置上的样本序列取出 sorted_weights[i] = *((float*) (wdata + index * wstep));//取出idx第i个位置上的权重 sum_weights += sorted_weights[i];//样本的权重和 } icvSort_32f( sorted_weights, num, 0 );//对样本排序 sum_weights *= (1.0F - factor); //根据训练样本总的权重和factor来计算需要剔除的小权重训练样本的权重和 i = -1; do { sum_weights -= sorted_weights[++i]; }//对排序后的样本从最小的小权重的样本开始减去,直到while中条件结束 while( sum_weights > 0.0F && i < (num - 1) ); threshold = sorted_weights[i]; /*跳出do-while循环后,把没有被剔除权重的样本中,最小权重的那个样本的权重赋给threshold。对外表现为:凡是样本的权重小于 这个阈值,就直接剔除*/ while( i > 0 && sorted_weights[i-1] == threshold ) i--;//剔除小权重的样本后,再对原来剔除的那部分中等于阈值的样本捡回来,挺人性化的哈 if( i > 0 || ( idx != NULL && CV_MAT_TYPE( idx->type ) != CV_32FC1 ) ) { CV_CALL( ptr = cvCreateMat( 1, num - i, CV_32FC1 ) ); count = 0; for( i = 0; i < num; i++ ) { index = icvGetIdxAt( idx, i ); if( *((float*) (wdata + index * wstep)) >= threshold )//只对阈值>threshold的权重操作 { CV_MAT_ELEM( *ptr, float, 0, count ) = (float) index; count++; } } assert( count == ptr->cols ); } cvFree( &sorted_weights ); } __END__; return ptr; //只返回权重大于阈值的样本 }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-09 22:11:39