2013-07-12 78 views
0

這個類(https://github.com/scalanlp/nak/blob/20637cfd6f373792b7d2fb4d9c965c0a6dac89d9/src/main/scala/nak/cluster/Kmeans.scala)作爲它的構造函數:如何調用此構造函數?

class Kmeans(
    points: IndexedSeq[Point], 
    distance: DistanceFunction, 
    minChangeInDispersion: Double = 0.0001, 
    maxIterations: Int = 100, 
    fixedSeedForRandom: Boolean = false 
) 

距離函數與特質 對象(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 
} 

這是迄今爲止我的構造函數實現:

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 , ?????? 

如何創建DistanceFunction實現以實現Kmeans構造函數?我可以使用現有的對象DistanceFunction嗎?

回答

1

不能使用DistanceFunction同伴對象 - it is just a place where statics for corresponding trait/class are placed,但您可以使用提供的對象,擴展了特質:CosineDistance,ManhattanDistance或歐幾里得距離:

val k = new Kmeans(clusters1 , CosineDistance, ...) 

如果你想創建自己的實現,你已經有了一個例子:

object ManhattanDistance extends DistanceFunction { 
    def apply(x: Point, y: Point) = (x - y).abs.sum 
} 

或與類:

class ManhattanDistance extends DistanceFunction { 
    def apply(x: Point, y: Point) = (x - y).abs.sum 
} 
val k = new Kmeans(clusters1 , new ManhattanDistance(), ...)