📄 userclassifier.java
字号:
m_tView = new TreeVisualizer(UserClassifier.this, graph(), new PlaceNode2()); m_tView.setHighlight(m_focus.m_identity); m_reps.setComponentAt(0, m_tView); m_iView.setShapes(null); } catch(Exception er) { System.out.println("Error : " + er); System.out.println("Part of user input so had to catch here"); } } }); m_built = false; m_mainWin = new JFrame(); m_mainWin.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { int well = JOptionPane.showConfirmDialog(m_mainWin, "Are You Sure...\n" + "Click Yes To Accept" + " The Tree" + "\n Click No To Return", "Accept Tree", JOptionPane.YES_NO_OPTION); if (well == 0) { m_mainWin.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); blocker(false); } else { m_mainWin.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); } } }); m_reps = new JTabbedPane(); m_mainWin.getContentPane().add(m_reps); //make a backup of the instances so that any changes don't go past here. Instances te = new Instances(i, i.numInstances()); for (int noa = 0; noa < i.numInstances(); noa++) { te.add(i.instance(noa)); } te.deleteWithMissingClass(); //remove all instances with a missing class //from training m_top = new TreeClass(null, 0, 0, m_nextId, 1, te, null); m_focus = m_top; //System.out.println(graph()); m_tView = new TreeVisualizer(this, graph(), new PlaceNode1()); m_reps.add("Tree Visualizer", m_tView); //tree_frame = new JFrame(); //tree_frame.getContentPane().add(m_tView); //tree_frame.setSize(800,600); //tree_frame.show(); m_tView.setHighlight(m_top.m_identity); m_iView = new VisualizePanel(this); //m_iView.setSize(400, 300); m_iView.setInstances(m_top.m_training); m_iView.setColourIndex(te.classIndex()); //vis_frame = new JFrame(); //vis_frame.getContentPane().add(m_iView); //vis_frame.setSize(400, 300); //vis_frame.show(); m_reps.add("Data Visualizer", m_iView); m_mainWin.setSize(560, 420); m_mainWin.show(); blocker(true); //a call so that the main thread of //execution has to wait for the all clear message from the user. //so that it can be garbage if (m_propertyDialog != null) { m_propertyDialog.dispose(); m_propertyDialog = null; } //collected m_classifiers = null; m_built = true; } /** * Call this function to get a double array filled with the probability * of how likely each class type is the class of the instance. * @param i The instance to classify. * @return A double array filled with the probalities of each class type. * @exception Exception if can't classify instance. */ public double[] distributionForInstance(Instance i) throws Exception { if (!m_built) { return null; } double[] res = m_top.calcClassType(i); if (m_top.m_training.classAttribute().isNumeric()) { return res; } double most_likely = 0, highest = -1; double count = 0; for (int noa = 0; noa < m_top.m_training.numClasses(); noa++) { count += res[noa]; if (res[noa] > highest) { most_likely = noa; highest = res[noa]; } } if (count <= 0) { //not sure how this happened. return null; } for (int noa = 0; noa < m_top.m_training.numClasses(); noa++) { res[noa] = res[noa] / count; } //System.out.println("ret"); return res; } /** * Inner class used to represent the actual decision tree structure and data. */ private class TreeClass { /** * This contains the info for the coords of the shape converted * to attrib coords, * for polygon the first attrib is the number of points, * This is not more object oriented because that would * be over kill. */ public FastVector m_ranges; public int m_attrib1; public int m_attrib2; public TreeClass m_set1; public TreeClass m_set2; public TreeClass m_parent; /** A string to uniquely identify this node. */ public String m_identity; public double m_weight; public Instances m_training; /** Used instead of the standard leaf if one exists. */ public Classifier m_classObject; /** Used on the instances while classifying if one exists. */ public Filter m_filter; /** * Constructs a TreeClass node with all the important information. * @param r A FastVector containing the shapes, null if it's a leaf node. * @param a1 The first attribute. * @param a2 The second attribute. * @param id The unique id number for this node. * @param w The weight of this node. * @param i The instances that make it to this node from the training data. * @exception Exception if can't use 'i' properly. */ public TreeClass(FastVector r, int a1, int a2, int id, double w, Instances i, TreeClass p) throws Exception { m_set1 = null; m_set2 = null; m_ranges = r; m_classObject = null; m_filter = null; m_training = i; m_attrib1 = a1; m_attrib2 = a2; m_identity = "N" + String.valueOf(id); m_weight = w; m_parent = p; m_nextId++; if (m_ranges == null) { setLeaf(); //this will fill the ranges array with the //number of times each class type occurs for the instances. /*m_ranges = new FastVector(1); m_ranges.addElement(new FastVector(i.numClasses() + 1)); FastVector tmp = (FastVector)m_ranges.elementAt(0); tmp.addElement(new Double(0)); for (int noa = 0; noa < i.numClasses(); noa++) { tmp.addElement(new Double(0)); } for (int noa = 0; noa < i.numInstances(); noa++) { tmp.setElementAt(new Double(((Double)tmp.elementAt ((int)i.instance(noa). classValue() + 1)).doubleValue() + i.instance(noa).weight()), (int)i.instance(noa).classValue() + 1); //this gets the current class value and alters it and replaces it }*/ } } /** * Call this to set an alternate classifier For this node. * @param c The alternative classifier to use. * @exception Exception if alternate classifier can't build classification. */ public void setClassifier(Classifier c) throws Exception { m_classObject = c; m_classObject.buildClassifier(m_training); } /** * Call this to set this node with different information to what * it was created with. * @param a1 The first attribute. * @param a2 The second attribute. * @param ar The shapes at this node, null if leaf node, or * alternate classifier. * @exception Exception if leaf node and cant't create leaf info. */ public void setInfo(int at1, int at2, FastVector ar) throws Exception { m_classObject = null; m_filter = null; m_attrib1 = at1; m_attrib2 = at2; m_ranges = ar; //FastVector tmp; if (m_ranges == null) { setLeaf(); /* //this will fill the ranges array with the number of times //each class type occurs for the instances. if (m_training != null) { m_ranges = new FastVector(1); m_ranges.addElement(new FastVector(m_training.numClasses() + 1)); tmp = (FastVector)m_ranges.elementAt(0); tmp.addElement(new Double(0)); for (int noa = 0; noa < m_training.numClasses(); noa++) { tmp.addElement(new Double(0)); } for (int noa = 0; noa < m_training.numInstances(); noa++) { tmp.setElementAt(new Double(((Double)tmp.elementAt ((int)m_training.instance(noa). classValue() + 1)).doubleValue() + m_training.instance(noa).weight()), (int)m_training.instance(noa).classValue() + 1); //this gets the current class val and alters it and replaces it } }*/ } } /** * This sets up the informtion about this node such as the s.d or the * number of each class. * @exception Exception if problem with training instances. */ private void setLeaf() throws Exception { //this will fill the ranges array with the number of times //each class type occurs for the instances. //System.out.println("ihere"); if (m_training != null ) { if (m_training.classAttribute().isNominal()) { FastVector tmp; //System.out.println("ehlpe"); m_ranges = new FastVector(1); m_ranges.addElement(new FastVector(m_training.numClasses() + 1)); tmp = (FastVector)m_ranges.elementAt(0); tmp.addElement(new Double(0)); for (int noa = 0; noa < m_training.numClasses(); noa++) { tmp.addElement(new Double(0)); } for (int noa = 0; noa < m_training.numInstances(); noa++) { tmp.setElementAt(new Double(((Double)tmp.elementAt ((int)m_training.instance(noa). classValue() + 1)).doubleValue() + m_training.instance(noa).weight()), (int)m_training.instance(noa).classValue() + 1); //this gets the current class val and alters it and replaces it } } else { //then calc the standard deviation. m_ranges = new FastVector(1); double t1 = 0; for (int noa = 0; noa < m_training.numInstances(); noa++) { t1 += m_training.instance(noa).classValue(); } if (m_training.numInstances() != 0) { t1 /= m_training.numInstances(); } double t2 = 0; for (int noa = 0; noa < m_training.numInstances(); noa++) { t2 += Math.pow(m_training.instance(noa).classValue() - t1, 2); } FastVector tmp; if (m_training.numInstances() != 0) { t1 = Math.sqrt(t2 / m_training.numInstances()); m_ranges.addElement(new FastVector(2)); tmp = (FastVector)m_ranges.elementAt(0); tmp.addElement(new Double(0)); tmp.addElement(new Double(t1)); } else { m_ranges.addElement(new FastVector(2)); tmp = (FastVector)m_ranges.elementAt(0); tmp.addElement(new Double(0)); tmp.addElement(new Double(Double.NaN)); } } } } /** * This will recursively go through the tree and return inside the * array the weightings of each of the class types * for this instance. Note that this function returns an otherwise * unreferenced double array so there are no worry's about * making changes. * * @param i The instance to test * @return A double array containing the results. * @exception Exception if can't use instance i properly. */ public double[] calcClassType(Instance i) throws Exception { //note that it will be the same calcs for both numeric and nominal //attrib types. //note the weightings for returning stuff will need to be modified //to work properly but will do for now. double x = 0, y = 0; if (m_attrib1 >= 0) { x = i.value(m_attrib1); } if (m_attrib2 >= 0) { y = i.value(m_attrib2); } double[] rt; if (m_training.classAttribute().isNominal()) { rt = new double[m_training.numClasses()]; } else { rt = new double[1]; } FastVector tmp; if (m_classObject != null) { //then use the classifier. if (m_training.classAttribute().isNominal()) { rt[(int)m_classObject.classifyInstance(i)] = 1; } else { if (m_filter != null) { m_filter.input(i); rt[0] = m_classObject.classifyInstance(m_filter.output()); } else { rt[0] = m_classObject.classifyInstance(i); } } //System.out.println("j48"); return rt; } else if (((Double)((FastVector)m_ranges.elementAt(0)). elementAt(0)).intValue() == LEAF) { //System.out.println("leaf"); //then this is a leaf //rt = new double[m_training.numClasses()]; if (m_training.classAttribute().isNumeric()) { setLinear(); m_filter.input(i); rt[0] = m_classObject.classifyInstance(m_filter.output()); return rt; } int totaler = 0; tmp = (FastVector)m_ranges.elementAt(0); for (int noa = 0; noa < m_training.numClasses();noa++) { rt[noa] = ((Double)tmp.elementAt(noa + 1)).doubleValue(); totaler += rt[noa]; } for (int noa = 0; noa < m_training.numClasses(); noa++) { rt[noa] = rt[noa] / totaler; } return rt; } for (int noa = 0; noa < m_ranges.size(); noa++) { tmp = (FastVector)m_ranges.elementAt(noa); if (((Double)tmp.elementAt(0)).intValue() == VLINE && !i.isMissingValue(x)) { } else if (((Double)tmp.elementAt(0)).intValue() == HLINE && !i.isMissingValue(y)) { } else if (i.isMissingValue(x) || i.isMissingValue(y)) { //System.out.println("miss"); //then go down both branches using their weights rt = m_set1.calcClassType(i); double[] tem = m_set2.calcClassType(i); if (m_training.classAttribute().isNominal()) { for (int nob = 0; nob < m_training.numClasses(); nob++) { rt[nob] *= m_set1.m_weight; rt[nob] += tem[nob] * m_set2.m_weight; } } else { rt[0] *= m_set1.m_weight; rt[0] += tem[0] * m_set2.m_weight; } return rt; } else if (((Double)tmp.elementAt(0)).intValue() == RECTANGLE) { //System.out.println("RECT"); if (x >= ((Double)tmp.elementAt(1)).doubleValue() && x <= ((Double)tmp.elementAt(3)).doubleValue() && y <= ((Double)tmp.elementAt(2)).doubleValue() && y >= ((Double)tmp.elementAt(4)).doubleValue()) { //then falls inside the rectangle //System.out.println("true"); rt = m_set1.calcClassType(i); return rt; } } else if (((Double)tmp.elementAt(0)).intValue() == POLYGON) { if (inPoly(tmp, x, y)) { rt = m_set1.calcClassType(i); return rt; } } else if (((Double)tmp.elementAt(0)).intValue() == POLYLINE) { if (inPolyline(tmp, x, y)) { rt = m_set1.calcClassType(i); return rt; } } } //is outside the split if (m_set2 != null) { rt = m_set2.calcClassType(i); } return rt; } /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -