/************************************************************************ * * * Program package T O O L D I A G * * * * Version 1.5 * * Date: Tue Feb 8 13:39:03 1994 * * * * NOTE: This program package is copyrighted in the sense that it * * may be used for scientific purposes. The package as a whole, or * * parts thereof, cannot be included or used in any commercial * * application without written permission granted by the author. * * No programs contained in this package may be copied for commercial * * distribution. * * * * All comments concerning this program package may be sent to the * * e-mail address 'tr@fct.unl.pt'. * * * ************************************************************************/ #include #include #include "def.h" #include "featslct.h" extern universe *U; extern float estimate_error_KNN(); extern float selectMultivariate(); #define MIN_DISPLAY 20 static str80 buf; static FeatSelectVector FSV = NULL; static int order_crits( feat1, feat2 ) feature *feat1, *feat2; { if( feat1->crit < feat2->crit ) return((int)1); if( feat1->crit > feat2->crit ) return((int)-1); return((int)0); } static float selectUnivariateMINERR( i ) int i; { float err, crit; feature feat; feat.rank = i; feat.crit = 0.0; err = estimate_error_KNN( 1, &feat ); crit = 1.0 - err; return( crit ); } static void selectUnivariateMAHALANOBIS( i, c, a, b ) int i; float *c; int a, b; { float mean1, mean2, stddev1, stddev2, m, s, pd; mean1 = U->C[a].mean[i]; stddev1 = U->C[a].stddev[i]; mean2 = U->C[b].mean[i]; stddev2 = U->C[b].stddev[i]; if( mean1 == mean2 ) pd = 0.0; else { m = ( mean1 - mean2 ); s = (stddev1*stddev1 + stddev2*stddev2) / 2.0; pd = m * m / s; } *c = pd; } static void selectUnivariateCHEBYCHEV( i, c, a, b ) int i; float *c; int a, b; { float mean1, mean2, stddev1, stddev2, quot, pd; mean1 = U->C[a].mean[i]; stddev1 = U->C[a].stddev[i]; mean2 = U->C[b].mean[i]; stddev2 = U->C[b].stddev[i]; if( mean1 == mean2 ) { printf("For feature %d the two classes %d and %d", i, a, b ); printf(" have the same mean %f\n", mean1 ); printf("Setting the criterion to -INFINITY...\n"); pd = -INFINITY; } else { quot = (stddev1 + stddev2) / ( mean1 - mean2 ); pd = 1.0-quot*quot; } *c = pd; } static float selectUnivariateAverageClass( i, crit ) int i, crit; { int a, b; float Jab, merit = 0.0; for( a = 0; a < U->nrClass-1; a++ ) { for( b = a+1; b < U->nrClass; b++ ) { switch( crit ) { case MAHALANOBIS : selectUnivariateMAHALANOBIS( i, &Jab, a, b ); break; case CHEBYCHEV : selectUnivariateCHEBYCHEV( i, &Jab, a, b ); break; } merit += U->C[a].a_priori_prob * U->C[b].a_priori_prob * Jab; } } /* printf("Returning merit = %lf", merit ); DBG; /**/ return( merit ); } static float selectUnivariate( i, crit ) int i, crit; { float c; feature feat; feat.rank = i; feat.crit = (float)EMPTY; switch( crit ) { case MINERR : c = selectUnivariateMINERR( i ); break; case CHEBYCHEV : c = selectUnivariateAverageClass( i, crit ); break; case MAHALANOBIS : c = selectUnivariateAverageClass( i, crit ); break; /**/ case CHERNOFF : case BHATTACHARYYA : case BHATTACHARYYA_MATUSITA : case DIVERGENCE : case PATRICK_FISHER : case INTER_CLASS_DISTANCE: c = selectMultivariate( crit, &feat, 1 ); break; default: fprintf(stderr,"Unknown criterion- exit\n"); exit(1); } return( c ); } void selectFeaturesBF( crit ) int crit; { int i, nrBest, nrSelectFeat; float unicrit; FSV = (feature*) malloc( sizeof(feature) * U->nrFeat ); CHKPTR( FSV ); /* for each individual feature calculate the univariate criterion */ for( i = 0; i < U->nrFeat; i++ ) { printf("Analyzing feature nr. %4d of %4d\r", i+1, U->nrFeat);fflush(stdout); unicrit = selectUnivariate( i, crit ); FSV[i].rank = i; FSV[i].crit = unicrit; } printf("\n\n"); /* sort the features following the criterion */ printf("Sorting..."); fflush( stdout ); qsort( FSV, U->nrFeat, sizeof(feature), order_crits ); printf(" done.\n"); if( U->nrFeat > MIN_DISPLAY ) { printf("Want to see the best ? features (1-%d): ", U->nrFeat ); get_d_range( &nrBest, 1, U->nrFeat, LEFT_CLOSED__RIGHT_CLOSED ); show_selected_feats( stdout, FSV, nrBest ); } else show_selected_feats( stdout, FSV, U->nrFeat ); printf("Want to select the best ? features (1-%d): ", U->nrFeat ); get_d_range( &nrSelectFeat, 1, U->nrFeat, LEFT_CLOSED__RIGHT_CLOSED ); U->nrSelFeat = nrSelectFeat; FREE( U->FSV ); U->FSV = (feature*) malloc( U->nrSelFeat * sizeof(struct feature_) ); for( i = 0; i < U->nrSelFeat; i++ ) copy_feature( &(FSV[i]), &(U->FSV[i]) ); show_selected_feats( stdout, U->FSV, U->nrSelFeat ); FREE( FSV ); }