Search in sources :

Example 1 with MutableProgress

use of de.lmu.ifi.dbs.elki.logging.progress.MutableProgress in project elki by elki-project.

the class XMeans method run.

/**
 * Run the algorithm on a database and relation.
 *
 * @param database Database to process
 * @param relation Data relation
 * @return Clustering result.
 */
@Override
public Clustering<M> run(Database database, Relation<V> relation) {
    MutableProgress prog = LOG.isVerbose() ? new MutableProgress("X-means number of clusters", k_max, LOG) : null;
    // Run initial k-means to find at least k_min clusters
    innerKMeans.setK(k_min);
    if (LOG.isStatistics()) {
        LOG.statistics(new StringStatistic(KEY + ".initialization", initializer.toString()));
    }
    splitInitializer.setInitialMeans(initializer.chooseInitialMeans(database, relation, k_min, getDistanceFunction()));
    Clustering<M> clustering = innerKMeans.run(database, relation);
    if (prog != null) {
        prog.setProcessed(k_min, LOG);
    }
    ArrayList<Cluster<M>> clusters = new ArrayList<>(clustering.getAllClusters());
    while (clusters.size() <= k_max) {
        // Improve-Structure:
        ArrayList<Cluster<M>> nextClusters = new ArrayList<>();
        for (Cluster<M> cluster : clusters) {
            // Try to split this cluster:
            List<Cluster<M>> childClusterList = splitCluster(cluster, database, relation);
            nextClusters.addAll(childClusterList);
            if (childClusterList.size() > 1) {
                k += childClusterList.size() - 1;
                if (prog != null) {
                    if (k >= k_max) {
                        prog.setTotal(k + 1);
                    }
                    prog.setProcessed(k, LOG);
                }
            }
        }
        if (clusters.size() == nextClusters.size()) {
            break;
        }
        // Improve-Params:
        splitInitializer.setInitialClusters(nextClusters);
        innerKMeans.setK(nextClusters.size());
        clustering = innerKMeans.run(database, relation);
        clusters.clear();
        clusters.addAll(clustering.getAllClusters());
    }
    // Ensure that the progress bar finished.
    if (prog != null) {
        prog.setTotal(k);
        prog.setProcessed(k, LOG);
    }
    if (LOG.isDebugging()) {
        LOG.debug("X-means returned k=" + k + " clusters.");
    }
    // add all current clusters to the result
    Clustering<M> result = new Clustering<>("X-Means Result", "X-Means", clusters);
    return result;
}
Also used : StringStatistic(de.lmu.ifi.dbs.elki.logging.statistics.StringStatistic) MutableProgress(de.lmu.ifi.dbs.elki.logging.progress.MutableProgress) ArrayList(java.util.ArrayList) Cluster(de.lmu.ifi.dbs.elki.data.Cluster) Clustering(de.lmu.ifi.dbs.elki.data.Clustering)

Example 2 with MutableProgress

use of de.lmu.ifi.dbs.elki.logging.progress.MutableProgress in project elki by elki-project.

the class AffinityPropagationClusteringAlgorithm method run.

/**
 * Perform affinity propagation clustering.
 *
 * @param db Database
 * @param relation Relation
 * @return Clustering result
 */
