clustering.myAgnes.java Source code

Java tutorial

Introduction

Here is the source code for clustering.myAgnes.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package clustering;

import java.util.ArrayList;
import weka.clusterers.AbstractClusterer;
import weka.core.*;

/**
 *
 * @author user
 */
public class myAgnes extends AbstractClusterer {
    private int numOfClusters = 2;
    private String type;
    private Instances instances;
    private ArrayList<ArrayList<Instance>> clusters;
    private ArrayList<ArrayList<Double>> clusterDistances;

    protected DistanceFunction distanceFunction = new EuclideanDistance();

    public DistanceFunction getDistanceFunction() {
        return this.distanceFunction;
    };

    public void setDistanceFunction(DistanceFunction distanceFunction) {
        this.distanceFunction = distanceFunction;
    }

    public myAgnes(int numOfClusters, String type) {
        super();
        this.numOfClusters = numOfClusters;
        this.type = type;
        clusters = new ArrayList<ArrayList<Instance>>();
        clusterDistances = new ArrayList<ArrayList<Double>>();
    }

    @Override
    public void buildClusterer(Instances data) throws Exception {
        for (int i = 0; i < data.numInstances(); i++) {
            ArrayList<Instance> instance = new ArrayList<Instance>();
            instance.add(data.instance(i));
            clusters.add(instance);
        }

        distanceFunction.setInstances(data);
        for (int i = 0; i < clusters.size(); i++) {
            ArrayList<Double> distances = new ArrayList<Double>();
            for (int j = 0; j < clusters.size(); j++) {
                Double distance = distanceFunction.distance(data.instance(i), data.instance(j));
                distances.add(distance);
            }
            clusterDistances.add(distances);
        }

        while (clusters.size() > numberOfClusters()) {
            int c1 = -1;
            int c2 = -1;
            double min = Double.MAX_VALUE;
            for (int i = 0; i < clusters.size(); i++) {
                for (int j = i + 1; j < clusters.size(); j++) {
                    if (clusterDistances.get(i).get(j) <= min) {
                        min = clusterDistances.get(i).get(j);
                        c1 = i;
                        c2 = j;
                    }
                }
            }
            merge(c1, c2);
        }
    }

    public void merge(int c1, int c2) {
        clusters.get(c1).addAll(clusters.get(c2));
        clusters.remove(c2);

        for (int i = 0; i < clusterDistances.get(c1).size(); i++) {
            if (this.type.equals("SINGLE_LINK")) {
                if (clusterDistances.get(c1).get(i) > clusterDistances.get(c2).get(i)) {
                    clusterDistances.get(c1).set(i, clusterDistances.get(c2).get(i));
                }
            } else if (this.type.equals("COMPLETE_LINK")) {
                if (clusterDistances.get(c1).get(i) < clusterDistances.get(c2).get(i)) {
                    clusterDistances.get(c1).set(i, clusterDistances.get(c2).get(i));
                }
            }
        }

        for (int i = 0; i < clusterDistances.size(); i++) {
            clusterDistances.get(i).remove(c2);
        }

        clusterDistances.remove(c2);
    }

    @Override
    public String toString() {
        String temp = "";
        for (int i = 0; i < clusters.size(); i++) {
            temp += "Cluster " + i + " : " + clusters.get(i).size() + " instance(s) \n";
            temp += "Instances : \n";
            for (int j = 0; j < clusters.get(i).size(); j++) {
                temp += "" + (j + 1) + ". " + clusters.get(i).get(j) + "\n";
            }
            temp += " \n";
        }
        return temp;
    }

    @Override
    public int numberOfClusters() throws Exception {
        return numOfClusters;
    }

    @Override
    public int clusterInstance(Instance instance) {
        ArrayList<Double> instanceDistances = new ArrayList<Double>();
        for (int i = 0; i < clusters.size(); i++) {
            double temp = Double.MAX_VALUE;
            for (int j = 0; j < clusters.get(i).size(); j++) {
                Double distance = distanceFunction.distance(clusters.get(i).get(j), instance);
                if (distance < temp) {
                    temp = distance;
                }
            }
            instanceDistances.add(temp);
        }

        Double min = instanceDistances.get(0);
        int cluster = 0;
        for (int i = 0; i < instanceDistances.size(); i++) {
            if (instanceDistances.get(i) < min) {
                min = instanceDistances.get(i);
                cluster = i;
            }
        }

        return cluster;
    }
}