Custom Distance function

superprotta
superprotta New Altair Community Member
edited November 5 in Community Q&A
Hi, i'm new to RapidMiner and i'm trying to develop a clustering application for a university project. I had to create my own custom similarity function and, as I read in this thread http://rapid-i.com/rapidforum/index.php/topic,604.0.html, I tried to use
DistanceMeasures.registerMeasure
Here is the beginning of my application code:
public static void main(String[] args) {
try{
RapidMiner.init();
DistanceMeasures.registerMeasure(DistanceMeasures.MIXED_MEASURES_TYPE, "AxmedisObjectsDistance", AxmedisObjectsDistance.class);
Process process = new Process(new File("ClusteringObjects.xml"));
IOContainer io = process.run();
...
The process is described by ClusteringObjects.xml and it should use KMedoids operator with my distance function, which is AxmedisObjectsDistance created extending DistanceMeasure class.
Problem is that when i try to run the code written above, the application fails at
IOContainer io = process.run();
with the following error message:
java.lang.ArrayIndexOutOfBoundsException: 1
at com.rapidminer.tools.math.similarity.DistanceMeasures.createMixedMeasure(DistanceMeasures.java:238)
at com.rapidminer.tools.math.similarity.DistanceMeasures.createMeasure(DistanceMeasures.java:216)
at com.rapidminer.operator.clustering.clusterer.AgglomerativeClustering.apply(AgglomerativeClustering.java:69)
at com.rapidminer.operator.Operator.apply(Operator.java:671)
at com.rapidminer.operator.OperatorChain.apply(OperatorChain.java:424)
at com.rapidminer.operator.Operator.apply(Operator.java:671)
at com.rapidminer.Process.run(Process.java:735)
at com.rapidminer.Process.run(Process.java:704)
at com.rapidminer.Process.run(Process.java:694)
at AxmedisClustererAgglomerative.main(AxmedisClustererAgglomerative.java:38)
Obviously i'm missing something, but i'm really not seeing what, could you please help me?

Answers

  • land
    land New Altair Community Member
    Hi,
    could you please switch to the newest 4.6 version? The problem will remain there, but the stack trace will actually point to anything in the code :)

    By the way, you might put your new distance measure into a plugin. Then you would have access to the gui for executing any process you like and your new measure would be available in the parameters dialog of KMedoids.

    Greetings,
      Sebastian
  • superprotta
    superprotta New Altair Community Member

    Hi, thanks for the quick answer. i tried switching to RapidMiner 4.6 but the stack trace remains the same and it poits to:

    public static DistanceMeasure createMixedMeasure(ParameterHandler parameterHandler, ExampleSet exampleSet, IOContainer ioContainer) throws UndefinedParameterError, OperatorException {
    Class measureClass = MIXED_MEASURE_CLASSES[parameterHandler.getParameterAsInt(PARAMETER_MIXED_MEASURE)];
    return createMeasureFromClass(measureClass, parameterHandler, exampleSet, ioContainer);
    }
    I tried recompiling RapidMiner modifying these lines in DistanceMeasures.java from:
    	private static Class[] MIXED_MEASURE_CLASSES = new Class[] {
    MixedEuclideanDistance.class
    };
    to:
    	private static Class[] MIXED_MEASURE_CLASSES = new Class[] {
    MixedEuclideanDistance.class,
    AxmedisObjectsDistance.class
    };
    This way my code works, even though it still needs the line
    DistanceMeasures.registerMeasure(DistanceMeasures.MIXED_MEASURES_TYPE, "AxmedisObjectsDistance", AxmedisObjectsDistance.class);
    at the beginning, otherwise it ends with the same stack trace as above....don't know if this is helpful.

    Anyway i tried implementing it as a plugin but it gives the same ArrayIndexOutOfBounds Exception when i try to use it in any clustering operator. I suppose it's the same problem and that's why I need to solve it possibly without recompiling RapidMiner core..
  • land
    land New Altair Community Member
    Hi,
    I will check, whats wrong there. To do so, it would be very nice, if you could send me your plugin by mail? This will help me a lot, because otherwise I would have to implement a new plugin just for debugging...

    Greetings,
      Sebastian
  • superprotta
    superprotta New Altair Community Member
    Hi sorry it took me so long to answer, but I only get the chance to work at this project when I'm at work. I would send you my plugin, but I can't see your email...Could you send me your address?
  • SilverMineMount
    SilverMineMount New Altair Community Member
    Hi,

    just in case someone having the same problem finds this old thread: It's a bug in RapidMiner that can be fixed easily by modifiying com.rapidminer.tools.math.similarity.DistanceMeasures:

            public static DistanceMeasure createNumericalMeasure(ParameterHandler parameterHandler, ExampleSet exampleSet, IOContainer ioContainer) throws UndefinedParameterError, OperatorException {
    Class measureClass = MEASURE_CLASS_ARRAYS[NUMERICAL_MEASURES_TYPE][parameterHandler.getParameterAsInt(PARAMETER_NUMERICAL_MEASURE)];
    return createMeasureFromClass(measureClass, parameterHandler, exampleSet, ioContainer);
    }

    public static DistanceMeasure createNominalMeasure(ParameterHandler parameterHandler, ExampleSet exampleSet, IOContainer ioContainer) throws UndefinedParameterError, OperatorException {
    Class measureClass = MEASURE_CLASS_ARRAYS[NOMINAL_MEASURES_TYPE][parameterHandler.getParameterAsInt(PARAMETER_NOMINAL_MEASURE)];
    return createMeasureFromClass(measureClass, parameterHandler, exampleSet, ioContainer);
    }

    public static DistanceMeasure createMixedMeasure(ParameterHandler parameterHandler, ExampleSet exampleSet, IOContainer ioContainer) throws UndefinedParameterError, OperatorException {
    Class measureClass = MEASURE_CLASS_ARRAYS[MIXED_MEASURES_TYPE][parameterHandler.getParameterAsInt(PARAMETER_MIXED_MEASURE)];
    return createMeasureFromClass(measureClass, parameterHandler, exampleSet, ioContainer);
    }

    public static DistanceMeasure createDivergence(ParameterHandler parameterHandler, ExampleSet exampleSet, IOContainer ioContainer) throws UndefinedParameterError, OperatorException {
    Class measureClass = MEASURE_CLASS_ARRAYS[DIVERGENCES_TYPE][parameterHandler.getParameterAsInt(PARAMETER_DIVERGENCE)];
    return createMeasureFromClass(measureClass, parameterHandler, exampleSet, ioContainer);
    }

    Cheers,
    Peter
  • land
    land New Altair Community Member
    Hi,
    in fact this has already been fixed and should be available in the current SVN repository at source-forge.

    Greetings,
      Sebastian