@Override protected FeatureValue calcFeatureValue(Decorable di) { // Feature applicable only to edges if (!(di instanceof Edge)) { throw new UnsupportedTypeException( "Feature only defined for edges: " + di.getClass().getCanonicalName()); } // Feature applicable only to binary edges Edge e = (Edge) di; if (e.numNodes() != 2) { throw new UnsupportedTypeException("Feature only defined for binary edges: " + e.numNodes()); } Iterator<Node> itr = e.getAllNodes(); Node n1 = itr.next(); Node n2 = itr.next(); FeatureValue fv1 = n1.getFeatureValue(fid); FeatureValue fv2 = n2.getFeatureValue(fid); if (fv1.equals(FeatureValue.UNKNOWN_VALUE) || fv2.equals(FeatureValue.UNKNOWN_VALUE)) { return val0; } // If sparse value is specified and at least one value is not the sparse // value, return 0. if (commonvalue != null && fv1.equals(commonvalue)) { return val0; } return fv1.getStringValue().equals(fv2.getStringValue()) ? val1 : val0; }
@Override public void addNoise(Decorable d) { if (initialize) { this.initialize(); } Schema schema = d.getSchema(); // Load feature ids, if needed if (fids == null) { fids = FeatureUtils.parseFeatureList( this, schema, IteratorUtils.iterator2stringlist(schema.getFeatureIDs())); } for (String fid : fids) { Feature f = schema.getFeature(fid); // Flip attributes if (f instanceof ExplicitCateg) { // Handle explicit categorical features UnmodifiableList<String> cats = ((ExplicitCateg) f).getAllCategories(); int catsize = cats.size(); String oldvalue = d.getFeatureValue(fid).getStringValue(); if (sparsevalue != null && !oldvalue.equals(sparsevalue)) { // Only flip the non-sparse values // Done so for sparse sets, the common value doesn't become // too common. continue; } // Only flip given some probability if (rand.nextDouble() > probflip) { continue; } // Randomly select a category int index = rand.nextInt(catsize); if (changevalue && catsize > 1) { while (oldvalue.equals(cats.get(index))) { index = rand.nextInt(catsize); } } d.setFeatureValue(fid, new CategValue(cats.get(index))); } else if (f instanceof ExplicitNum) { double oldvalue = ((NumValue) d.getFeatureValue(fid)).getNumber(); if (oldvalue != 0.0 && oldvalue != 1.0) { throw new UnsupportedTypeException( "Numeric values must be either 0 or 1: " + d + "." + fid + "=" + oldvalue); } if (sparsevalue != null && oldvalue != Double.parseDouble(sparsevalue)) { // Only flip the non-sparse values // Done so for sparse sets, the common value doesn't become // too common. continue; } // Only flip given some probability if (rand.nextDouble() > probflip) { continue; } double value = 0; if (changevalue && oldvalue == value) { value = (oldvalue + 1) % 2; } else { // Randomly select a category value = rand.nextInt(2); } d.setFeatureValue(fid, new NumValue(value)); } else { throw new UnsupportedTypeException("Unsupported Type: " + f.getClass().getCanonicalName()); } } }