Custom Distance function

superprottasuperprotta Member Posts: 3 Contributor I
edited November 2018 in Help
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?
Tagged:

Answers

  • landland RapidMiner Certified Analyst, RapidMiner Certified Expert, Member Posts: 2,531 Unicorn
    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
  • superprottasuperprotta Member Posts: 3 Contributor I

    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..
  • landland RapidMiner Certified Analyst, RapidMiner Certified Expert, Member Posts: 2,531 Unicorn
    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
  • superprottasuperprotta Member Posts: 3 Contributor I
    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?
  • SilverMineMountSilverMineMount Member Posts: 3 Contributor I
    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
  • landland RapidMiner Certified Analyst, RapidMiner Certified Expert, Member Posts: 2,531 Unicorn
    Hi,
    in fact this has already been fixed and should be available in the current SVN repository at source-forge.

    Greetings,
      Sebastian
Sign In or Register to comment.