public Clustering<MedoidModel> run(Database db, Relation<O> relation) {
    ArrayDBIDs ids = DBIDUtil.ensureArray(relation.getDBIDs());
    final int size = ids.size();
    int[] assignment = new int[size];
    double[][] s = initialization.getSimilarityMatrix(db, relation, ids);
    double[][] r = new double[size][size];
    double[][] a = new double[size][size];
    IndefiniteProgress prog = LOG.isVerbose() ? new IndefiniteProgress("Affinity Propagation Iteration", LOG) : null;
    MutableProgress aprog = LOG.isVerbose() ? new MutableProgress("Stable assignments", size + 1, LOG) : null;
    int inactive = 0;
    for (int iteration = 0; iteration < maxiter && inactive < convergence; iteration++) {
        // Update responsibility matrix:
        for (int i = 0; i < size; i++) {
            double[] ai = a[i], ri = r[i], si = s[i];
            // Find the two largest values (as initially maxk == i)
            double max1 = Double.NEGATIVE_INFINITY, max2 = Double.NEGATIVE_INFINITY;
            int maxk = -1;
            for (int k = 0; k < size; k++) {
                double val = ai[k] + si[k];
                if (val > max1) {
                    max2 = max1;
                    max1 = val;
                    maxk = k;
                } else if (val > max2) {
                    max2 = val;
                }
            }
            // With the maximum value known, update r:
            for (int k = 0; k < size; k++) {
                double val = si[k] - ((k != maxk) ? max1 : max2);
                ri[k] = ri[k] * lambda + val * (1. - lambda);
            }
        }
        // Update availability matrix
        for (int k = 0; k < size; k++) {
            // Compute sum of max(0, r_ik) for all i.
            // For r_kk, don't apply the max.
            double colposum = 0.;
            for (int i = 0; i < size; i++) {
                if (i == k || r[i][k] > 0.) {
                    colposum += r[i][k];
                }
            }
            for (int i = 0; i < size; i++) {
                double val = colposum;
                // Adjust column sum by the one extra term.
                if (i == k || r[i][k] > 0.) {
                    val -= r[i][k];
                }
                if (i != k && val > 0.) {
                    // min
                    val = 0.;
                }
                a[i][k] = a[i][k] * lambda + val * (1 - lambda);
            }
        }
        int changed = 0;
        for (int i = 0; i < size; i++) {
            double[] ai = a[i], ri = r[i];
            double max = Double.NEGATIVE_INFINITY;
            int maxj = -1;
            for (int j = 0; j < size; j++) {
                double v = ai[j] + ri[j];
                if (v > max || (i == j && v >= max)) {
                    max = v;
                    maxj = j;
                }
            }
            if (assignment[i] != maxj) {
                changed += 1;
                assignment[i] = maxj;
            }
        }
        inactive = (changed > 0) ? 0 : (inactive + 1);
        LOG.incrementProcessed(prog);
        if (aprog != null) {
            aprog.setProcessed(size - changed, LOG);
        }
    }
    if (aprog != null) {
        aprog.setProcessed(aprog.getTotal(), LOG);
    }
    LOG.setCompleted(prog);
    // Cluster map, by lead object
    Int2ObjectOpenHashMap<ModifiableDBIDs> map = new Int2ObjectOpenHashMap<>();
    DBIDArrayIter i1 = ids.iter();
    for (int i = 0; i1.valid(); i1.advance(), i++) {
        int c = assignment[i];
        // Add to cluster members:
        ModifiableDBIDs cids = map.get(c);
        if (cids == null) {
            cids = DBIDUtil.newArray();
            map.put(c, cids);
        }
        cids.add(i1);
    }
    // If we stopped early, the cluster lead might be in a different cluster.
    for (ObjectIterator<Int2ObjectOpenHashMap.Entry<ModifiableDBIDs>> iter = map.int2ObjectEntrySet().fastIterator(); iter.hasNext(); ) {
        Int2ObjectOpenHashMap.Entry<ModifiableDBIDs> entry = iter.next();
        final int key = entry.getIntKey();
        int targetkey = key;
        ModifiableDBIDs tids = null;
        // Chase arrows:
        while (ids == null && assignment[targetkey] != targetkey) {
            targetkey = assignment[targetkey];
            tids = map.get(targetkey);
        }
        if (tids != null && targetkey != key) {
            tids.addDBIDs(entry.getValue());
            iter.remove();
        }
    }
    Clustering<MedoidModel> clustering = new Clustering<>("Affinity Propagation Clustering", "ap-clustering");
    ModifiableDBIDs noise = DBIDUtil.newArray();
    for (ObjectIterator<Int2ObjectOpenHashMap.Entry<ModifiableDBIDs>> iter = map.int2ObjectEntrySet().fastIterator(); iter.hasNext(); ) {
        Int2ObjectOpenHashMap.Entry<ModifiableDBIDs> entry = iter.next();
        i1.seek(entry.getIntKey());
        if (entry.getValue().size() > 1) {
            MedoidModel mod = new MedoidModel(DBIDUtil.deref(i1));
            clustering.addToplevelCluster(new Cluster<>(entry.getValue(), mod));
        } else {
            noise.add(i1);
        }
    }
    if (noise.size() > 0) {
        MedoidModel mod = new MedoidModel(DBIDUtil.deref(noise.iter()));
        clustering.addToplevelCluster(new Cluster<>(noise, true, mod));
    }
    return clustering;
}
Also used : Int2ObjectOpenHashMap(it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap) DBIDArrayIter(de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter) Clustering(de.lmu.ifi.dbs.elki.data.Clustering) MedoidModel(de.lmu.ifi.dbs.elki.data.model.MedoidModel) MutableProgress(de.lmu.ifi.dbs.elki.logging.progress.MutableProgress) IndefiniteProgress(de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress) ArrayDBIDs(de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs) ModifiableDBIDs(de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs)

