1616
1717import com .rapidminer .operator .ports .metadata .AttributeMetaData ;
1818import com .rapidminer .operator .ports .metadata .ExampleSetMetaData ;
19+ import org .apache .commons .lang .math .NumberUtils ;
1920
2021import java .util .ArrayList ;
2122import java .util .List ;
23+ import java .util .logging .Level ;
2224import java .util .regex .Matcher ;
2325import java .util .regex .Pattern ;
2426
@@ -39,45 +41,50 @@ public class RuleParser {
3941 */
4042 public static Rule parseRule (String s , ExampleSetMetaData meta ) {
4143 Rule rule = null ;
42-
43- Pattern pattern = Pattern .compile ("IF\\ s+(?<premise>.+)\\ s+THEN(?<consequence>\\ s+.*|\\ s*)" );
44- Matcher matcher = pattern .matcher (s );
45-
46- boolean isSurvival = false ;
44+
45+ Pattern pattern = Pattern .compile ("IF\\ s+(?<premise>.+)\\ s+THEN(?<consequence>\\ s+.*|\\ s*)" );
46+ Matcher matcher = pattern .matcher (s );
47+
48+ boolean isSurvival = false ;
4749 if (meta .getAttributeByRole (SurvivalRule .SURVIVAL_TIME_ROLE ) != null ) {
4850 isSurvival = true ;
4951 }
50-
51- if (matcher .find ()) {
52- String pre = matcher .group ("premise" );
53- String con = matcher .group ("consequence" );
54-
55- ElementaryCondition consequence ;
56- CompoundCondition premise = parseCompoundCondition (pre , meta );
57-
58- if (con == null || con .trim ().length () == 0 ) {
59- if (!meta .getLabelMetaData ().isNumerical ())
60- throw new IllegalArgumentException ("Empty conclusion for non-numeric label attribute" );
61- consequence = new ElementaryCondition ();
62- consequence .attribute = meta .getLabelMetaData ().getName ();
63- consequence .valueSet = new SingletonSet (NaN , null );
64- consequence .adjustable = false ;
65- consequence .disabled = false ;
52+
53+ if (matcher .find ()) {
54+ String pre = matcher .group ("premise" );
55+ String con = matcher .group ("consequence" );
56+
57+ ElementaryCondition consequence = null ;
58+ CompoundCondition premise = parseCompoundCondition (pre , meta );
59+
60+ if (con == null || con .trim ().length () == 0 ) {
61+ if (!meta .getLabelMetaData ().isNumerical ()) {
62+ Logger .log ("Empty conclusion for nominal label" + "\n " , Level .WARNING );
63+ } else {
64+ consequence = new ElementaryCondition ();
65+ consequence .attribute = meta .getLabelMetaData ().getName ();
66+ consequence .valueSet = new SingletonSet (NaN , null );
67+ consequence .adjustable = false ;
68+ consequence .disabled = false ;
69+ }
6670 } else {
6771 consequence = parseElementaryCondition (con , meta );
6872 }
69-
70- if (premise == null || consequence == null ) {
71- return null ;
72- }
73-
74- rule = meta .getLabelMetaData ().isNominal ()
75- ? new ClassificationRule (premise , consequence )
76- : (isSurvival
73+
74+ if (premise != null && consequence != null ) {
75+
76+ rule = meta .getLabelMetaData ().isNominal ()
77+ ? new ClassificationRule (premise , consequence )
78+ : (isSurvival
7779 ? new SurvivalRule (premise , consequence )
7880 : new RegressionRule (premise , consequence ));
79- }
80-
81+ }
82+ }
83+
84+ if (rule == null ) {
85+ Logger .log ("Omitting expert's knowledge entry: " + s + "\n " , Level .WARNING );
86+ }
87+
8188 return rule ;
8289 }
8390
@@ -143,6 +150,10 @@ public static ElementaryCondition parseElementaryCondition(String s, ExampleSetM
143150 IValueSet valueSet = null ;
144151
145152 AttributeMetaData attributeMeta = meta .getAttributeByName (attribute );
153+ if (attributeMeta == null ) {
154+ Logger .log ("Attribute <" + attribute + "> not found" + "\n " , Level .WARNING );
155+ return null ;
156+ }
146157
147158 ConditionBase .Type type = (numBrackets == 0 ) ? ConditionBase .Type .NORMAL :
148159 ((numBrackets == 1 ) ? ConditionBase .Type .PREFERRED : ConditionBase .Type .FORCED );
@@ -159,7 +170,8 @@ public static ElementaryCondition parseElementaryCondition(String s, ExampleSetM
159170 mapping .addAll (attributeMeta .getValueSet ());
160171 double v = mapping .indexOf (value );
161172 if (v == -1 ) {
162- return null ;
173+ Logger .log ("Invalid value <" + value + "> of the nominal attribute <" + attribute + ">" + "\n " , Level .WARNING );
174+ return null ;
163175 }
164176 valueSet = new SingletonSet (v , mapping );
165177
@@ -180,14 +192,36 @@ public static ElementaryCondition parseElementaryCondition(String s, ExampleSetM
180192 matcher = regex .matcher (valueString );
181193
182194 if (matcher .find ()) {
195+
183196 String lo = matcher .group ("lo" );
184197 String hi = matcher .group ("hi" );
185-
186- valueSet = new Interval (
187- lo .equals ("-inf" ) ? Interval .MINUS_INF : Double .parseDouble (lo ),
188- hi .equals ("inf" )? Interval .INF : Double .parseDouble (hi ),
189- leftClosed , rightClosed );
190- }
198+
199+ double numLo = Double .NaN ;
200+ double numHi = Double .NaN ;
201+
202+ if (lo .equals ("-inf" )) {
203+ numLo = Interval .MINUS_INF ;
204+ } else if (NumberUtils .isNumber (lo )) {
205+ numLo = Double .parseDouble (lo );
206+ } else {
207+ Logger .log ("Invalid lower interval bound: " + lo + "\n " , Level .WARNING );
208+ return null ;
209+ }
210+
211+ if (hi .equals ("inf" )) {
212+ numHi = Interval .INF ;
213+ } else if (NumberUtils .isNumber (hi )) {
214+ numHi = Double .parseDouble (hi );
215+ } else {
216+ Logger .log ("Invalid upper interval bound: " + hi + "\n " , Level .WARNING );
217+ return null ;
218+ }
219+
220+ valueSet = new Interval (numLo , numHi , leftClosed , rightClosed );
221+ } else {
222+ Logger .log ("Invalid interval: " + valueString , Level .WARNING );
223+ return null ;
224+ }
191225 }
192226 }
193227
@@ -196,8 +230,11 @@ public static ElementaryCondition parseElementaryCondition(String s, ExampleSetM
196230 out .setType (type );
197231 out .setAdjustable (adjustable );
198232 }
199- }
233+ } else {
234+ Logger .log ("Invalid elementary condition: " + s + "\n " , Level .WARNING );
235+ }
200236
201237 return out ;
202238 }
239+
203240}
0 commit comments