Search code examples
javanullpointerexceptioncluster-analysisdata-miningelki

Attempting to run SLINK in own data - ELKI


I am new here and so to ELKI. Here goes what i am trying to do:

  1. I have a list of instances MyInstance that have numerical and categorical variables like {int xpto; String customer; int another, ...}

  2. I need to run SLINK with a specific distance measure gower for the case for this entire list of custom objects

After reading the tutorials and the posts I did the following:

  1. I created a database connection to load the data into DB
  2. I created my own custom data type which implements FeatureVector though each one of the instances only have one object - my own custom object
  3. I created the SimpleTypeInformation(MyDataType.class)

The problem I have is that when I try to run the algorithm it gives me a null pointer exception on getting a relation

Exception in thread "main" java.lang.NullPointerException at de.lmu.ifi.dbs.elki.database.AbstractDatabase.getRelation(AbstractDatabase.java:118) at de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm.run(AbstractAlgorithm.java:81) at main.TestingELKI.main(TestingELKI.java:104)

Can you please help here? I do not really now what's wrong with getting the db relations

public class MyDatabaseConnection implements DatabaseConnection {

    private List<MyInstance> m_data;
    private int m_size;

    public MyDatabaseConnection(ArrayList<MyInstance> data, int size) {
        m_data = data;
        m_size = size;
    }

    @Override
    public MultipleObjectsBundle loadData() {
         MultipleObjectsBundle b = new MultipleObjectsBundle();
         int mind = 1;
         int maxd = 1;
         List<MyDataType> vecs = new ArrayList<>(m_size);
         for(int i = 0; i < m_size; i++) {
             vecs.add(new MyDataType(m_data.get(i)));
         }
         SimpleTypeInformation<MyDataType> type = new SimpleTypeInformation(MyDataType.class);
         b.appendColumn(type, vecs);
         return b;
    }
}

public class MyDataType implements FeatureVector {

    MyInstance m_instance;

    public static final MyDataType.Factory FACTORY = new MyDataType.Factory();

    public MyDataType(MyInstance instance) {
        m_instance = instance;
    }

    @Override
    public int getDimensionality() {
        // TODO Auto-generated method stub
        return 1;
    }

    @Override
    public Object getValue(int arg0) {
        // TODO Auto-generated method stub
        if (arg0 == 1) {
            return m_instance;
        } else {
            System.out.println("OOOOPPPPPPPSSSSS!");
            return null;
        }
    }


    public static class Factory implements FeatureVector.Factory {

        @Override
        public ByteBufferSerializer getDefaultSerializer() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public Class getRestrictionClass() {
            // TODO Auto-generated method stub
            return MyDataType.class;
        }

        @Override
        public FeatureVector newFeatureVector(Object arg0, ArrayAdapter arg1) {
            // TODO Auto-generated method stub
            return new MyDataType(new MyInstance("0","0"));
        }
    }
}

MAIN
// create my database connection
        // load data into database  
        DatabaseConnection dbc = new MyDatabaseConnection(data, size);
        Database db = new StaticArrayDatabase(dbc, null);
        db.initialize();

        Relation<FeatureVector> labels = db.getRelation(TypeUtil.ANY);

        // now set the right distance function
        MyDistance dist = new MyDistance();
        SLINK algorithm = new SLINK(dist);

        Result res = algorithm.run(db);

Solution

  • You do not need to inherit from FeatureVector. Avoid boxing objects - this is expensive - just use MyInstance directly.

    The error you are seeing is most likely because you did not correctly implement the distance function.

    Most likely, your distance function does not specify its correct input type information? If you provide the input type null, then you get a NullPointerException like this.