source: proiecte/Parallel-DT/R8/Src/besttree.c @ 26

Last change on this file since 26 was 26, checked in by (none), 14 years ago

blabla

File size: 9.9 KB
Line 
1/*************************************************************************/
2/*                                                                       */
3/*      Routines to manage tree growth, pruning and evaluation           */
4/*      ------------------------------------------------------           */
5/*                                                                       */
6/*************************************************************************/
7
8
9#include "defns.i"
10#include "types.i"
11#include "extern.i"
12
13
14ItemNo          *TargetClassFreq;
15Tree            *Raw;
16extern Tree     *Pruned;
17
18
19
20/*************************************************************************/
21/*                                                                       */
22/*      Grow and prune a single tree from all data                       */
23/*                                                                       */
24/*************************************************************************/
25
26
27    OneTree()
28/*  ---------  */
29{
30    Tree FormTree(), CopyTree();
31    Boolean Prune();
32
33    InitialiseTreeData();
34    InitialiseWeights();
35
36    Raw = (Tree *) calloc(1, sizeof(Tree));
37    Pruned = (Tree *) calloc(1, sizeof(Tree));
38
39    AllKnown = true;
40    Raw[0] = FormTree(0, MaxItem);
41    printf("\n");
42    PrintTree(Raw[0]);
43
44    SaveTree(Raw[0], ".unpruned");
45
46    Pruned[0] = CopyTree(Raw[0]);
47    if ( Prune(Pruned[0]) )
48    {
49        printf("\nSimplified ");
50        PrintTree(Pruned[0]);
51    }
52}
53
54
55
56/*************************************************************************/
57/*                                                                       */
58/*      Grow and prune TRIALS trees and select the best of them          */
59/*                                                                       */
60/*************************************************************************/
61
62
63short BestTree()
64/*    --------  */
65{
66    Tree CopyTree(), Iterate();
67    Boolean Prune();
68    short t, Best=0;
69
70    InitialiseTreeData();
71
72    TargetClassFreq = (ItemNo *) calloc(MaxClass+1, sizeof(ItemNo));
73
74    Raw    = (Tree *) calloc(TRIALS, sizeof(Tree));
75    Pruned = (Tree *) calloc(TRIALS, sizeof(Tree));
76
77    /*  If necessary, set initial size of window to 20% (or twice
78        the sqrt, if this is larger) of the number of data items,
79        and the maximum number of items that can be added to the
80        window at each iteration to 20% of the initial window size  */
81
82    if ( ! WINDOW )
83    {
84        WINDOW = Max(2 * sqrt(MaxItem+1.0), (MaxItem+1) / 5);
85    }
86
87    if ( ! INCREMENT )
88    {
89        INCREMENT = Max(WINDOW / 5, 1);
90    }
91
92    FormTarget(WINDOW);
93
94    /*  Form set of trees by iteration and prune  */
95
96    ForEach(t, 0, TRIALS-1 )
97    {
98        FormInitialWindow();
99
100        printf("\n--------\nTrial %d\n--------\n\n", t);
101
102        Raw[t] = Iterate(WINDOW, INCREMENT);
103        printf("\n");
104        PrintTree(Raw[t]);
105
106        SaveTree(Raw[t], ".unpruned");
107
108        Pruned[t] = CopyTree(Raw[t]);
109        if ( Prune(Pruned[t]) )
110        {
111            printf("\nSimplified ");
112            PrintTree(Pruned[t]);
113        }
114
115        if ( Pruned[t]->Errors < Pruned[Best]->Errors )
116        {
117            Best = t;
118        }
119    }
120    printf("\n--------\n");
121
122    return Best;
123}
124
125
126
127/*************************************************************************/
128/*                                                                       */
129/*  The windowing approach seems to work best when the class             */
130/*  distribution of the initial window is as close to uniform as         */
131/*  possible.  FormTarget generates this initial target distribution,    */
132/*  setting up a TargetClassFreq value for each class.                   */
133/*                                                                       */
134/*************************************************************************/
135
136
137    FormTarget(Size)
138/*  -----------  */
139    ItemNo Size;
140{
141    ItemNo i, *ClassFreq;
142    ClassNo c, Smallest, ClassesLeft=0;
143
144    ClassFreq = (ItemNo *) calloc(MaxClass+1, sizeof(ItemNo));
145
146    /*  Generate the class frequency distribution  */
147
148    ForEach(i, 0, MaxItem)
149    {
150        ClassFreq[ Class(Item[i]) ]++;
151    }
152
153    /*  Calculate the no. of classes of which there are items  */
154
155    ForEach(c, 0, MaxClass)
156    {
157        if ( ClassFreq[c] )
158        {
159            ClassesLeft++;
160        }
161        else
162        {
163            TargetClassFreq[c] = 0;
164        }
165    }
166
167    while ( ClassesLeft )
168    {
169        /*  Find least common class of which there are some items  */
170
171        Smallest = -1;
172        ForEach(c, 0, MaxClass)
173        {
174            if ( ClassFreq[c] &&
175                 ( Smallest < 0 || ClassFreq[c] < ClassFreq[Smallest] ) )
176            {
177                Smallest = c;
178            }
179        }
180
181        /*  Allocate the no. of items of this class to use in the window  */
182
183        TargetClassFreq[Smallest] = Min(ClassFreq[Smallest], Round(Size/ClassesLeft));
184
185        ClassFreq[Smallest] = 0;
186
187        Size -= TargetClassFreq[Smallest];
188        ClassesLeft--;
189    }
190
191    cfree(ClassFreq);
192}
193
194
195
196/*************************************************************************/
197/*                                                                       */
198/*  Form initial window, attempting to obtain the target class profile   */
199/*  in TargetClassFreq.  This is done by placing the targeted number     */
200/*  of items of each class at the beginning of the set of data items.    */
201/*                                                                       */
202/*************************************************************************/
203
204
205    FormInitialWindow()
206/*  -------------------  */
207{
208    ItemNo i, Start=0, More;
209    ClassNo c;
210    void Swap();
211
212    Shuffle();
213
214    ForEach(c, 0, MaxClass)
215    {
216        More = TargetClassFreq[c];
217
218        for ( i = Start ; More ; i++ )
219        {
220            if ( Class(Item[i]) == c )
221            {
222                Swap(Start, i);
223                Start++;
224                More--;
225            }
226        }
227    }
228}
229
230
231
232/*************************************************************************/
233/*                                                                       */
234/*              Shuffle the data items randomly                          */
235/*                                                                       */
236/*************************************************************************/
237
238
239    Shuffle()
240/*  -------  */
241{
242    ItemNo This, Alt, Left;
243    Description Hold;
244
245    This = 0;
246    for( Left = MaxItem+1 ; Left ; )
247    {
248        Alt = This + (Left--) * Random;
249        Hold = Item[This];
250        Item[This++] = Item[Alt];
251        Item[Alt] = Hold;
252    }
253}
254
255
256
257/*************************************************************************/
258/*                                                                       */
259/*  Grow a tree iteratively with initial window size Window and          */
260/*  initial window increment IncExceptions.                              */
261/*                                                                       */
262/*  Construct a classifier tree using the data items in the              */
263/*  window, then test for the successful classification of other         */
264/*  data items by this tree.  If there are misclassified items,          */
265/*  put them immediately after the items in the window, increase         */
266/*  the size of the window and build another classifier tree, and        */
267/*  so on until we have a tree which successfully classifies all         */
268/*  of the test items or no improvement is apparent.                     */
269/*                                                                       */
270/*  On completion, return the tree which produced the least errors.      */
271/*                                                                       */
272/*************************************************************************/
273
274
275Tree Iterate(Window, IncExceptions)
276/*   -------  */
277    ItemNo Window, IncExceptions;
278{
279    Tree Classifier, BestClassifier=Nil, FormTree();
280    ItemNo i, Errors, TotalErrors, BestTotalErrors=MaxItem+1,
281           Exceptions, Additions;
282    ClassNo Assigned, Category();
283    short Cycle=0;
284    void Swap();
285
286    printf("Cycle   Tree    -----Cases----");
287    printf("    -----------------Errors-----------------\n");
288    printf("        size    window   other");
289    printf("    window  rate   other  rate   total  rate\n");
290    printf("-----   ----    ------  ------");
291    printf("    ------  ----  ------  ----  ------  ----\n");
292
293    do
294    {
295        /*  Build a classifier tree with the first Window items  */
296
297        InitialiseWeights();
298        AllKnown = true;
299        Classifier = FormTree(0, Window-1);
300
301        /*  Error analysis  */
302
303        Errors = Round(Classifier->Errors);
304
305        /*  Move all items that are incorrectly classified by the
306            classifier tree to immediately after the items in the
307            current window.  */
308
309        Exceptions = Window;
310        ForEach(i, Window, MaxItem)
311        {
312            Assigned = Category(Item[i], Classifier);
313            if ( Assigned != Class(Item[i]) )
314            {
315                Swap(Exceptions, i);
316                Exceptions++;
317            }
318        }
319        Exceptions -= Window;
320        TotalErrors = Errors + Exceptions;
321
322        /*  Print error analysis  */
323
324        printf("%3d  %7d  %8d  %6d  %8d%5.1f%%  %6d%5.1f%%  %6d%5.1f%%\n",
325               ++Cycle, TreeSize(Classifier), Window, MaxItem-Window+1,
326               Errors, 100*(float)Errors/Window,
327               Exceptions, 100*Exceptions/(MaxItem-Window+1.001),
328               TotalErrors, 100*TotalErrors/(MaxItem+1.0));
329
330        /*  Keep track of the most successful classifier tree so far  */
331
332        if ( ! BestClassifier || TotalErrors < BestTotalErrors )
333        {
334            if ( BestClassifier ) ReleaseTree(BestClassifier);
335            BestClassifier = Classifier;
336            BestTotalErrors = TotalErrors;
337        }
338        else
339        {
340            ReleaseTree(Classifier);
341        }
342
343        /*  Increment window size  */
344
345        Additions = Min(Exceptions, IncExceptions);
346        Window = Min(Window + Max(Additions, Exceptions / 2), MaxItem + 1);
347    }
348    while ( Exceptions );
349
350    return BestClassifier;
351}
352
353
354
355/*************************************************************************/
356/*                                                                       */
357/*      Print report of errors for each of the trials                    */
358/*                                                                       */
359/*************************************************************************/
360
361
362    Evaluate(CMInfo, Saved)
363/*  --------  */
364    Boolean CMInfo;
365    short Saved;
366{
367    ClassNo RealClass, PrunedClass, Category();
368    short t;
369    ItemNo *ConfusionMat, i, RawErrors, PrunedErrors;
370
371    if ( CMInfo )
372    {
373        ConfusionMat = (ItemNo *) calloc((MaxClass+1)*(MaxClass+1), sizeof(ItemNo));
374    }
375
376    printf("\n");
377
378    if ( TRIALS > 1 )
379    {
380        printf("Trial\t Before Pruning           After Pruning\n");
381        printf("-----\t----------------   ---------------------------\n");
382    }
383    else
384    {
385        printf("\t Before Pruning           After Pruning\n");
386        printf("\t----------------   ---------------------------\n");
387    }
388    printf("\tSize      Errors   Size      Errors   Estimate\n\n");
389
390    ForEach(t, 0, TRIALS-1)
391    {
392        RawErrors = PrunedErrors = 0;
393
394        ForEach(i, 0, MaxItem)
395        {
396            RealClass = Class(Item[i]);
397
398            if ( Category(Item[i], Raw[t]) != RealClass ) RawErrors++;
399
400            PrunedClass = Category(Item[i], Pruned[t]);
401
402            if ( PrunedClass != RealClass ) PrunedErrors++;
403
404            if ( CMInfo && t == Saved )
405            {
406                ConfusionMat[RealClass*(MaxClass+1)+PrunedClass]++;
407            }
408        }
409   
410        if ( TRIALS > 1 )
411        {
412            printf("%4d", t);
413        }
414
415        printf("\t%4d  %3d(%4.1f%%)   %4d  %3d(%4.1f%%)    (%4.1f%%)%s\n",
416               TreeSize(Raw[t]), RawErrors, 100.0*RawErrors / (MaxItem+1.0),
417               TreeSize(Pruned[t]), PrunedErrors, 100.0*PrunedErrors / (MaxItem+1.0),
418               100 * Pruned[t]->Errors / Pruned[t]->Items,
419               ( t == Saved ? "   <<" : "" ));
420    }
421
422    if ( CMInfo )
423    {
424        PrintConfusionMatrix(ConfusionMat);
425        free(ConfusionMat);
426    }
427}
Note: See TracBrowser for help on using the repository browser.