Example 3 with MutableProgress

use of de.lmu.ifi.dbs.elki.logging.progress.MutableProgress in project elki by elki-project.

the class LogPanel method getOrCreateProgressBar.

/**
 * Get an existing or create a new progress bar.
 *
 * @param prog Progress
 * @return Associated progress bar.
 */
private JProgressBar getOrCreateProgressBar(Progress prog) {
    JProgressBar pbar = pbarmap.get(prog);
    // Add a new progress bar.
    if (pbar == null) {
        synchronized (pbarmap) {
            if (prog instanceof FiniteProgress) {
                pbar = new JProgressBar(0, ((FiniteProgress) prog).getTotal());
                pbar.setStringPainted(true);
            } else if (prog instanceof IndefiniteProgress) {
                pbar = new JProgressBar();
                pbar.setIndeterminate(true);
                pbar.setStringPainted(true);
            } else if (prog instanceof MutableProgress) {
                pbar = new JProgressBar(0, ((MutableProgress) prog).getTotal());
                pbar.setStringPainted(true);
            } else {
                throw new RuntimeException("Unsupported progress record");
            }
            pbarmap.put(prog, pbar);
            final JProgressBar pbar2 = pbar;
            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    addProgressBar(pbar2);
                }
            });
        }
    }
    return pbar;
}
Also used : MutableProgress(de.lmu.ifi.dbs.elki.logging.progress.MutableProgress) IndefiniteProgress(de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress) FiniteProgress(de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress) JProgressBar(javax.swing.JProgressBar)

Example 4 with MutableProgress

use of de.lmu.ifi.dbs.elki.logging.progress.MutableProgress in project elki by elki-project.

the class P3C method mergeClusterCores.

/**
 * Merge 1-signatures into p-signatures.
 *
 * @param binCount Number of bins in each dimension.
 * @param signatures 1-signatures
 * @return p-signatures
 */
private ArrayList<Signature> mergeClusterCores(final int binCount, ArrayList<Signature> signatures) {
    MutableProgress mergeProgress = LOG.isVerbose() ? new MutableProgress("Merging signatures", signatures.size(), LOG) : null;
    // Annotate dimensions to 1-signatures for quick stopping.
    int[] firstdim = new int[signatures.size()];
    for (int i = 0; i < signatures.size(); i++) {
        firstdim[i] = signatures.get(i).getFirstDim();
    }
    LOG.debug("First dimensions: " + FormatUtil.format(firstdim));
    // Merge to (p+1)-signatures (cluster cores).
    ArrayList<Signature> clusterCores = new ArrayList<>(signatures);
    // Try adding merge 1-signature with each cluster core.
    for (int i = 0; i < clusterCores.size(); i++) {
        final Signature parent = clusterCores.get(i);
        final int end = parent.getFirstDim();
        for (int j = 0; j < signatures.size() && firstdim[j] < end; j++) {
            final Signature onesig = signatures.get(j);
            final Signature merge = mergeSignatures(parent, onesig, binCount);
            if (merge != null) {
                // We add each potential core to the list to allow remaining
                // 1-signatures to try merging with this p-signature as well.
                clusterCores.add(merge);
                // Flag both "parents" for removal.
                parent.prune = true;
                onesig.prune = true;
            }
        }
        if (mergeProgress != null) {
            mergeProgress.setTotal(clusterCores.size());
            mergeProgress.incrementProcessed(LOG);
        }
    }
    if (mergeProgress != null) {
        mergeProgress.setProcessed(mergeProgress.getTotal(), LOG);
    }
    return clusterCores;
}
Also used : MutableProgress(de.lmu.ifi.dbs.elki.logging.progress.MutableProgress) ArrayList(java.util.ArrayList)

Aggregations

MutableProgress (de.lmu.ifi.dbs.elki.logging.progress.MutableProgress)4 Clustering (de.lmu.ifi.dbs.elki.data.Clustering)2 IndefiniteProgress (de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress)2 ArrayList (java.util.ArrayList)2 Cluster (de.lmu.ifi.dbs.elki.data.Cluster)1 MedoidModel (de.lmu.ifi.dbs.elki.data.model.MedoidModel)1 ArrayDBIDs (de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs)1 DBIDArrayIter (de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter)1 ModifiableDBIDs (de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs)1 FiniteProgress (de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress)1 StringStatistic (de.lmu.ifi.dbs.elki.logging.statistics.StringStatistic)1 Int2ObjectOpenHashMap (it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap)1 JProgressBar (javax.swing.JProgressBar)1