package me.mcnelis.rudder.ml.unsupervised.clustering;
import java.util.List;
import me.mcnelis.rudder.data.collections.IRudderList;
import org.apache.commons.math.stat.descriptive.SynchronizedSummaryStatistics;
import org.apache.commons.math.util.MathUtils;
public abstract class DensityBased
{
protected double epsilon;
protected int minPts;
protected int minClusters;
protected SynchronizedSummaryStatistics distance = new SynchronizedSummaryStatistics();
protected List<Cluster<?>> clusters;
protected IRudderList<?> sourceData;
public void setSourceData(IRudderList<?> rl)
{
this.sourceData = (IRudderList<?>) rl;
}
/**
*
* @param epsilon
* -- the max distance between elements in the cluster
* @param minPts
*/
protected DensityBased(double epsilon, int minPts)
{
this.epsilon = epsilon;
this.minPts = minPts;
}
public List<Cluster<?>> getClusters()
{
if (this.clusters == null)
{
this.clusters = this.cluster();
}
return this.clusters;
}
protected abstract List<Cluster<?>> cluster();
/**
* Find the neighbors of r within range (this.epsilon)
*
* Create a cluster based on the neighbors.
*
* @param Record
* @return Cluster of nearest neighbors to Record
*/
protected Cluster<?> rangeQuery(Object r)
{
Cluster<Object> c = new Cluster<Object>();
c.addRecord(r);
for (Object r2 : this.sourceData)
{
if (!r.equals(r2))
{
double mDistance = MathUtils.distance(
this.sourceData.getUnsupervisedDoubleArray(r2),
this.sourceData.getUnsupervisedDoubleArray(r));
this.distance.addValue(mDistance);
if (mDistance < this.epsilon)
{
this.sourceData.setNoise(r2, false);
c.addRecord(r2);
}
}
}
return c;
}
public double getMinDistance()
{
return this.distance.getMin();
}
public double getMeanDistance()
{
return this.distance.getMean();
}
public SynchronizedSummaryStatistics getDistanceStats()
{
return this.distance;
}
public IRudderList<?> getSourceData()
{
return this.sourceData;
}
}