Changeset 70
- Timestamp:
- Jan 7, 2010, 9:02:28 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
proiecte/Parallel-DT/R8/Src/subset.c
r26 r70 6 6 /*************************************************************************/ 7 7 8 9 8 #include "buildex.i" 10 9 11 12 ItemCount 13 *Slice1, /* Slice1[c] = saved values of Freq[x][c] in subset.c */ 14 *Slice2; /* Slice2[c] = saved values of Freq[y][c] */ 15 16 Set 17 **Subset; /* Subset[a][s] = subset s for att a */ 18 19 short 20 *Subsets; /* Subsets[a] = no. subsets for att a */ 21 22 10 ItemCount *Slice1, /* Slice1[c] = saved values of Freq[x][c] in subset.c */ 11 *Slice2; /* Slice2[c] = saved values of Freq[y][c] */ 12 13 Set **Subset; /* Subset[a][s] = subset s for att a */ 14 15 short *Subsets; /* Subsets[a] = no. subsets for att a */ 23 16 24 17 /*************************************************************************/ … … 30 23 /*************************************************************************/ 31 24 32 33 EvalSubset(Att, Fp, Lp, Items) 34 /* ---------- */ 35 Attribute Att; 36 ItemNo Fp, Lp; 37 ItemCount Items; 38 { 39 DiscrValue V1, V2, BestV1, BestV2, Barred; 40 ItemCount KnownItems; 41 ClassNo c; 42 float BaseInfo, MinGain, ThisGain, ThisInfo, 43 Val, BestVal, BestGain, BestInfo, 44 PrevVal, PrevGain, PrevInfo, 45 DiscrKnownBaseInfo(), Worth(), ComputeGain(), TotalInfo(); 46 short Blocks=0, MissingValues=0, ReasonableSubsets, Bytes, b; 47 Boolean MergedSubsets = false; 48 int SaveMINOBJS; 49 50 SaveMINOBJS = MINOBJS; 51 MINOBJS = 1; 52 53 /* First compute Freq[][], ValFreq[], base info, and the gain 54 and total info of a split on discrete attribute Att */ 55 56 ComputeFrequencies(Att, Fp, Lp); 57 58 KnownItems = Items - ValFreq[0]; 59 if ( KnownItems < Epsilon ) 60 { 61 Verbosity(2) printf("\tAtt %s: no known values\n", AttName[Att]); 62 63 Gain[Att] = -Epsilon; 64 Info[Att] = 0; 65 return; 66 } 67 68 BaseInfo = DiscrKnownBaseInfo(KnownItems, MaxAttVal[Att]); 69 70 PrevGain = ComputeGain(BaseInfo, UnknownRate[Att], MaxAttVal[Att],KnownItems); 71 PrevInfo = TotalInfo(ValFreq, 0, MaxAttVal[Att]) / Items; 72 PrevVal = Worth(PrevInfo, PrevGain, Epsilon); 73 74 Verbosity(2) 75 { 76 printf("\tAtt %s", AttName[Att]); 77 78 Verbosity(3) PrintDistribution(Att, MaxAttVal[Att], true); 79 80 printf("\tinf %.3f, gain %.3f, val=%.3f\n", 81 PrevInfo, PrevGain, PrevVal); 82 } 83 84 /* Eliminate unrepresented attribute values from Freq[] and ValFreq[] 85 and form a separate subset for each represented attribute value */ 86 87 Bytes = (MaxAttVal[Att]>>3) + 1; 88 ClearBits(Bytes, Subset[Att][0]); 89 90 ForEach(V1, 1, MaxAttVal[Att]) 91 { 92 if ( ValFreq[V1] > 0.5 ) 93 { 94 if ( ++Blocks < V1 ) 95 { 96 ValFreq[Blocks] = ValFreq[V1]; 97 ForEach(c, 0, MaxClass) 98 { 99 Freq[Blocks][c] = Freq[V1][c]; 100 } 101 } 102 ClearBits(Bytes, Subset[Att][Blocks]); 103 SetBit(V1, Subset[Att][Blocks]); 104 } 105 else 106 { 107 SetBit(V1, Subset[Att][0]); 108 MissingValues++; 109 } 110 } 111 112 /* Merge any single-class subsets with others of the same class */ 113 /* Note: have ValFreq[V] > 0 for all V */ 114 115 ForEach(V1, 1, Blocks-1) 116 { 117 for ( c = 0 ; Freq[V1][c] < 0.1 ; c++ ) 118 ; 119 120 if ( Freq[V1][c] < ValFreq[V1] - 0.1 ) continue; 121 122 /* Now have a single class -- look for others */ 123 124 for ( V2 = V1+1 ; V2 <= Blocks ; ) 125 { 126 if ( Freq[V2][c] < ValFreq[V2] - 0.1 ) 127 { 128 V2++; 129 } 130 else 131 { 132 /* Merge these subsets */ 133 134 Combine(V1, V2, Blocks); 135 136 ForEach(b, 0, Bytes-1) 137 { 138 Subset[Att][V1][b] |= Subset[Att][V2][b]; 139 Subset[Att][V2][b] = Subset[Att][Blocks][b]; 25 EvalSubset(Att, Fp, Lp, Items) 26 /* ---------- */ 27 Attribute Att;ItemNo Fp, Lp;ItemCount Items; { 28 DiscrValue V1, V2, BestV1, BestV2, Barred; 29 ItemCount KnownItems; 30 ClassNo c; 31 float BaseInfo, MinGain, ThisGain, ThisInfo, Val, BestVal, BestGain, 32 BestInfo, PrevVal, PrevGain, PrevInfo, DiscrKnownBaseInfo(), 33 Worth(), ComputeGain(), TotalInfo(); 34 short Blocks = 0, MissingValues = 0, ReasonableSubsets, Bytes, b; 35 Boolean MergedSubsets = false; 36 int SaveMINOBJS; 37 38 SaveMINOBJS = MINOBJS; 39 MINOBJS = 1; 40 41 /* First compute Freq[][], ValFreq[], base info, and the gain 42 and total info of a split on discrete attribute Att */ 43 44 ComputeFrequencies(Att, Fp, Lp); 45 46 KnownItems = Items - ValFreq[0]; 47 if (KnownItems < Epsilon) { 48 Verbosity(2) 49 printf("\tAtt %s: no known values\n", AttName[Att]); 50 51 Gain[Att] = -Epsilon; 52 Info[Att] = 0; 53 return; 54 } 55 56 BaseInfo = DiscrKnownBaseInfo(KnownItems, MaxAttVal[Att]); 57 58 PrevGain = ComputeGain(BaseInfo, UnknownRate[Att], MaxAttVal[Att], 59 KnownItems); 60 PrevInfo = TotalInfo(ValFreq, 0, MaxAttVal[Att]) / Items; 61 PrevVal = Worth(PrevInfo, PrevGain, Epsilon); 62 63 Verbosity(2) { 64 printf("\tAtt %s", AttName[Att]); 65 66 Verbosity(3) 67 PrintDistribution(Att, MaxAttVal[Att], true); 68 69 printf("\tinf %.3f, gain %.3f, val=%.3f\n", PrevInfo, PrevGain, PrevVal); 70 } 71 72 /* Eliminate unrepresented attribute values from Freq[] and ValFreq[] 73 and form a separate subset for each represented attribute value */ 74 75 Bytes = (MaxAttVal[Att] >> 3) + 1; 76 ClearBits(Bytes, Subset[Att][0]); 77 78 ForEach(V1, 1, MaxAttVal[Att]) { 79 if (ValFreq[V1] > 0.5) { 80 if (++Blocks < V1) { 81 ValFreq[Blocks] = ValFreq[V1]; 82 ForEach(c, 0, MaxClass) { 83 Freq[Blocks][c] = Freq[V1][c]; 84 } 85 } 86 ClearBits(Bytes, Subset[Att][Blocks]); 87 SetBit(V1, Subset[Att][Blocks]); 88 } else { 89 SetBit(V1, Subset[Att][0]); 90 MissingValues++; 91 } 92 } 93 94 /* Merge any single-class subsets with others of the same class */ 95 /* Note: have ValFreq[V] > 0 for all V */ 96 97 ForEach(V1, 1, Blocks-1) { 98 for (c = 0; Freq[V1][c] < 0.1; c++) 99 ; 100 101 if (Freq[V1][c] < ValFreq[V1] - 0.1) 102 continue; 103 104 /* Now have a single class -- look for others */ 105 106 for (V2 = V1 + 1; V2 <= Blocks;) { 107 if (Freq[V2][c] < ValFreq[V2] - 0.1) { 108 V2++; 109 } else { 110 /* Merge these subsets */ 111 112 Combine(V1, V2, Blocks); 113 114 ForEach(b, 0, Bytes-1) { 115 Subset[Att][V1][b] |= Subset[Att][V2][b]; 116 Subset[Att][V2][b] = Subset[Att][Blocks][b]; 117 } 118 119 Blocks--; 120 MergedSubsets = true; 121 } 122 } 123 } 124 125 if (MergedSubsets) { 126 PrevGain = ComputeGain(BaseInfo, UnknownRate[Att], Blocks, KnownItems); 127 PrevInfo = TotalInfo(ValFreq, 0, Blocks) / Items; 128 PrevVal = Worth(PrevInfo, PrevGain, Epsilon); 129 130 Verbosity(2) { 131 printf("\tAfter merging single-class subsets:"); 132 133 Verbosity(3) 134 PrintDistribution(Att, Blocks, false); 135 136 printf("\tinf %.3f, gain %.3f, val=%.3f\n", PrevInfo, PrevGain, 137 PrevVal); 138 } 139 } 140 141 /* Examine possible pair mergers and hill-climb */ 142 143 MinGain = PrevGain / 2; 144 145 while (Blocks > 2) { 146 BestVal = BestV1 = 0; 147 BestGain = -Epsilon; 148 149 /* Check reasonable subsets; if less than 3, bar mergers 150 involving the largest block */ 151 152 ReasonableSubsets = 0; 153 Barred = 1; 154 155 ForEach(V1, 1, Blocks) { 156 if (ValFreq[V1] >= SaveMINOBJS) 157 ReasonableSubsets++; 158 159 if (ValFreq[V1] > ValFreq[Barred]) 160 Barred = V1; 161 } 162 163 if (ReasonableSubsets >= 3) 164 Barred = 0; 165 166 /* For each possible pair of values, calculate the gain and 167 total info of a split in which they are treated as one. 168 Keep track of the pair with the best gain. */ 169 170 ForEach(V1, 1, Blocks-1) { 171 ForEach(V2, V1+1, Blocks) { 172 if (V1 == Barred || V2 == Barred) 173 continue; 174 175 Combine(V1, V2, Blocks); 176 177 ThisGain = ComputeGain(BaseInfo, UnknownRate[Att], Blocks - 1, 178 KnownItems); 179 ThisInfo = TotalInfo(ValFreq, 0, Blocks - 1) / Items; 180 Val = Worth(ThisInfo, ThisGain, Epsilon); 181 182 Verbosity(4) { 183 printf("\tcombine %d %d info %.3f gain %.3f val %.3f", V1, 184 V2, ThisInfo, ThisGain, Val); 185 PrintDistribution(Att, Blocks - 1, false); 186 } 187 188 /* Force a split if 189 less than two reasonable subsets, or 190 using GAIN criterion 191 Prefer this split to the previous one if 192 gain >= MinGain (and previous < MinGain), or 193 val >= previous best val */ 194 195 if (ThisGain >= MinGain && BestGain < MinGain || Val >= BestVal 196 || !BestV1 && (!GAINRATIO || ReasonableSubsets < 2)) { 197 BestVal = Val; 198 BestGain = ThisGain; 199 BestInfo = ThisInfo; 200 BestV1 = V1; 201 BestV2 = V2; 202 } 203 204 Uncombine(V1, V2); 205 } 206 } 207 208 if (GAINRATIO && ReasonableSubsets >= 2 && (!BestV1 || BestVal 209 < PrevVal + 1E-5 || BestVal == PrevVal && BestGain < PrevGain)) 210 break; 211 212 PrevGain = BestGain; 213 PrevInfo = BestInfo; 214 PrevVal = BestVal; 215 216 Combine(BestV1, BestV2, Blocks); 217 218 ForEach(b, 0, Bytes-1) { 219 Subset[Att][BestV1][b] |= Subset[Att][BestV2][b]; 220 Subset[Att][BestV2][b] = Subset[Att][Blocks][b]; 140 221 } 141 222 142 223 Blocks--; 143 MergedSubsets = true; 144 } 145 } 146 } 147 148 if ( MergedSubsets ) 149 { 150 PrevGain = ComputeGain(BaseInfo, UnknownRate[Att], Blocks, KnownItems); 151 PrevInfo = TotalInfo(ValFreq, 0, Blocks) / Items; 152 PrevVal = Worth(PrevInfo, PrevGain, Epsilon); 153 154 Verbosity(2) 155 { 156 printf("\tAfter merging single-class subsets:"); 157 158 Verbosity(3) PrintDistribution(Att, Blocks, false); 159 160 printf("\tinf %.3f, gain %.3f, val=%.3f\n", 161 PrevInfo, PrevGain, PrevVal); 162 } 163 } 164 165 /* Examine possible pair mergers and hill-climb */ 166 167 MinGain = PrevGain / 2; 168 169 while ( Blocks > 2 ) 170 { 171 BestVal = BestV1 = 0; 172 BestGain = -Epsilon; 173 174 /* Check reasonable subsets; if less than 3, bar mergers 175 involving the largest block */ 176 177 ReasonableSubsets = 0; 178 Barred = 1; 179 180 ForEach(V1, 1, Blocks) 181 { 182 if ( ValFreq[V1] >= SaveMINOBJS ) ReasonableSubsets++; 183 184 if ( ValFreq[V1] > ValFreq[Barred] ) Barred = V1; 185 } 186 187 if ( ReasonableSubsets >= 3 ) Barred = 0; 188 189 /* For each possible pair of values, calculate the gain and 190 total info of a split in which they are treated as one. 191 Keep track of the pair with the best gain. */ 192 193 ForEach(V1, 1, Blocks-1) 194 { 195 ForEach(V2, V1+1, Blocks) 196 { 197 if ( V1 == Barred || V2 == Barred ) continue; 198 199 Combine(V1, V2, Blocks); 200 201 ThisGain = ComputeGain(BaseInfo, UnknownRate[Att], 202 Blocks-1, KnownItems); 203 ThisInfo = TotalInfo(ValFreq, 0, Blocks-1) / Items; 204 Val = Worth(ThisInfo, ThisGain, Epsilon); 205 206 Verbosity(4) 207 { 208 printf("\tcombine %d %d info %.3f gain %.3f val %.3f", 209 V1, V2, ThisInfo, ThisGain, Val); 210 PrintDistribution(Att, Blocks-1, false); 211 } 212 213 /* Force a split if 214 less than two reasonable subsets, or 215 using GAIN criterion 216 Prefer this split to the previous one if 217 gain >= MinGain (and previous < MinGain), or 218 val >= previous best val */ 219 220 if ( ThisGain >= MinGain && BestGain < MinGain || 221 Val >= BestVal || 222 ! BestV1 && ( ! GAINRATIO || ReasonableSubsets < 2 ) ) 223 { 224 BestVal = Val; 225 BestGain = ThisGain; 226 BestInfo = ThisInfo; 227 BestV1 = V1; 228 BestV2 = V2; 229 } 230 231 Uncombine(V1, V2); 232 } 233 } 234 235 if ( GAINRATIO && 236 ReasonableSubsets >= 2 && 237 ( ! BestV1 || 238 BestVal < PrevVal + 1E-5 || 239 BestVal == PrevVal && BestGain < PrevGain ) ) break; 240 241 PrevGain = BestGain; 242 PrevInfo = BestInfo; 243 PrevVal = BestVal; 244 245 Combine(BestV1, BestV2, Blocks); 246 247 ForEach(b, 0, Bytes-1) 248 { 249 Subset[Att][BestV1][b] |= Subset[Att][BestV2][b]; 250 Subset[Att][BestV2][b] = Subset[Att][Blocks][b]; 251 } 252 253 Blocks--; 254 255 Verbosity(2) 256 { 257 printf("\t\tform subset "); 258 PrintSubset(Att, Subset[Att][BestV1]); 259 printf(": %d subsets, inf %.3f, gain %.3f, val %.3f\n", 260 Blocks, BestInfo, BestGain, BestVal); 261 Verbosity(3) 262 { 263 printf("\t\tcombine %d, %d", BestV1, BestV2); 264 PrintDistribution(Att, Blocks, false); 265 } 266 } 267 } 268 269 MINOBJS = SaveMINOBJS; 270 271 if ( PrevVal <= 0 ) 272 { 273 Gain[Att] = -Epsilon; 274 Info[Att] = 0; 275 } 276 else 277 { 278 Gain[Att] = ComputeGain(BaseInfo, UnknownRate[Att], Blocks, KnownItems); 279 Info[Att] = PrevInfo; 280 281 if ( MissingValues ) 282 { 283 Blocks++; 284 CopyBits(Bytes, Subset[Att][0], Subset[Att][Blocks]); 285 } 286 287 Subsets[Att] = Blocks; 288 289 Verbosity(2) printf("\tFinal subsets:"); 290 Verbosity(3) PrintDistribution(Att, Blocks, false); 291 Verbosity(2) 292 printf("\tinf %.3f gain %.3f val %.3f\n", 293 Info[Att], Gain[Att], Worth(Info[Att], Gain[Att], Epsilon)); 294 } 295 } 296 297 224 225 Verbosity(2) { 226 printf("\t\tform subset "); 227 PrintSubset(Att, Subset[Att][BestV1]); 228 printf(": %d subsets, inf %.3f, gain %.3f, val %.3f\n", Blocks, 229 BestInfo, BestGain, BestVal); 230 Verbosity(3) { 231 printf("\t\tcombine %d, %d", BestV1, BestV2); 232 PrintDistribution(Att, Blocks, false); 233 } 234 } 235 } 236 237 MINOBJS = SaveMINOBJS; 238 239 if (PrevVal <= 0) { 240 Gain[Att] = -Epsilon; 241 Info[Att] = 0; 242 } else { 243 Gain[Att] = ComputeGain(BaseInfo, UnknownRate[Att], Blocks, KnownItems); 244 Info[Att] = PrevInfo; 245 246 if (MissingValues) { 247 Blocks++; 248 CopyBits(Bytes, Subset[Att][0], Subset[Att][Blocks]); 249 } 250 251 Subsets[Att] = Blocks; 252 253 Verbosity(2) 254 printf("\tFinal subsets:"); 255 Verbosity(3) 256 PrintDistribution(Att, Blocks, false); 257 Verbosity(2) 258 printf("\tinf %.3f gain %.3f val %.3f\n", Info[Att], Gain[Att], 259 Worth(Info[Att], Gain[Att], Epsilon)); 260 } 261 } 298 262 299 263 /*************************************************************************/ … … 305 269 /*************************************************************************/ 306 270 307 308 Combine(x, y, Last) 309 /* ------- */ 310 DiscrValue x, y, Last; 311 { 312 ClassNo c; 313 314 ForEach(c, 0, MaxClass) 315 { 316 Slice1[c] = Freq[x][c]; 317 Slice2[c] = Freq[y][c]; 318 319 Freq[x][c] += Freq[y][c]; 320 Freq[y][c] = Freq[Last][c]; 321 } 322 323 Slice1[MaxClass+1] = ValFreq[x]; 324 Slice2[MaxClass+1] = ValFreq[y]; 325 326 ValFreq[x] += ValFreq[y]; 327 ValFreq[y] = ValFreq[Last]; 328 } 329 330 271 Combine(x, y, Last) 272 /* ------- */ 273 DiscrValue x, y, Last; { 274 ClassNo c; 275 276 ForEach(c, 0, MaxClass) { 277 Slice1[c] = Freq[x][c]; 278 Slice2[c] = Freq[y][c]; 279 280 Freq[x][c] += Freq[y][c]; 281 Freq[y][c] = Freq[Last][c]; 282 } 283 284 Slice1[MaxClass + 1] = ValFreq[x]; 285 Slice2[MaxClass + 1] = ValFreq[y]; 286 287 ValFreq[x] += ValFreq[y]; 288 ValFreq[y] = ValFreq[Last]; 289 } 331 290 332 291 /*************************************************************************/ … … 337 296 /*************************************************************************/ 338 297 339 340 Uncombine(x, y) 341 /* --------- */ 342 DiscrValue x, y; 343 { 344 ClassNo c; 345 346 ForEach(c, 0, MaxClass) 347 { 348 Freq[x][c] = Slice1[c]; 349 Freq[y][c] = Slice2[c]; 350 } 351 352 ValFreq[x] = Slice1[MaxClass+1]; 353 ValFreq[y] = Slice2[MaxClass+1]; 354 } 355 356 298 Uncombine(x, y) 299 /* --------- */ 300 DiscrValue x, y; { 301 ClassNo c; 302 303 ForEach(c, 0, MaxClass) { 304 Freq[x][c] = Slice1[c]; 305 Freq[y][c] = Slice2[c]; 306 } 307 308 ValFreq[x] = Slice1[MaxClass + 1]; 309 ValFreq[y] = Slice2[MaxClass + 1]; 310 } 357 311 358 312 /*************************************************************************/ … … 362 316 /*************************************************************************/ 363 317 364 365 PrintSubset(Att, Ss) 366 /* ----------- */ 367 Attribute Att; 368 Set Ss; 369 { 370 DiscrValue V1; 371 Boolean First=true; 372 373 ForEach(V1, 1, MaxAttVal[Att]) 374 { 375 if ( In(V1, Ss) ) 376 { 377 if ( First ) 378 { 379 First = false; 380 } 381 else 382 { 383 printf(", "); 384 } 385 386 printf("%s", AttValName[Att][V1]); 387 } 388 } 389 } 390 391 318 PrintSubset(Att, Ss) 319 /* ----------- */ 320 Attribute Att;Set Ss; { 321 DiscrValue V1; 322 Boolean First = true; 323 324 ForEach(V1, 1, MaxAttVal[Att]) { 325 if (In(V1, Ss)) { 326 if (First) { 327 First = false; 328 } else { 329 printf(", "); 330 } 331 332 printf("%s", AttValName[Att][V1]); 333 } 334 } 335 } 392 336 393 337 /*************************************************************************/ … … 397 341 /*************************************************************************/ 398 342 399 400 SubsetTest(Node, Att) 401 /* ----------- */ 402 Tree Node; 403 Attribute Att; 404 { 405 ItemCount CountItems(); 406 short S, Bytes; 407 408 Sprout(Node, Subsets[Att]); 409 410 Node->NodeType = BrSubset; 411 Node->Tested = Att; 412 Node->Errors = 0; 413 414 Bytes = (MaxAttVal[Att]>>3) + 1; 415 Node->Subset = (Set *) calloc(Subsets[Att] + 1, sizeof(Set)); 416 ForEach(S, 1, Node->Forks) 417 { 418 Node->Subset[S] = (Set) malloc(Bytes); 419 CopyBits(Bytes, Subset[Att][S], Node->Subset[S]); 420 } 421 } 343 SubsetTest(Node, Att) 344 /* ----------- */ 345 Tree Node;Attribute Att; { 346 ItemCount CountItems(); 347 short S, Bytes; 348 349 Sprout(Node, Subsets[Att]); 350 351 Node->NodeType = BrSubset; 352 Node->Tested = Att; 353 Node->Errors = 0; 354 355 Bytes = (MaxAttVal[Att] >> 3) + 1; 356 Node->Subset = (Set *) calloc(Subsets[Att] + 1, sizeof(Set)); 357 ForEach(S, 1, Node->Forks) { 358 Node->Subset[S] = (Set) malloc(Bytes); 359 CopyBits(Bytes, Subset[Att][S], Node->Subset[S]); 360 } 361 }
Note: See TracChangeset
for help on using the changeset viewer.