Skip to content

Commit

Permalink
add unit test for model construction
Browse files Browse the repository at this point in the history
  • Loading branch information
mengxr committed Jan 30, 2015
1 parent 5925113 commit 05422a8
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ class IsotonicRegressionModel (

private val predictionOrd = if (isotonic) Ordering[Double] else Ordering[Double].reverse

assert(boundaries.length == predictions.length)
require(boundaries.length == predictions.length)
assertOrdered(boundaries)
assertOrdered(predictions)(predictionOrd)

/** Asserts the input array is monotone with the given ordering. */
private def assertOrdered(xs: Array[Double])(implicit ord: Ordering[Double]): Unit = {
var i = 1
while (i < xs.length) {
assert(ord.compare(xs(i - 1), xs(i)) <= 0,
require(ord.compare(xs(i - 1), xs(i)) <= 0,
s"Elements (${xs(i - 1)}, ${xs(i)}) are not ordered.")
i += 1
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package org.apache.spark.mllib.regression
import org.scalatest.{Matchers, FunSuite}

import org.apache.spark.mllib.util.MLlibTestSparkContext
import org.apache.spark.mllib.util.TestingUtils._

class IsotonicRegressionSuite extends FunSuite with MLlibTestSparkContext with Matchers {

Expand Down Expand Up @@ -55,80 +56,67 @@ class IsotonicRegressionSuite extends FunSuite with MLlibTestSparkContext with M

test("increasing isotonic regression") {
val model = runIsotonicRegression(Seq(1, 2, 3, 3, 1, 6, 17, 16, 17, 18), true)

assert(model.predictions === Array(1, 2, 7d/3, 7d/3, 7d/3, 6, 16.5, 16.5, 17, 18))
}

test("isotonic regression with size 0") {
val model = runIsotonicRegression(Seq(), true)

assert(model.predictions === Array())
}

test("isotonic regression with size 1") {
val model = runIsotonicRegression(Seq(1), true)

assert(model.predictions === Array(1.0))
}

test("isotonic regression strictly increasing sequence") {
val model = runIsotonicRegression(Seq(1, 2, 3, 4, 5), true)

assert(model.predictions === Array(1, 2, 3, 4, 5))
}

test("isotonic regression strictly decreasing sequence") {
val model = runIsotonicRegression(Seq(5, 4, 3, 2, 1), true)

assert(model.predictions === Array(3, 3, 3, 3, 3))
}

test("isotonic regression with last element violating monotonicity") {
val model = runIsotonicRegression(Seq(1, 2, 3, 4, 2), true)

assert(model.predictions === Array(1, 2, 3, 3, 3))
}

test("isotonic regression with first element violating monotonicity") {
val model = runIsotonicRegression(Seq(4, 2, 3, 4, 5), true)

assert(model.predictions === Array(3, 3, 3, 4, 5))
}

test("isotonic regression with negative labels") {
val model = runIsotonicRegression(Seq(-1, -2, 0, 1, -1), true)

assert(model.predictions === Array(-1.5, -1.5, 0, 0, 0))
}

test("isotonic regression with unordered input") {
val trainRDD = sc.parallelize(generateIsotonicInput(Seq(1, 2, 3, 4, 5)).reverse).cache()
val model = new IsotonicRegression().run(trainRDD)

assert(model.predictions === Array(1, 2, 3, 4, 5))
}

test("weighted isotonic regression") {
val model = runIsotonicRegression(Seq(1, 2, 3, 4, 2), Seq(1, 1, 1, 1, 2), true)

assert(model.predictions === Array(1, 2, 2.75, 2.75,2.75))
}

test("weighted isotonic regression with weights lower than 1") {
val model = runIsotonicRegression(Seq(1, 2, 3, 2, 1), Seq(1, 1, 1, 0.1, 0.1), true)

assert(model.predictions.map(round) === Array(1, 2, 3.3/1.2, 3.3/1.2, 3.3/1.2))
}

test("weighted isotonic regression with negative weights") {
val model = runIsotonicRegression(Seq(1, 2, 3, 2, 1), Seq(-1, 1, -3, 1, -5), true)

assert(model.predictions === Array(1.0, 10.0/6, 10.0/6, 10.0/6, 10.0/6))
}

test("weighted isotonic regression with zero weights") {
val model = runIsotonicRegression(Seq[Double](1, 2, 3, 2, 1), Seq[Double](0, 0, 0, 1, 0), true)

assert(model.predictions === Array(1, 2, 2, 2, 2))
}

Expand Down Expand Up @@ -186,4 +174,33 @@ class IsotonicRegressionSuite extends FunSuite with MLlibTestSparkContext with M
assert(model.predict(3) === 4)
assert(model.predict(10) === 1)
}
}

test("model construction") {
val model = new IsotonicRegressionModel(Array(0.0, 1.0), Array(1.0, 2.0), isotonic = true)
assert(model.predict(-0.5) === 1.0)
assert(model.predict(0.0) === 1.0)
assert(model.predict(0.5) ~== 1.5 absTol 1e-14)
assert(model.predict(1.0) === 2.0)
assert(model.predict(1.5) === 2.0)

intercept[IllegalArgumentException] {
// different array sizes.
new IsotonicRegressionModel(Array(0.0, 1.0), Array(1.0), isotonic = true)
}

intercept[IllegalArgumentException] {
// unordered boundaries
new IsotonicRegressionModel(Array(1.0, 0.0), Array(1.0, 2.0), isotonic = true)
}

intercept[IllegalArgumentException] {
// unordered predictions (isotonic)
new IsotonicRegressionModel(Array(0.0, 1.0), Array(2.0, 1.0), isotonic = true)
}

intercept[IllegalArgumentException] {
// unordered predictions (antitonic)
new IsotonicRegressionModel(Array(0.0, 1.0), Array(1.0, 2.0), isotonic = false)
}
}
}

0 comments on commit 05422a8

Please sign in to comment.