@@ -61,8 +61,6 @@ public ClassificationSnC(AbstractFinder finder, InductionParameters params) {
6161 public RuleSetBase run (ExampleSet dataset ) {
6262 Logger .log ("ClassificationSnC.run()\n " , Level .FINE );
6363
64- ClassificationRuleSet finalRuleset = (ClassificationRuleSet ) factory .create (dataset );
65-
6664 // use contrast attribute if specified
6765 final Attribute outputAttr = (dataset .getAttributes ().getSpecial (ContrastRule .CONTRAST_ATTRIBUTE_ROLE ) == null )
6866 ? dataset .getAttributes ().getLabel ()
@@ -72,168 +70,129 @@ public RuleSetBase run(ExampleSet dataset) {
7270
7371 boolean weighted = (dataset .getAttributes ().getWeight () != null );
7472
75- ExecutorService pool = Executors .newFixedThreadPool (numClassThreads );
76- Semaphore mutex = new Semaphore (1 );
77- AtomicInteger totalRules = new AtomicInteger (0 );
78-
7973 // perform prepreprocessing
8074 finder .preprocess (dataset );
75+ ClassificationRuleSet ruleset = (ClassificationRuleSet ) factory .create (dataset );
76+
77+ // add rulesets from all classes
78+ double defaultClassP = 0 ;
8179
82- // array of futures, each consisting of ruleset and P value
83- Map <Integer , Future <Pair <ClassificationRuleSet , Double >>> futures = new HashMap <Integer , Future <Pair <ClassificationRuleSet , Double >>>();
84-
8580 // iterate over all classes
8681 for (int cid = 0 ; cid < mapping .size (); ++cid ) {
8782 final int classId = cid ;
83+ Logger .log ("Class " + classId + " started\n " , Level .FINE );
8884
89- Future <Pair <ClassificationRuleSet , Double >> future = pool .submit ( () -> {
90- Logger .log ("Class " + classId + " started\n " , Level .FINE );
91-
92- preprocessClass (dataset , classId );
93-
94- ClassificationRuleSet ruleset = (ClassificationRuleSet ) factory .create (dataset );
95-
96- IntegerBitSet positives = new IntegerBitSet (dataset .size ());
97- IntegerBitSet negatives = new IntegerBitSet (dataset .size ());
98- IntegerBitSet uncoveredPositives = new IntegerBitSet (dataset .size ());
99- Set <Integer > uncovered = new HashSet <Integer >();
100-
101- double weighted_P = 0 ;
102- double weighted_N = 0 ;
103-
104- // at the beginning rule set does not cover any examples
105- for (int id = 0 ; id < dataset .size (); ++id ) {
106- Example e = dataset .getExample (id );
107- double w = dataset .getAttributes ().getWeight () == null ? 1.0 : e .getWeight ();
108-
109- if ((double )e .getValue (outputAttr ) == classId ) {
110- weighted_P += w ;
111- positives .add (id );
112- } else {
113- weighted_N += w ;
114- negatives .add (id );
115- }
85+ preprocessClass (dataset , classId );
86+
87+ IntegerBitSet positives = new IntegerBitSet (dataset .size ());
88+ IntegerBitSet negatives = new IntegerBitSet (dataset .size ());
89+ IntegerBitSet uncoveredPositives = new IntegerBitSet (dataset .size ());
90+ Set <Integer > uncovered = new HashSet <Integer >();
91+
92+ double weighted_P = 0 ;
93+ double weighted_N = 0 ;
94+
95+ // at the beginning rule set does not cover any examples
96+ for (int id = 0 ; id < dataset .size (); ++id ) {
97+ Example e = dataset .getExample (id );
98+ double w = !weighted ? 1.0 : e .getWeight ();
99+
100+ if ((double )e .getValue (outputAttr ) == classId ) {
101+ weighted_P += w ;
102+ positives .add (id );
103+ } else {
104+ weighted_N += w ;
105+ negatives .add (id );
116106 }
117- uncoveredPositives .addAll (positives );
118- uncovered .addAll (positives );
119- uncovered .addAll (negatives );
120-
121- boolean carryOn = uncoveredPositives .size () > 0 ;
122- double uncovered_p = weighted_P ;
123-
124- while (carryOn ) {
125-
126- Logger .log ("Class " + classId + " uncovered positive weight:" +
127- uncovered_p + "/" + weighted_P + "\n " , Level .FINE );
128- Rule rule = factory .create (
129- new CompoundCondition (),
130- new ElementaryCondition (outputAttr .getName (), new SingletonSet ((double )classId , mapping .getValues ())));
131-
132- // rule covers everything at the beginning
133- rule .setWeighted_P (weighted_P );
134- rule .setWeighted_N (weighted_N );
135- rule .setWeighted_p (weighted_P );
136- rule .setWeighted_n (weighted_N );
137-
138- rule .setCoveredPositives (new IntegerBitSet (dataset .size ()));
139- rule .setCoveredNegatives (new IntegerBitSet (dataset .size ()));
140- rule .getCoveredPositives ().addAll (positives );
141- rule .getCoveredNegatives ().addAll (negatives );
142- rule .setRuleOrderNum (ruleset .getRules ().size ());
143-
144- rule .getConsequence ().setCovering (positives );
145-
146- double t = System .nanoTime ();
147- carryOn = (finder .grow (rule , dataset , uncoveredPositives ) > 0 );
148- ruleset .setGrowingTime ( ruleset .getGrowingTime () + (System .nanoTime () - t ) / 1e9 );
149-
150- if (carryOn ) {
151- if (params .isPruningEnabled ()) {
152- Logger .log ("Before prunning:" + rule .toString () + "\n " , Level .FINE );
153- t = System .nanoTime ();
154- finder .prune (rule , dataset , uncoveredPositives );
155- ruleset .setPruningTime ( ruleset .getPruningTime () + (System .nanoTime () - t ) / 1e9 );
156- }
157-
158-
159- Logger .log ("Class " + classId + ", candidate rule " + ruleset .getRules ().size () + ":" + rule .toString () + "\n " , Level .FINE );
160-
161- // remove covered examples
162- int previouslyUncovered = uncoveredPositives .size ();
163- uncoveredPositives .removeAll (rule .getCoveredPositives ());
164- uncovered .removeAll (rule .getCoveredPositives ());
165- uncovered .removeAll (rule .getCoveredNegatives ());
166-
167- uncovered_p = 0 ;
168- for (int id : uncoveredPositives ) {
169- Example e = dataset .getExample (id );
170- uncovered_p += dataset .getAttributes ().getWeight () == null ? 1.0 : e .getWeight ();
171- }
172-
173- Logger .log ("Uncovered positives" + uncovered_p + "\n " , Level .FINER );
174-
175-
176- // stop if number of positive examples remaining is less than threshold
177- if (uncovered_p <= params .getMaximumUncoveredFraction () * weighted_P ) {
178- carryOn = false ;
179- }
180-
181- // stop and ignore last rule if no new positive examples covered
182- if (uncoveredPositives .size () == previouslyUncovered ) {
183- carryOn = false ;
184- } else {
185- finder .postprocess (rule , dataset );
186- ruleset .addRule (rule );
187- mutex .acquire (1 );
188- Logger .log ( "\r " + StringUtils .repeat ("\t " , 10 ) + "\r " , Level .INFO );
189- Logger .log ("\t " + totalRules .incrementAndGet () + " rules" , Level .INFO );
190- mutex .release (1 );
191- }
192- //report to operator command proxy
193- this .operatorCommandProxy .onNewRule (rule );
194- this .operatorCommandProxy .onProgressChange (dataset .size (), uncovered .size ());
107+ }
108+ uncoveredPositives .addAll (positives );
109+ uncovered .addAll (positives );
110+ uncovered .addAll (negatives );
111+
112+ if (weighted_P > defaultClassP ) {
113+ defaultClassP = weighted_P ;
114+ ruleset .setDefaultClass (classId );
115+ }
116+
117+ boolean carryOn = uncoveredPositives .size () > 0 ;
118+ double uncovered_p = weighted_P ;
119+
120+ while (carryOn ) {
121+
122+ Logger .log ("Class " + classId + " uncovered positive weight:" +
123+ uncovered_p + "/" + weighted_P + "\n " , Level .FINE );
124+ Rule rule = factory .create (
125+ new CompoundCondition (),
126+ new ElementaryCondition (outputAttr .getName (), new SingletonSet ((double ) classId , mapping .getValues ())));
127+
128+ // rule covers everything at the beginning
129+ rule .setWeighted_P (weighted_P );
130+ rule .setWeighted_N (weighted_N );
131+ rule .setWeighted_p (weighted_P );
132+ rule .setWeighted_n (weighted_N );
133+
134+ rule .setCoveredPositives (new IntegerBitSet (dataset .size ()));
135+ rule .setCoveredNegatives (new IntegerBitSet (dataset .size ()));
136+ rule .getCoveredPositives ().addAll (positives );
137+ rule .getCoveredNegatives ().addAll (negatives );
138+ rule .setRuleOrderNum (ruleset .getRules ().size ());
139+
140+ rule .getConsequence ().setCovering (positives );
141+
142+ double t = System .nanoTime ();
143+ carryOn = (finder .grow (rule , dataset , uncoveredPositives ) > 0 );
144+ ruleset .setGrowingTime (ruleset .getGrowingTime () + (System .nanoTime () - t ) / 1e9 );
145+
146+ if (carryOn ) {
147+ if (params .isPruningEnabled ()) {
148+ Logger .log ("Before prunning:" + rule .toString () + "\n " , Level .FINE );
149+ t = System .nanoTime ();
150+ finder .prune (rule , dataset , uncoveredPositives );
151+ ruleset .setPruningTime (ruleset .getPruningTime () + (System .nanoTime () - t ) / 1e9 );
152+ }
153+
154+
155+ Logger .log ("Class " + classId + ", candidate rule " + ruleset .getRules ().size () + ":" + rule .toString () + "\n " , Level .FINE );
156+
157+ // remove covered examples
158+ int previouslyUncovered = uncoveredPositives .size ();
159+ uncoveredPositives .removeAll (rule .getCoveredPositives ());
160+ uncovered .removeAll (rule .getCoveredPositives ());
161+ uncovered .removeAll (rule .getCoveredNegatives ());
195162
163+ uncovered_p = 0 ;
164+ for (int id : uncoveredPositives ) {
165+ Example e = dataset .getExample (id );
166+ uncovered_p += dataset .getAttributes ().getWeight () == null ? 1.0 : e .getWeight ();
196167 }
197- if (this .operatorCommandProxy .isRequestStop ()) {
168+
169+ Logger .log ("Uncovered positives" + uncovered_p + "\n " , Level .FINER );
170+
171+ // stop if number of positive examples remaining is less than threshold
172+ if (uncovered_p <= params .getMaximumUncoveredFraction () * weighted_P ) {
198173 carryOn = false ;
199174 }
200- }
201-
202- return new Pair <ClassificationRuleSet , Double >(ruleset , weighted_P );
203- });
204-
205- futures .put (classId , future );
206- }
207175
208- // add rulesets from all classes
209- double defaultClassP = 0 ;
210-
211- for (int classId = 0 ; classId < mapping .size (); ++classId ) {
212- Pair <ClassificationRuleSet , Double > result ;
213-
214- try {
215- result = futures .get (classId ).get ();
216- ClassificationRuleSet partialSet = result .getFirst ();
217- finalRuleset .getRules ().addAll (partialSet .getRules ());
218- finalRuleset .setGrowingTime ( finalRuleset .getGrowingTime () + partialSet .getGrowingTime ());
219- finalRuleset .setPruningTime ( finalRuleset .getPruningTime () + partialSet .getPruningTime ());
220-
221- // set default class
222- if (result .getSecond () > defaultClassP ) {
223- defaultClassP = result .getSecond ();
224- finalRuleset .setDefaultClass (classId );
176+ // stop and ignore last rule if no new positive examples covered
177+ if (uncoveredPositives .size () == previouslyUncovered ) {
178+ carryOn = false ;
179+ } else {
180+ finder .postprocess (rule , dataset );
181+ ruleset .addRule (rule );
182+ Logger .log ("\r " + StringUtils .repeat ("\t " , 10 ) + "\r " , Level .INFO );
183+ Logger .log ("\t " + ruleset .getRules ().size () + " rules" , Level .INFO );
184+ }
185+ //report to operator command proxy
186+ this .operatorCommandProxy .onNewRule (rule );
187+ this .operatorCommandProxy .onProgressChange (dataset .size (), uncovered .size ());
188+ }
189+ if (this .operatorCommandProxy .isRequestStop ()) {
190+ carryOn = false ;
225191 }
226-
227- } catch (InterruptedException | ExecutionException e ) {
228- // TODO Auto-generated catch block
229- e .printStackTrace ();
230192 }
231-
232193 }
233194
234- pool .shutdown ();
235-
236- return finalRuleset ;
195+ return ruleset ;
237196 }
238197
239198 public void preprocessClass (ExampleSet dataset , int classId ) {
0 commit comments