use of de.lmu.ifi.dbs.elki.database.ids.DBIDs in project elki by elki-project.
the class DiSHPreferenceVectorIndex method max.
/**
* Returns the set with the maximum size contained in the specified map.
*
* @param candidates the map containing the sets
* @return the set with the maximum size
*/
private int max(Map<Integer, ModifiableDBIDs> candidates) {
DBIDs maxSet = null;
Integer maxDim = null;
for (Integer nextDim : candidates.keySet()) {
DBIDs nextSet = candidates.get(nextDim);
if (maxSet == null || maxSet.size() < nextSet.size()) {
maxSet = nextSet;
maxDim = nextDim;
}
}
return maxDim;
}
use of de.lmu.ifi.dbs.elki.database.ids.DBIDs in project elki by elki-project.
the class DiSHPreferenceVectorIndex method maxIntersection.
/**
* Returns the index of the set having the maximum intersection set with the
* specified set contained in the specified map.
*
* @param candidates the map containing the sets
* @param set the set to intersect with
* @param result the set to put the result in
* @return the set with the maximum size
*/
private int maxIntersection(Map<Integer, ModifiableDBIDs> candidates, DBIDs set, ModifiableDBIDs result) {
Integer maxDim = null;
for (Integer nextDim : candidates.keySet()) {
DBIDs nextSet = candidates.get(nextDim);
ModifiableDBIDs nextIntersection = DBIDUtil.intersection(set, nextSet);
if (result.size() < nextIntersection.size()) {
result = nextIntersection;
maxDim = nextDim;
}
}
return maxDim;
}
use of de.lmu.ifi.dbs.elki.database.ids.DBIDs in project elki by elki-project.
the class KMLOutputHandler method buildHullsRecursively.
/**
* Recursively step through the clusters to build the hulls.
*
* @param clu Current cluster
* @param hier Clustering hierarchy
* @param hulls Hull map
*/
private DoubleObjPair<Polygon> buildHullsRecursively(Cluster<Model> clu, Hierarchy<Cluster<Model>> hier, Map<Object, DoubleObjPair<Polygon>> hulls, Relation<? extends NumberVector> coords) {
final DBIDs ids = clu.getIDs();
GrahamScanConvexHull2D hull = new GrahamScanConvexHull2D();
for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
hull.add(coords.get(iter).toArray());
}
double weight = ids.size();
if (hier != null && hulls != null) {
final int numc = hier.numChildren(clu);
if (numc > 0) {
for (It<Cluster<Model>> iter = hier.iterChildren(clu); iter.valid(); iter.advance()) {
final Cluster<Model> iclu = iter.get();
DoubleObjPair<Polygon> poly = hulls.get(iclu);
if (poly == null) {
poly = buildHullsRecursively(iclu, hier, hulls, coords);
}
// Add inner convex hull to outer convex hull.
for (ArrayListIter<double[]> vi = poly.second.iter(); vi.valid(); vi.advance()) {
hull.add(vi.get());
}
weight += poly.first / numc;
}
}
}
DoubleObjPair<Polygon> pair = new DoubleObjPair<>(weight, hull.getHull());
hulls.put(clu, pair);
return pair;
}
use of de.lmu.ifi.dbs.elki.database.ids.DBIDs in project elki by elki-project.
the class PROCLUS method getLocalities.
/**
* Computes the localities of the specified medoids: for each medoid m the
* objects in the sphere centered at m with radius minDist are determined,
* where minDist is the minimum distance between medoid m and any other medoid
* m_i.
*
* @param medoids the ids of the medoids
* @param database the database holding the objects
* @param distFunc the distance function
* @return a mapping of the medoid's id to its locality
*/
private DataStore<DBIDs> getLocalities(DBIDs medoids, Relation<V> database, DistanceQuery<V> distFunc, RangeQuery<V> rangeQuery) {
WritableDataStore<DBIDs> result = DataStoreUtil.makeStorage(medoids, DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT, DBIDs.class);
for (DBIDIter iter = medoids.iter(); iter.valid(); iter.advance()) {
// determine minimum distance between current medoid m and any other
// medoid m_i
double minDist = Double.POSITIVE_INFINITY;
for (DBIDIter iter2 = medoids.iter(); iter2.valid(); iter2.advance()) {
if (DBIDUtil.equal(iter, iter2)) {
continue;
}
double currentDist = distFunc.distance(iter, iter2);
if (currentDist < minDist) {
minDist = currentDist;
}
}
// determine points in sphere centered at m with radius minDist
assert minDist != Double.POSITIVE_INFINITY;
result.put(iter, rangeQuery.getRangeForDBID(iter, minDist));
}
return result;
}
use of de.lmu.ifi.dbs.elki.database.ids.DBIDs in project elki by elki-project.
the class PROCLUS method run.
/**
* Performs the PROCLUS algorithm on the given database.
*
* @param database Database to process
* @param relation Relation to process
*/
public Clustering<SubspaceModel> run(Database database, Relation<V> relation) {
if (RelationUtil.dimensionality(relation) < l) {
throw new IllegalStateException("Dimensionality of data < parameter l! (" + RelationUtil.dimensionality(relation) + " < " + l + ")");
}
DistanceQuery<V> distFunc = database.getDistanceQuery(relation, SquaredEuclideanDistanceFunction.STATIC);
RangeQuery<V> rangeQuery = database.getRangeQuery(distFunc);
final Random random = rnd.getSingleThreadedRandom();
// initialization phase
if (LOG.isVerbose()) {
LOG.verbose("1. Initialization phase...");
}
int sampleSize = Math.min(relation.size(), k_i * k);
DBIDs sampleSet = DBIDUtil.randomSample(relation.getDBIDs(), sampleSize, random);
int medoidSize = Math.min(relation.size(), m_i * k);
ArrayDBIDs medoids = greedy(distFunc, sampleSet, medoidSize, random);
if (LOG.isDebugging()) {
LOG.debugFine(//
new StringBuilder().append("sampleSize ").append(sampleSize).append('\n').append("sampleSet ").append(sampleSet).append(//
'\n').append("medoidSize ").append(medoidSize).append(//
'\n').append("m ").append(medoids).toString());
}
// iterative phase
if (LOG.isVerbose()) {
LOG.verbose("2. Iterative phase...");
}
double bestObjective = Double.POSITIVE_INFINITY;
ArrayDBIDs m_best = null;
DBIDs m_bad = null;
ArrayDBIDs m_current = initialSet(medoids, k, random);
if (LOG.isDebugging()) {
LOG.debugFine(new StringBuilder().append("m_c ").append(m_current).toString());
}
IndefiniteProgress cprogress = LOG.isVerbose() ? new IndefiniteProgress("Current number of clusters:", LOG) : null;
ArrayList<PROCLUSCluster> clusters = null;
int loops = 0;
while (loops < 10) {
long[][] dimensions = findDimensions(m_current, relation, distFunc, rangeQuery);
clusters = assignPoints(m_current, dimensions, relation);
double objectiveFunction = evaluateClusters(clusters, dimensions, relation);
if (objectiveFunction < bestObjective) {
// restart counting loops
loops = 0;
bestObjective = objectiveFunction;
m_best = m_current;
m_bad = computeBadMedoids(m_current, clusters, (int) (relation.size() * 0.1 / k));
}
m_current = computeM_current(medoids, m_best, m_bad, random);
loops++;
if (cprogress != null) {
cprogress.setProcessed(clusters.size(), LOG);
}
}
LOG.setCompleted(cprogress);
// refinement phase
if (LOG.isVerbose()) {
LOG.verbose("3. Refinement phase...");
}
List<Pair<double[], long[]>> dimensions = findDimensions(clusters, relation);
List<PROCLUSCluster> finalClusters = finalAssignment(dimensions, relation);
// build result
int numClusters = 1;
Clustering<SubspaceModel> result = new Clustering<>("ProClus clustering", "proclus-clustering");
for (PROCLUSCluster c : finalClusters) {
Cluster<SubspaceModel> cluster = new Cluster<>(c.objectIDs);
cluster.setModel(new SubspaceModel(new Subspace(c.getDimensions()), c.centroid));
cluster.setName("cluster_" + numClusters++);
result.addToplevelCluster(cluster);
}
return result;
}
Aggregations