📄 balltree.java
字号:
if (leftPivotDist < rightPivotDist) { nearestNeighbours(heap, node.m_Left, target, k); nearestNeighbours(heap, node.m_Right, target, k); } else { nearestNeighbours(heap, node.m_Right, target, k); nearestNeighbours(heap, node.m_Left, target, k); } } // else see which ball is closer (if dist < 0 target is inside a ball, and // hence the ball is closer). else { if (leftBallDist < rightBallDist) { nearestNeighbours(heap, node.m_Left, target, k); nearestNeighbours(heap, node.m_Right, target, k); } else { nearestNeighbours(heap, node.m_Right, target, k); nearestNeighbours(heap, node.m_Left, target, k); } } } else if (node.m_Left != null || node.m_Right != null) { // invalid leaves // assignment throw new Exception("Error: Only one leaf of the built ball tree is " + "assigned. Please check code."); } else if (node.m_Left == null && node.m_Right == null) { // if node is a // leaf if (m_TreeStats != null) { m_TreeStats.updatePointCount(node.numInstances()); m_TreeStats.incrLeafCount(); } for (int i = node.m_Start; i <= node.m_End; i++) { if (target == m_Instances.instance(m_InstList[i])) //for hold-one-out cross-validation continue; if (heap.totalSize() < k) { distance = m_DistanceFunction.distance(target, m_Instances .instance(m_InstList[i]), Double.POSITIVE_INFINITY, m_Stats); heap.put(m_InstList[i], distance); } else { MyHeapElement head = heap.peek(); distance = m_DistanceFunction.distance(target, m_Instances.instance(m_InstList[i]), head.distance, m_Stats); if (distance < head.distance) { heap.putBySubstitute(m_InstList[i], distance); } else if (distance == head.distance) { heap.putKthNearest(m_InstList[i], distance); } }//end else(heap.totalSize()) } }//end else if node is a leaf } /** * Returns the nearest instance in the current neighbourhood to the supplied * instance. * * @param target The instance to find the nearest neighbour for. * @throws Exception if the nearest neighbour could not be found. * @return The nearest neighbour of the given target instance. */ public Instance nearestNeighbour(Instance target) throws Exception { return kNearestNeighbours(target, 1).instance(0); } /** * Returns the distances of the k nearest neighbours. The kNearestNeighbours * or nearestNeighbour must always be called before calling this function. If * this function is called before calling either the kNearestNeighbours or * the nearestNeighbour, then it throws an exception. If, however, any * one of the two functions is called at any point in the past, then no * exception is thrown and the distances of NN(s) from the training set for * the last supplied target instance (to either one of the nearestNeighbour * functions) is/are returned. * * @return array containing the distances of the * nearestNeighbours. The length and ordering of the * array is the same as that of the instances returned * by nearestNeighbour functions. * @throws Exception if called before calling kNearestNeighbours * or nearestNeighbours. */ public double[] getDistances() throws Exception { if(m_Distances==null) throw new Exception("No distances available. Please call either "+ "kNearestNeighbours or nearestNeighbours first."); return m_Distances; } /** * Adds one instance to the BallTree. This involves creating/updating the * structure to reflect the newly added training instance * * @param ins The instance to be added. Usually the newly added instance in the * training set. * @throws Exception If the instance cannot be added to the tree. */ public void update(Instance ins) throws Exception { addInstanceInfo(ins); m_InstList = m_TreeConstructor.addInstance(m_Root, ins); } /** * Adds the given instance's info. This implementation updates the attributes' * range datastructures of EuclideanDistance class. * * @param ins The instance to add the information of. Usually this is * the test instance supplied to update the range of * attributes in the distance function. */ public void addInstanceInfo(Instance ins) { if(m_Instances!=null) m_DistanceFunction.update(ins); } /** * Builds the BallTree based on the given set of instances. * @param insts The insts for which the BallTree is to be * built. * @throws Exception If some error occurs while * building the BallTree */ public void setInstances(Instances insts) throws Exception { super.setInstances(insts); buildTree(); } /** * Returns the tip text for this property. * * @return tip text for this property suitable for * displaying in the explorer/experimenter gui */ public String ballTreeConstructorTipText() { return "The tree constructor being used."; } /** * Returns the BallTreeConstructor currently in use. * @return The BallTreeConstructor currently in use. */ public BallTreeConstructor getBallTreeConstructor() { return m_TreeConstructor; } /** * Sets the BallTreeConstructor for building the BallTree * (default TopDownConstructor). * @param constructor The new BallTreeConstructor. */ public void setBallTreeConstructor(BallTreeConstructor constructor) { m_TreeConstructor = constructor; } /** * Returns the size of the tree. * * @return the size of the tree */ public double measureTreeSize() { return m_TreeConstructor.getNumNodes(); } /** * Returns the number of leaves. * * @return the number of leaves */ public double measureNumLeaves() { return m_TreeConstructor.getNumLeaves(); } /** * Returns the depth of the tree. * * @return the number of rules */ public double measureMaxDepth() { return m_TreeConstructor.getMaxDepth(); } /** * Returns an enumeration of the additional measure names. * * @return an enumeration of the measure names */ public Enumeration enumerateMeasures() { Vector newVector = new Vector(); newVector.addElement("measureTreeSize"); newVector.addElement("measureNumLeaves"); newVector.addElement("measureMaxDepth"); if (m_Stats != null) { for (Enumeration e = m_Stats.enumerateMeasures(); e.hasMoreElements();) { newVector.addElement(e.nextElement()); } } return newVector.elements(); } /** * Returns the value of the named measure. * * @param additionalMeasureName the name of the measure to query for * its value. * @return the value of the named measure. * @throws IllegalArgumentException if the named measure is not supported. */ public double getMeasure(String additionalMeasureName) { if (additionalMeasureName.compareToIgnoreCase("measureMaxDepth") == 0) { return measureMaxDepth(); } else if (additionalMeasureName.compareToIgnoreCase("measureTreeSize") == 0) { return measureTreeSize(); } else if (additionalMeasureName.compareToIgnoreCase("measureNumLeaves") == 0) { return measureNumLeaves(); } else if(m_Stats!=null) { return m_Stats.getMeasure(additionalMeasureName); } else { throw new IllegalArgumentException(additionalMeasureName + " not supported (BallTree)"); } } /** * Sets whether to calculate the performance statistics or not. * @param measurePerformance This should be true if performance * statistics are to be calculated. */ public void setMeasurePerformance(boolean measurePerformance) { m_MeasurePerformance = measurePerformance; if (m_MeasurePerformance) { if (m_Stats == null) m_Stats = m_TreeStats = new TreePerformanceStats(); } else m_Stats = m_TreeStats = null; } /** * Returns an enumeration describing the available options. * * @return an enumeration of all the available options. */ public Enumeration listOptions() { Vector newVector = new Vector(); newVector.addElement(new Option( "\tThe construction method to employ. Either TopDown or BottomUp\n" + "\t(default: weka.core.TopDownConstructor)", "C", 1, "-C <classname and options>")); return newVector.elements(); } /** * Parses a given list of options. * <!-- options-start --> * Valid options are: <p/> * * <pre> -C <classname and options> * The construction method to employ. Either TopDown or BottomUp * (default: weka.core.TopDownConstructor)</pre> * <!-- options-end --> * * @param options the list of options as an array of strings * @throws Exception if an option is not supported */ public void setOptions(String[] options) throws Exception { super.setOptions(options); String optionString = Utils.getOption('C', options); if(optionString.length() != 0) { String constructorSpec[] = Utils.splitOptions(optionString); if(constructorSpec.length == 0) { throw new Exception("Invalid BallTreeConstructor specification string."); } String className = constructorSpec[0]; constructorSpec[0] = ""; setBallTreeConstructor( (BallTreeConstructor) Utils.forName( BallTreeConstructor.class, className, constructorSpec) ); } else { setBallTreeConstructor(new TopDownConstructor()); } } /** * Gets the current settings of KDtree. * * @return an array of strings suitable for passing to setOptions */ public String[] getOptions() { Vector<String> result; String[] options; int i; result = new Vector<String>(); options = super.getOptions(); for (i = 0; i < options.length; i++) result.add(options[i]); result.add("-C"); result.add( (m_TreeConstructor.getClass().getName() + " " + Utils.joinOptions(m_TreeConstructor.getOptions())).trim()); return result.toArray(new String[result.size()]); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -