📄 weightedmahalanobis.java
字号:
/** Computes the L1 regularizer */ public void recomputeNormalizer() { Matrix weightMatrix = new Matrix(m_weightsMatrix); m_normalizer = Math.log(weightMatrix.det()); System.out.println("Recomputed normalizer: " + (float) m_normalizer); } /** * Create an instance with features corresponding to dot-product components of the two given instances * @param instance1 first instance * @param instance2 second instance */ public Instance createDiffInstance (Instance instance1, Instance instance2) { double[] values1 = instance1.toDoubleArray(); double[] values2 = instance2.toDoubleArray(); int numAttributes = values1.length; if (instance1.classIndex() > 0) { numAttributes--; } double[] diffInstanceValues = new double[numAttributes]; for (int i = 0; i < numAttributes; i++) { diffInstanceValues[i] = (values1[i] - values2[i]); } Instance diffInstance = new Instance(1.0, diffInstanceValues); return diffInstance; } /** * Create a matrix of the form (inst1 - inst2) * (inst1 - inst2)^T * @param instance1 first instance * @param instance2 second instance */ public Matrix createDiffMatrix (Instance instance1, Instance instance2) { Instance diffInstance = createDiffInstance(instance1, instance2); double [] values = diffInstance.toDoubleArray(); int numAttributes = diffInstance.numValues(); double [][] matrix = new double [numAttributes][numAttributes]; for (int i = 0; i < numAttributes; i++) { for (int j = 0; j <= i; j++) { matrix[i][j] = values[i] * values[j]; matrix[j][i] = matrix[i][j]; } } return new Matrix(matrix); } /** * Set the type of distance to similarity conversion. Values other * than CONVERSION_LAPLACIAN, CONVERSION_UNIT, or CONVERSION_EXPONENTIAL will be ignored * * @param type type of the similarity to distance conversion to use */ public void setConversionType(SelectedTag conversionType) { if (conversionType.getTags() == TAGS_CONVERSION) { m_conversionType = conversionType.getSelectedTag().getID(); } } /** * return the type of distance to similarity conversion * @return one of CONVERSION_LAPLACIAN, CONVERSION_UNIT, or CONVERSION_EXPONENTIAL */ public SelectedTag getConversionType() { return new SelectedTag(m_conversionType, TAGS_CONVERSION); } /** The computation of a metric can be either based on distance, or on similarity * @returns true because euclidean metrict fundamentally computes distance */ public boolean isDistanceBased() { return true; } /** * Given a cluster of instances, return the centroid of that cluster * @param instances objects belonging to a cluster * @param fastMode whether fast mode should be used for SparseInstances * @param normalized normalize centroids for SPKMeans * @return a centroid instance for the given cluster */ public Instance getCentroidInstance(Instances instances, boolean fastMode, boolean normalized) { System.err.println("Mahalanobis distance does not return a centroid"); return null; } /** * Parses a given list of options. Valid options are:<p> * * -N <br> * Normalize the euclidean distance by vectors lengths * * -E <br> * Use exponential conversion from distance to similarity * (default laplacian conversion) <p> * * -U <br> * Use unit conversion from similarity to distance (dist=1-sim) * (default laplacian conversion) <p> * * -R <br> * The metric is trainable and will be trained using the current MetricLearner * (default non-trainable) * * @param options the list of options as an array of strings * @exception Exception if an option is not supported */ public void setOptions(String[] options) throws Exception { if (Utils.getFlag('E', options)) { setConversionType(new SelectedTag(CONVERSION_EXPONENTIAL, TAGS_CONVERSION)); } else if (Utils.getFlag('U', options)) { setConversionType(new SelectedTag(CONVERSION_UNIT, TAGS_CONVERSION)); } else { setConversionType(new SelectedTag(CONVERSION_LAPLACIAN, TAGS_CONVERSION)); } Utils.checkForRemainingOptions(options); } /** * Returns an enumeration describing the available options. * * @return an enumeration of all the available options. */ public Enumeration listOptions() { Vector newVector = new Vector(4); newVector.addElement(new Option("\tNormalize the euclidean distance by vectors lengths\n", "N", 0, "-N")); newVector.addElement(new Option("\tUse exponential conversion from similarity to distance\n", "E", 0, "-E")); newVector.addElement(new Option("\tUse unit conversion from similarity to distance\n", "U", 0, "-U")); newVector.addElement(new Option("\tTrain the metric\n", "R", 0, "-R")); newVector.addElement(new Option("\tUse the metric learner for similarity calculations(\"external\")", "X", 0, "-X")); newVector.addElement(new Option( "\tFull class name of metric learner to use, followed\n" + "\tby scheme options. (required)\n" + "\teg: \"weka.core.metrics.ClassifierMetricLearner -B weka.classifiers.function.SMO\"", "L", 1, "-L <classifier specification>")); return newVector.elements(); } /** * Gets the current settings of WeightedMahalanobisP. * * @return an array of strings suitable for passing to setOptions() */ public String [] getOptions() { String [] options = new String [45]; int current = 0; if (m_conversionType == CONVERSION_EXPONENTIAL) { options[current++] = "-E"; } else if (m_conversionType == CONVERSION_UNIT) { options[current++] = "-U"; } if (m_trainable) { options[current++] = "-R"; } while (current < options.length) { options[current++] = ""; } return options; } /** Create a copy of this metric */ public Object clone() { WeightedMahalanobis m = null; m = (WeightedMahalanobis) super.clone(); return m; } public static void main(String[] args) { try { // Create numeric attributes "length" and "weight" Attribute length = new Attribute("length"); Attribute weight = new Attribute("weight"); Attribute height = new Attribute("height"); Attribute width = new Attribute("width"); // Create vector to hold nominal values "first", "second", "third" FastVector my_nominal_values = new FastVector(3); my_nominal_values.addElement("first"); my_nominal_values.addElement("second"); my_nominal_values.addElement("third"); // Create nominal attribute "position" Attribute position = new Attribute("position", my_nominal_values); // Create vector of the above attributes FastVector attributes = new FastVector(4); attributes.addElement(length); attributes.addElement(weight); attributes.addElement(height); attributes.addElement(width); attributes.addElement(position); // Create the empty dataset "race" with above attributes Instances race = new Instances("race", attributes, 0); // Make position the class attribute race.setClassIndex(position.index()); // Create a sparse instance with three attribute values SparseInstance s_inst1 = new SparseInstance(1, new double[0], new int[0], 4); s_inst1.setValue(length, 2); s_inst1.setValue(weight, 1); s_inst1.setValue(position, "third"); // Create a sparse instance with three attribute values SparseInstance s_inst2 = new SparseInstance(1, new double[0], new int[0], 4); s_inst2.setValue(length, 1); s_inst2.setValue(height, 5); s_inst2.setValue(position, "second"); // Create a non-sparse instance with all attribute values Instance inst1 = new Instance(5); inst1.setValue(length, 3); inst1.setValue(weight, 4); inst1.setValue(height, 5); inst1.setValue(width, 2); inst1.setValue(position, "first"); // Create a sparse instance with three attribute values Instance inst2 = new Instance(5); inst2.setValue(length, 2); inst2.setValue(weight, 2); inst2.setValue(height, 2); inst2.setValue(width, 3); inst2.setValue(position, "second"); // Set instances' dataset to be the dataset "race" s_inst1.setDataset(race); s_inst2.setDataset(race); inst1.setDataset(race); inst2.setDataset(race); // Print the instances System.out.println("Sparse instance S1: " + s_inst1); System.out.println("Sparse instance S2: " + s_inst2); System.out.println("Non-sparse instance NS1: " + inst1); System.out.println("Non-sparse instance NS2: " + inst2); // Print the class attribute System.out.println("Class attribute: " + s_inst1.classAttribute()); // Print the class index System.out.println("Class index: " + s_inst1.classIndex()); // Create a new metric and print the distances WeightedMahalanobis metric = new WeightedMahalanobis(4); metric.setClassIndex(position.index()); System.out.println("Distance between S1 and S2: " + metric.distance(s_inst1, s_inst2)); System.out.println("Distance between S1 and NS1: " + metric.distance(s_inst1, inst1)); System.out.println("Distance between NS1 and S1: " + metric.distance(inst1, s_inst1)); System.out.println("Distance between NS1 and NS2: " + metric.distance(inst1, inst2)); System.out.println("\nDistance-similarity conversion type: " + metric.getConversionType().getSelectedTag().getReadable()); System.out.println("Similarity between S1 and S2: " + metric.similarity(s_inst1, s_inst2)); System.out.println("Similarity between S1 and NS1: " + metric.similarity(s_inst1, inst1)); System.out.println("Similarity between NS1 and S1: " + metric.similarity(inst1, s_inst1)); System.out.println("Similarity between NS1 and NS2: " + metric.similarity(inst1, inst2)); System.out.println(); System.out.println("Difference instance S1-S2: " + metric.createDiffInstance(s_inst1, s_inst2)); System.out.println("Difference instance S1-NS1: " + metric.createDiffInstance(s_inst1, inst1)); System.out.println("Difference instance NS1-S1: " + metric.createDiffInstance(inst1, s_inst1)); System.out.println("Difference instance NS1-NS2: " + metric.createDiffInstance(inst1, inst2)); } catch (Exception e) { e.printStackTrace(); } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -