@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; }
private double getSimilarity(Node item1, Node item2, boolean normalize) { if (initialize) { initialize(); } // If either value is unknown, return 0 similarity if (!item1.hasFeatureValue(featureid) || !item2.hasFeatureValue(featureid)) { return 0; } String[] string1 = item1.getFeatureValue(featureid).getStringValue().split(delimiter); Set<String> string1set = new HashSet<String>(string1.length); for (String s : string1) { if (s.trim().length() != 0) { string1set.add(s); } } String[] string2 = item2.getFeatureValue(featureid).getStringValue().split(delimiter); Set<String> string2set = new HashSet<String>(string2.length); for (String s : string2) { if (s.trim().length() != 0) { string2set.add(s); } } Set<String> isect = new HashSet<String>(string1set); isect.removeAll(string2set); if (isect.isEmpty()) { // Save computation by breaking early return 0; } double numerator = 0; for (String fid : isect) { double val1 = ((NumValue) item1.getFeatureValue(fid)).getNumber(); double val2 = ((NumValue) item2.getFeatureValue(fid)).getNumber(); numerator += val1 * val2; } double denom1 = 0; for (String fid : string1set) { double val1 = ((NumValue) item1.getFeatureValue(fid)).getNumber(); if (val1 == 0) { throw new InvalidStateException("Feature value cannot be 0: " + fid + " for " + item1); } denom1 += val1 * val1; } double denom2 = 0; for (String fid : string2set) { double val2 = ((NumValue) item2.getFeatureValue(fid)).getNumber(); if (val2 == 0) { throw new InvalidStateException("Feature value cannot be 0: " + fid + " for " + item2); } denom2 += val2 * val2; } double finalsim = denom1 != 0 && denom2 != 0 ? (numerator / (Math.sqrt(denom1) * Math.sqrt(denom2))) : 0; return finalsim; }