Reputation: 53806
This class (https://github.com/scalanlp/nak/blob/20637cfd6f373792b7d2fb4d9c965c0a6dac89d9/src/main/scala/nak/cluster/Kmeans.scala) has as its constructor :
class Kmeans(
points: IndexedSeq[Point],
distance: DistanceFunction,
minChangeInDispersion: Double = 0.0001,
maxIterations: Int = 100,
fixedSeedForRandom: Boolean = false
)
Distance function is an object with trait (https://github.com/scalanlp/nak/blob/ae8fc0c534ea0613300e8c53487afe099327977a/src/main/scala/nak/cluster/Points.scala) :
trait DistanceFunction extends ((Point, Point) => Double)
/**
* A companion object to the DistanceFunction trait that helps select the
* DistanceFunction corresponding to each string description.
*/
object DistanceFunction {
def apply(description: String) = description match {
case "c" | "cosine" => CosineDistance
case "m" | "manhattan" => ManhattanDistance
case "e" | "euclidean" => EuclideanDistance
case _ => throw new MatchError("Invalid distance function: " + description)
}
}
/**
* Compute the cosine distance between two points. Note that it is a distance
* because we subtract the cosine similarity from one.
*/
object CosineDistance extends DistanceFunction {
def apply(x: Point, y: Point) = 1 - x.dotProduct(y) / (x.norm * y.norm)
}
/**
* Compute the Manhattan (city-block) distance between two points.
*/
object ManhattanDistance extends DistanceFunction {
def apply(x: Point, y: Point) = (x - y).abs.sum
}
/**
* Compute the Euclidean distance between two points.
*/
object EuclideanDistance extends DistanceFunction {
def apply(x: Point, y: Point) = (x - y).norm
}
This is my constructor implementation so far :
val p1 = new Point(IndexedSeq(0.0, 0.0 , 3.0));
val p2 = new Point(IndexedSeq(0.0, 0.0 , 3.0));
val p3 = new Point(IndexedSeq(0.0, 0.0 , 3.0));
val clusters1 = IndexedSeq( p1 , p2 , p3 )
val k = new Kmeans(clusters1 , ??????
How do I create a DistanceFunction implementation so as to implement the Kmeans constructor ? Can I just use the existing object DistanceFunction ?
Upvotes: 0
Views: 156
Reputation: 62835
You can't use DistanceFunction companion object -- it is just a place where statics for corresponding trait/class are placed, but you can use provided object which extend the trait: CosineDistance, ManhattanDistance or EuclideanDistance:
val k = new Kmeans(clusters1 , CosineDistance, ... )
If you want to create your own implementation, you already have an example:
object ManhattanDistance extends DistanceFunction {
def apply(x: Point, y: Point) = (x - y).abs.sum
}
or with class:
class ManhattanDistance extends DistanceFunction {
def apply(x: Point, y: Point) = (x - y).abs.sum
}
val k = new Kmeans(clusters1 , new ManhattanDistance(), ... )
Upvotes: 1