1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #define CLUSTERS 9 #define BETA ( double )7.0 #define RHO ( double )0.55 typedef struct vector { char name[ MAX_NAME ]; int features[ MAX_FEATURES ]; int count; // Prototype cluster count int cluster; // Feature vector cluster int actual_class; } vector; // In-memory observations (feature vectors) vector feature_vectors[ MAX_FEAT_VECS ]; int max_feature_vectors; // Prototype feature vectors vector clusters[ CLUSTERS ]; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | void art_train( FILE *fptr ) { int changes = 1; int cluster; while ( changes ) { changes = 0; for (int feature = 0 ; feature < max_feature_vectors ; feature++) { cluster = cluster_observation( feature ); if ( cluster == CLUSTERS ) { cluster_create( feature ); changes++; } else { // If this feature vector has moved, move it. if ( feature_vectors[ feature ].cluster != cluster ) { cluster_add( cluster, feature ); changes++; } } } } emit_clusters( fptr ); return; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | int cluster_observation( int feature ) { vector result; double best_max = 0.0; int best_cluster = CLUSTERS; double featureMag = ( double )vMagnitude( &feature_vectors[ feature ] ); for ( int cluster = 0 ; cluster < CLUSTERS ; cluster++ ) { // If a cluster has no members, skip it. if ( clusters[ cluster ].count == 0 ) continue; vAnd( &result, &feature_vectors[ feature ], &clusters[ cluster ] ); double resultMag = ( double )vMagnitude( &result ); double clusterMag = ( double )vMagnitude( &clusters[ cluster ] ); double maximum = resultMag / ( BETA + clusterMag ); if ( maximum > best_max ) { best_max = maximum; best_cluster = cluster; } } if ( best_cluster != CLUSTERS ) { vAnd( &result, &feature_vectors[ feature ], &clusters[best_cluster] ); double resultMag = ( double )vMagnitude( &result ); double clusterMag = ( double )vMagnitude( &clusters[ best_cluster ] ); double maximum = resultMag / ( BETA + clusterMag ); double similarity = featureMag / ( BETA + ( double ) MAX_FEATURES ); // See if the feature vector is similar to the cluster if ( maximum > similarity ) { if ( ( resultMag / clusterMag ) >= RHO ) { return best_cluster; } } } return CLUSTERS; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | void cluster_create( int feature ) { int cluster = find_empty_cluster( ); if ( cluster != CLUSTERS ) { for ( int i = 0 ; i < MAX_FEATURES ; i++ ) { clusters[ cluster ].features[ i ] = feature_vectors[ feature ].features[ i ]; } clusters[ cluster ].count = 1; feature_vectors[ feature ].cluster = cluster; } return; } void cluster_add( int cluster, int vector ) { // If the current feature vector has been classified, pull it out. if ( feature_vectors[ vector ].cluster != CLUSTERS ) { int prior_cluster = feature_vectors[ vector ].cluster; feature_vectors[ vector ].cluster = CLUSTERS; clusters[ prior_cluster ].count--; recalculate_cluster( prior_cluster ); } // Add the feature vector to the new cluster. feature_vectors[ vector ].cluster = cluster; clusters[ cluster ].count++; recalculate_cluster( cluster ); return; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | void recalculate_cluster( int cluster ) { int first = 0; for ( int vec = 0 ; vec < max_feature_vectors ; vec++ ) { if ( feature_vectors[ vec ].cluster == cluster ) { if ( !first ) { first = 1; // Set the cluster to the first feature vector. for (int feature = 0 ; feature < MAX_FEATURES ; feature++ ) { clusters[ cluster ].features[ feature ] = feature_vectors[ vec ].features[ feature ]; } } else { // Boolean AND the next feature vectors into the cluster. for (int feature = 0 ; feature < MAX_FEATURES ; feature++ ) { clusters[ cluster ].features[ feature ] &= feature_vectors[ vec ].features[ feature ]; } } } } return; }代码比矢量量化的代码多一些,但 ART 可能比 VQ 更稳健。接下来,我将展示该算法的实际应用。 |
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) | Powered by Discuz! 7.0.0 |