Skip to content

Instantly share code, notes, and snippets.

@Atternatt
Last active September 21, 2017 04:59
Show Gist options
  • Save Atternatt/aee324135b0cf056beca9c902f50366d to your computer and use it in GitHub Desktop.
Save Atternatt/aee324135b0cf056beca9c902f50366d to your computer and use it in GitHub Desktop.
Recommendation algorithms
fun List<Number>.getNearestNeighbors(posibleNeighbors: List<List<Number>>, numberOfNeighbors: Int): List<List<Double>> {
return posibleNeighbors.mapIndexed { index, posibleNeighbor -> index to this.pearsonCorrelationWith(posibleNeighbor) }
.sortedBy { it.second }
.take(numberOfNeighbors)
.map { posibleNeighbors[it.first].map { it.toDouble() } }
}
fun Array<Number>.sum(): Double {
return this.map { it.toDouble() }.reduce { acc, new -> acc + new }
}
fun Array<Number>.sumSq(): Double {
return this.map { it.toDouble() * it.toDouble() }.reduce { acc, new -> acc + new }
}
fun Array<Number>.pearsonCorrelationWith(otherArray: Array<Number>): Double {
assert(this.size == otherArray.size)
val sumX = this.sum()
val sumY = otherArray.sum()
val sumXSq = this.sumSq()
val sumYSq = otherArray.sumSq()
val pSum = this.zip(otherArray) { x, y -> x.toDouble() * y.toDouble() }.reduce { acc, new -> acc + new }
val num = pSum - (sumX * sumY / this.size)
val den = Math.pow((sumXSq - Math.pow(sumX, 2.0) / this.size) * (sumYSq - Math.pow(sumY, 2.0)), 0.5)
return if (den == 0.0) 1.0 else num/den
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment