package lineage; import java.io.ObjectInputStream; import java.util.ArrayList; import java.util.Hashtable; import weka.classifiers.Classifier; import weka.core.Attribute; import weka.core.DenseInstance; import weka.core.Instance; import weka.core.Instances; /** * Lineage classifier class * * 2009 Ignacio Arganda-Carreras and Sergio Jimenez-Celorrio * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation (http://www.gnu.org/licenses/gpl.txt ) * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ public class LineageClassifier { // Deserialize model static private Classifier getClassifier() { ObjectInputStream ois = null; try { ois = new ObjectInputStream(LineageClassifier.class.getResourceAsStream("random_forest_top8_w1.1.model")); return (Classifier) ois.readObject(); } catch (Exception e) { e.printStackTrace(); } finally { if (null != ois) try { ois.close(); } catch (Exception e) { e.printStackTrace(); } } return null; } // Hashtable's methods are all synchronized static private final Hashtable<Thread,Operator> table = new Hashtable<Thread,Operator>(); final static protected String[] attrs = new String[]{"APD", "CPD", "STD", "MPD", "PM", "LEV", "SIM", "PRX", "PRM", "LR", "TR", "CLASS"}; static private final class Operator { final Classifier c = getClassifier(); final Instances data; Operator() { ArrayList<Attribute> a = new ArrayList<Attribute>(); for (int i=0; i<attrs.length-1; i++) { a.add(new Attribute(attrs[i])); // numeric } ArrayList<String> d = new ArrayList<String>(); d.add("false"); d.add("true"); a.add(new Attribute(attrs[attrs.length-1], d)); // nominal attribute data = new Instances("Buh", a, 0); data.setClassIndex(attrs.length-1); // the CLASS } } public static final boolean classify(final double[] vector) throws Exception { // Obtain or generate a Thread-local instance Operator op; synchronized (table) { // avoid clashes within weka final Thread t = Thread.currentThread(); op = table.get(t); if (null == op) { op = new Operator(); table.put(t, op); } } // Future weka versions will use new DenseInstance(1, vector) instead final Instance ins = new DenseInstance(1, vector); ins.setDataset(op.data); // Was trained to return true or false, represented in weka as 0 or 1 return 1 == ((int) Math.round(op.c.classifyInstance(ins))); } /** Removes all threads and Instances from the cache tables. */ static public final void flush () { table.clear(); } }